summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--ILMergeInternalizeExceptions.txt0
-rw-r--r--LICENSE.txt2
-rw-r--r--build.proj197
-rw-r--r--doc/logo/dotnetopenid.icobin318 -> 17318 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.dllbin21504 -> 37888 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.pdbbin60928 -> 83456 bytes
-rw-r--r--lib/DotNetOpenAuth.BuildTasks.targets2
-rw-r--r--lib/Microsoft.Contracts.dllbin16384 -> 16384 bytes
-rw-r--r--projecttemplates/Settings.StyleCop44
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Admin.Master7
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.cs19
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.designer.cs25
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql128
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Default.aspx52
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs24
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.designer.cs34
-rw-r--r--projecttemplates/WebFormsRelyingParty/Admin/Web.config9
-rw-r--r--projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs123
-rw-r--r--projecttemplates/WebFormsRelyingParty/Default.aspx12
-rw-r--r--projecttemplates/WebFormsRelyingParty/Default.aspx.cs21
-rw-r--r--projecttemplates/WebFormsRelyingParty/Default.aspx.designer.cs34
-rw-r--r--projecttemplates/WebFormsRelyingParty/GettingStarted.htm19
-rw-r--r--projecttemplates/WebFormsRelyingParty/Global.asax1
-rw-r--r--projecttemplates/WebFormsRelyingParty/Global.asax.cs178
-rw-r--r--projecttemplates/WebFormsRelyingParty/Login.aspx10
-rw-r--r--projecttemplates/WebFormsRelyingParty/Login.aspx.cs23
-rw-r--r--projecttemplates/WebFormsRelyingParty/Login.aspx.designer.cs16
-rw-r--r--projecttemplates/WebFormsRelyingParty/LoginFrame.aspx65
-rw-r--r--projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs98
-rw-r--r--projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.designer.cs61
-rw-r--r--projecttemplates/WebFormsRelyingParty/Logout.aspx16
-rw-r--r--projecttemplates/WebFormsRelyingParty/Logout.aspx.cs11
-rw-r--r--projecttemplates/WebFormsRelyingParty/Logout.aspx.designer.cs25
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx99
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs82
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs151
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/Default.aspx9
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/Default.aspx.cs13
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/Default.aspx.designer.cs16
-rw-r--r--projecttemplates/WebFormsRelyingParty/Members/Web.config18
-rw-r--r--projecttemplates/WebFormsRelyingParty/Model.Designer.cs494
-rw-r--r--projecttemplates/WebFormsRelyingParty/Model.cs21
-rw-r--r--projecttemplates/WebFormsRelyingParty/Model.edmx225
-rw-r--r--projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate132
-rw-r--r--projecttemplates/WebFormsRelyingParty/Properties/AssemblyInfo.cs41
-rw-r--r--projecttemplates/WebFormsRelyingParty/Setup.aspx43
-rw-r--r--projecttemplates/WebFormsRelyingParty/Setup.aspx.cs64
-rw-r--r--projecttemplates/WebFormsRelyingParty/Setup.aspx.designer.cs70
-rw-r--r--projecttemplates/WebFormsRelyingParty/Site.Master49
-rw-r--r--projecttemplates/WebFormsRelyingParty/Site.Master.cs19
-rw-r--r--projecttemplates/WebFormsRelyingParty/Site.Master.designer.cs43
-rw-r--r--projecttemplates/WebFormsRelyingParty/Web.config179
-rw-r--r--projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj281
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/google.gifbin0 -> 1596 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/infocard_23x16.pngbin0 -> 810 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/myopenid.pngbin0 -> 1796 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/openid.gifbin0 -> 740 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/openid_login.gifbin0 -> 237 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/verisign.gifbin0 -> 2550 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/yahoo.gifbin0 -> 1682 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/images/yahoo_login.pngbin0 -> 6310 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/scripts/LoginLink.js53
-rw-r--r--projecttemplates/WebFormsRelyingParty/scripts/jquery-1.3.1.js4241
-rw-r--r--projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.js4126
-rw-r--r--projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.min.js184
-rw-r--r--projecttemplates/WebFormsRelyingParty/scripts/jquery.cookie.js96
-rw-r--r--projecttemplates/WebFormsRelyingParty/styles/Standard.css67
-rw-r--r--projecttemplates/WebFormsRelyingParty/styles/loginpopup.css23
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_55_999999_40x100.pngbin0 -> 180 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_75_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_45_0078ae_1x400.pngbin0 -> 136 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_55_f8da4e_1x400.pngbin0 -> 131 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_75_79c9ec_1x400.pngbin0 -> 132 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_45_e14f1c_500x100.pngbin0 -> 3649 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_50_6eac2c_500x100.pngbin0 -> 4256 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_75_2191c0_500x100.pngbin0 -> 3457 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.pngbin0 -> 88 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_0078ae_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_056b93_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_d8e7f3_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_e0fdff_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f5e175_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f7a50d_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_fcd113_256x240.pngbin0 -> 4379 bytes
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.accordion.css9
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.all.css2
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.base.css9
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.core.css37
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.datepicker.css62
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.dialog.css13
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.progressbar.css4
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.resizable.css13
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.slider.css17
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.tabs.css9
-rw-r--r--projecttemplates/WebFormsRelyingParty/theme/ui.theme.css243
-rw-r--r--projecttemplates/WebFormsRelyingParty/xrds.aspx20
-rw-r--r--samples/OAuthConsumer/App_Code/InMemoryTokenManager.cs8
-rw-r--r--samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs4
-rw-r--r--samples/OAuthServiceProvider/Members/Authorize.aspx.cs4
-rw-r--r--samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj5
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs31
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs31
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs42
-rw-r--r--samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs117
-rw-r--r--samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs46
-rw-r--r--samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj11
-rw-r--r--samples/OpenIdProviderWebForms/access_token.ashx1
-rw-r--r--samples/OpenIdProviderWebForms/access_token.ashx.cs23
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx4
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.cs24
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.designer.cs18
-rw-r--r--samples/OpenIdRelyingPartyMvc/Content/css/openidlogin.css2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/Global.asax.cs14
-rw-r--r--samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj8
-rw-r--r--samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx10
-rw-r--r--samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx.cs2
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx6
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx.cs4
-rw-r--r--samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs9
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx34
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs62
-rw-r--r--samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs88
-rw-r--r--samples/OpenIdRelyingPartyWebForms/logout.aspx1
-rw-r--r--samples/OpenIdRelyingPartyWebForms/xrds.aspx4
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs47
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs52
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs30
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CompareFiles.cs85
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs108
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs95
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln20
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs66
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj89
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ECMAScriptPacker.cs486
-rw-r--r--src/DotNetOpenAuth.BuildTasks/FilterItems.cs24
-rw-r--r--src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs51
-rw-r--r--src/DotNetOpenAuth.BuildTasks/JsPack.cs75
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ParseMaster.cs250
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs36
-rw-r--r--src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs56
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs33
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs45
-rw-r--r--src/DotNetOpenAuth.BuildTasks/SnToolTask.cs37
-rw-r--r--src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs117
-rw-r--r--src/DotNetOpenAuth.BuildTasks/TaskStrings.resx138
-rw-r--r--src/DotNetOpenAuth.BuildTasks/Trim.cs79
-rw-r--r--src/DotNetOpenAuth.Test/App.config4
-rw-r--r--src/DotNetOpenAuth.Test/AssemblyTesting.cs7
-rw-r--r--src/DotNetOpenAuth.Test/CoordinatorBase.cs6
-rw-r--r--src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj47
-rw-r--r--src/DotNetOpenAuth.Test/LocalizationTests.cs28
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/Bindings/StandardReplayProtectionBindingElementTests.cs1
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs1
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/CollectionAssert.cs12
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs99
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs99
-rw-r--r--src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs1
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs7
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs7
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs5
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs4
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs15
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs9
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/MockRealm.cs4
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/TestMessageFactory.cs3
-rw-r--r--src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs7
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs6
-rw-r--r--src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs5
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs5
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs5
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeRequestTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestUtilities.cs4
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Messages/IndirectSignedResponseTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs5
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/ProviderEndpointDescriptionTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdTextBoxTests.cs49
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs2
-rw-r--r--src/DotNetOpenAuth.Test/Properties/AssemblyInfo.cs2
-rw-r--r--src/DotNetOpenAuth.Test/TestBase.cs11
-rw-r--r--src/DotNetOpenAuth.sln15
-rw-r--r--src/DotNetOpenAuth.vsmdi24
-rw-r--r--src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverter.cs4
-rw-r--r--src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverterContract.cs30
-rw-r--r--src/DotNetOpenAuth/ComponentModel/UriConverter.cs8
-rw-r--r--src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs3
-rw-r--r--src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs2
-rw-r--r--src/DotNetOpenAuth/Configuration/OpenIdElement.cs13
-rw-r--r--src/DotNetOpenAuth/Configuration/TypeConfigurationCollection.cs8
-rw-r--r--src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs8
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj95
-rw-r--r--src/DotNetOpenAuth/GlobalSuppressions.cs2
-rw-r--r--src/DotNetOpenAuth/InfoCard/ClaimType.cs4
-rw-r--r--src/DotNetOpenAuth/InfoCard/InfoCardImage.cs2
-rw-r--r--src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs131
-rw-r--r--src/DotNetOpenAuth/InfoCard/InfoCardStrings.sr.resx135
-rw-r--r--src/DotNetOpenAuth/InfoCard/ReceivedTokenEventArgs.cs1
-rw-r--r--src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs9
-rw-r--r--src/DotNetOpenAuth/InfoCard/SupportingScript.js40
-rw-r--r--src/DotNetOpenAuth/InfoCard/Token/Token.cs43
-rw-r--r--src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs4
-rw-r--r--src/DotNetOpenAuth/InfoCard/Token/TokenUtility.cs19
-rw-r--r--src/DotNetOpenAuth/InfoCard/TokenProcessingErrorEventArgs.cs5
-rw-r--r--src/DotNetOpenAuth/Logger.cs3
-rw-r--r--src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs6
-rw-r--r--src/DotNetOpenAuth/Messaging/Bindings/StandardReplayProtectionBindingElement.cs3
-rw-r--r--src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs9
-rw-r--r--src/DotNetOpenAuth/Messaging/Channel.cs181
-rw-r--r--src/DotNetOpenAuth/Messaging/ChannelContract.cs4
-rw-r--r--src/DotNetOpenAuth/Messaging/ChannelEventArgs.cs3
-rw-r--r--src/DotNetOpenAuth/Messaging/ErrorUtilities.cs71
-rw-r--r--src/DotNetOpenAuth/Messaging/HttpDeliveryMethods.cs15
-rw-r--r--src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs64
-rw-r--r--src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs8
-rw-r--r--src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs117
-rw-r--r--src/DotNetOpenAuth/Messaging/IMessageFactory.cs45
-rw-r--r--src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs11
-rw-r--r--src/DotNetOpenAuth/Messaging/IncomingWebResponseContract.cs54
-rw-r--r--src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs5
-rw-r--r--src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs7
-rw-r--r--src/DotNetOpenAuth/Messaging/MessageSerializer.cs28
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs20
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.resx8
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingStrings.sr.resx294
-rw-r--r--src/DotNetOpenAuth/Messaging/MessagingUtilities.cs152
-rw-r--r--src/DotNetOpenAuth/Messaging/MultipartPostPart.cs202
-rw-r--r--src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs6
-rw-r--r--src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs14
-rw-r--r--src/DotNetOpenAuth/Messaging/OutgoingWebResponseActionResult.cs4
-rw-r--r--src/DotNetOpenAuth/Messaging/ProtocolException.cs3
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/IMessagePartEncoder.cs43
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs11
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs22
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessageDictionary.cs33
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs63
-rw-r--r--src/DotNetOpenAuth/Messaging/Reflection/ValueMapping.cs8
-rw-r--r--src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs12
-rw-r--r--src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs23
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs1
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs14
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs17
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs35
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs7
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs12
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthIdentity.cs3
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs9
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs7
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs7
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs6
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBaseContract.cs3
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs21
-rw-r--r--src/DotNetOpenAuth/OAuth/ChannelElements/UriOrOobEncoding.cs3
-rw-r--r--src/DotNetOpenAuth/OAuth/ConsumerBase.cs33
-rw-r--r--src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs11
-rw-r--r--src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs2
-rw-r--r--src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OAuth/OAuthStrings.sr.resx162
-rw-r--r--src/DotNetOpenAuth/OAuth/Protocol.cs8
-rw-r--r--src/DotNetOpenAuth/OAuth/ServiceProvider.cs79
-rw-r--r--src/DotNetOpenAuth/OAuth/WebConsumer.cs11
-rw-r--r--src/DotNetOpenAuth/OpenId/Association.cs59
-rw-r--r--src/DotNetOpenAuth/OpenId/AssociationContract.cs65
-rw-r--r--src/DotNetOpenAuth/OpenId/Associations.cs26
-rw-r--r--src/DotNetOpenAuth/OpenId/Behaviors/BehaviorStrings.sr.resx123
-rw-r--r--src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/Behaviors/PpidGeneration.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/ExtensionsBindingElement.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs22
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToNonceBindingElement.cs15
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs19
-rw-r--r--src/DotNetOpenAuth/OpenId/DiffieHellmanUtilities.cs21
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs17
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs13
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs9
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/ExtensionArgumentsManager.cs80
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs23
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PapeUtilities.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/Extensions/UI/UIUtilities.cs8
-rw-r--r--src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs48
-rw-r--r--src/DotNetOpenAuth/OpenId/IAssociationStore.cs99
-rw-r--r--src/DotNetOpenAuth/OpenId/Identifier.cs25
-rw-r--r--src/DotNetOpenAuth/OpenId/IdentifierContract.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Interop/ClaimsResponseShim.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs19
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs4
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs29
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationRequest.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationResponse.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/IndirectResponseBase.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs6
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs20
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.resx10
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdStrings.sr.resx340
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs11
-rw-r--r--src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs12
-rw-r--r--src/DotNetOpenAuth/OpenId/Protocol.cs30
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AnonymousRequestEventArgs.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs11
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs261
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs10
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IHostProcessedRequest.cs11
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IProviderBehavior.cs64
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/IRequest.cs7
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs62
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs13
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/Request.cs18
-rw-r--r--src/DotNetOpenAuth/OpenId/Provider/RequestContract.cs2
-rw-r--r--src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs17
-rw-r--r--src/DotNetOpenAuth/OpenId/Realm.cs30
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs15
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs102
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/Controls.cd112
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/FailedAuthenticationResponse.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs36
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs96
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationResponse.cs278
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs66
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs53
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs31
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs59
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/NegativeAuthenticationResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs1056
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.css49
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js865
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs8
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdEventArgs.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs318
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdMobileTextBox.cs17
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cd1
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs75
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs524
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js765
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs505
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js34
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.cs351
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.css109
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.js179
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdTextBox.cs903
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs36
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs (renamed from src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationResponseSnapshot.cs)15
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs9
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButton.cs46
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButtonContract.cs46
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/SelectorInfoCardButton.cs44
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/SelectorOpenIdButton.cs65
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/SelectorProviderButton.cs94
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs17
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/WellKnownProviders.cs14
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs5
-rw-r--r--src/DotNetOpenAuth/OpenId/SecuritySettings.cs3
-rw-r--r--src/DotNetOpenAuth/OpenId/UriIdentifier.cs13
-rw-r--r--src/DotNetOpenAuth/OpenId/XriIdentifier.cs21
-rw-r--r--src/DotNetOpenAuth/Properties/AssemblyInfo.cs2
-rw-r--r--src/DotNetOpenAuth/Strings.sr.resx126
-rw-r--r--src/DotNetOpenAuth/UriUtil.cs11
-rw-r--r--src/DotNetOpenAuth/Util.cs13
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdsNode.cs8
-rw-r--r--src/DotNetOpenAuth/Xrds/XrdsStrings.sr.resx132
-rw-r--r--src/DotNetOpenAuth/Yadis/HtmlParser.cs4
-rw-r--r--src/DotNetOpenAuth/Yadis/Yadis.cs5
-rw-r--r--src/official-build-key.pubbin0 -> 160 bytes
-rw-r--r--src/version.txt2
-rw-r--r--tools/DotNetOpenAuth.Common.Settings.targets25
-rw-r--r--tools/DotNetOpenAuth.Versioning.targets2
-rw-r--r--tools/JavascriptPacker.targets43
-rw-r--r--tools/Sandcastle/Presentation/Prototype/chm/Test.hhp14
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/conceptual.config9
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/reference-core.config190
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/reference.config175
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/sandcastle-scbuild.config1
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/sandcastle.config5
-rw-r--r--tools/Sandcastle/Presentation/Prototype/configuration/schema.config27
-rw-r--r--tools/Sandcastle/Presentation/Prototype/content/reference_content.xml4
-rw-r--r--tools/Sandcastle/Presentation/Prototype/content/shared_content.xml4
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test.HxC22
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test.HxF8
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_A.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_B.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_F.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_K.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_N.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/hxs/test_S.HxK3
-rw-r--r--tools/Sandcastle/Presentation/Prototype/scripts/LanguageFilter.js6
-rw-r--r--tools/Sandcastle/Presentation/Prototype/scripts/script_prototype.js189
-rw-r--r--tools/Sandcastle/Presentation/Prototype/styles/presentation.css4
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/main_conceptual.xsl60
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/main_reference.xsl10
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/main_sandcastle.xsl50
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/utilities_dduexml.xsl13
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/utilities_metadata.xsl4
-rw-r--r--tools/Sandcastle/Presentation/Prototype/transforms/utilities_reference.xsl107
-rw-r--r--tools/Sandcastle/Presentation/Shared/configuration/xamlSyntax.config69
-rw-r--r--tools/Sandcastle/Presentation/Shared/content/syntax_content.xml13
-rw-r--r--tools/Sandcastle/Presentation/Shared/transforms/utilities_dduexml.xsl8
-rw-r--r--tools/Sandcastle/Presentation/Shared/transforms/utilities_metadata.xsl99
-rw-r--r--tools/Sandcastle/Presentation/Shared/transforms/utilities_reference.xsl86
-rw-r--r--tools/Sandcastle/Presentation/hana/Content/conceptual_content.xml68
-rw-r--r--tools/Sandcastle/Presentation/hana/Content/reference_content.xml482
-rw-r--r--tools/Sandcastle/Presentation/hana/Content/shared_content.xml139
-rw-r--r--tools/Sandcastle/Presentation/hana/Content/token_content.xml4
-rw-r--r--tools/Sandcastle/Presentation/hana/DocModel.ps122
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/CommonUtilities.js314
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/DataStore.js116
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/Dropdown.js56
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/EventUtilities.js23
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/LanguageFilter.js91
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/MemberFilter.js110
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/SplitScreen.js29
-rw-r--r--tools/Sandcastle/Presentation/hana/Scripts/script_manifold.js1594
-rw-r--r--tools/Sandcastle/Presentation/hana/Styles/Presentation.css934
-rw-r--r--tools/Sandcastle/Presentation/hana/Styles/syntax.css22
-rw-r--r--tools/Sandcastle/Presentation/hana/Styles/tabs.css118
-rw-r--r--tools/Sandcastle/Presentation/hana/configuration/conceptual.config108
-rw-r--r--tools/Sandcastle/Presentation/hana/configuration/sandcastle-scbuild.config126
-rw-r--r--tools/Sandcastle/Presentation/hana/configuration/sandcastle.config127
-rw-r--r--tools/Sandcastle/Presentation/hana/copyOutput.bat11
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/CFW.gifbin588 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/Caution.gifbin526 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/LastChild.gifbin67 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/NSRbottomgrad.gifbin92 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/adm.gifbin960 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/adm_arch.gifbin1123 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/adm_dev.gifbin1199 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/adm_dev_arch.gifbin1363 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/alert_caution.gifbin526 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/alert_note.gifbin123 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/alert_security.gifbin183 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/arch.gifbin966 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/big_adm.gifbin1283 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/big_arch.gifbin1316 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/big_dev.gifbin1215 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/big_kw.gifbin1300 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/box.gifbin129 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/ch_selected.gifbin302 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/ch_selected_hover.gifbin301 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/ch_unselected.gifbin499 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/ch_unselected_hover.gifbin294 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/collall.gifbin75 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/collapse.gifbin64 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/collapse_all.gifbin197 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/copycode.gifbin578 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/copycodeHighlight.gifbin578 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/dev.gifbin1031 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/dev_arch.gifbin1190 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/drpdown.gifbin221 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/drpdown_orange.gifbin366 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/drpdown_orange_up.gifbin364 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/drpup.gifbin923 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/exp.gifbin67 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/expall.gifbin78 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/expand_all.gifbin200 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/filter1a.gifbin137 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/filter1c.gifbin137 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/footer.gifbin41 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/greencheck.gifbin138 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/greychck.gifbin138 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/header_prev_next.jpgbin10663 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_blank.jpgbin12762 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_logo.GIFbin3033 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw.gifbin975 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_adm.gifbin1129 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_adm_arch.gifbin1287 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_adm_dev.gifbin1356 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_adm_dev_arch.gifbin1610 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_arch.gifbin1133 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_dev.gifbin1208 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/kw_dev_arch.gifbin1369 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/load.gifbin100 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/load_hover.gifbin186 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/note.gifbin123 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pencil.GIFbin340 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privclass.gifbin621 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privdelegate.gifbin1045 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privenum.gifbin597 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privenumeration.gifbin597 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privevent.gifbin580 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privfield.gifbin574 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privinterface.gifbin585 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privmethod.gifbin603 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privproperty.gifbin1054 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/privstructure.gifbin630 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protclass.gifbin600 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protdelegate.gifbin1041 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protenum.gifbin583 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protenumeration.gifbin583 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protevent.gifbin564 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protfield.gifbin570 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protinterface.gifbin562 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protmethod.gifbin183 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protoperator.gifbin547 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protproperty.gifbin1039 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/protstructure.gifbin619 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubclass.gifbin368 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubdelegate.gifbin1041 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubenum.gifbin339 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubenumeration.gifbin339 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubevent.gifbin314 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubfield.gifbin311 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubinterface.gifbin314 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubmethod.gifbin329 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/puboperator.gifbin310 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubproperty.gifbin609 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/pubstructure.gifbin595 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/r_select.gifbin304 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/r_select_hover.gifbin298 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/r_unselect.gifbin300 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/r_unselect_hover.gifbin298 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/requirements1a.gifbin139 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/requirements1c.gifbin139 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/save.gifbin981 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/save_hover.gifbin985 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/security.gifbin183 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/seealso1a.gifbin138 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/seealso1c.gifbin138 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/static.gifbin126 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_cnr.gifbin99 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_grad.gifbin63 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_cnr.gifbin99 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_grad.gifbin63 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_cnr.gifbin99 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_grad.gifbin63 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_cnr.gifbin99 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_grad.gifbin63 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/twirl_selected.gifbin76 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/twirl_selected_hover.gifbin105 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/twirl_unselected.gifbin105 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/twirl_unselected_hover.gifbin79 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/icons/xna.gifbin549 -> 0 bytes
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/globalTemplates.xsl125
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/htmlBody.xsl507
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/main_conceptual.xsl455
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/main_reference.xsl447
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/main_sandcastle.xsl710
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/skeleton.xml7
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/skeleton_conceptual.xml3
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/utilities_dduexml.xsl1293
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/utilities_metadata.xsl928
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/utilities_reference.xsl2442
-rw-r--r--tools/Sandcastle/Presentation/hana/transforms/xamlSyntax.xsl491
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Content/conceptual_content.xml4
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Content/feedBack_content.xml4
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Content/reference_content.xml78
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Content/shared_content.xml38
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Scripts/CommonUtilities.js50
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Scripts/script_feedBack.js4
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Scripts/script_manifold.js7
-rw-r--r--tools/Sandcastle/Presentation/vs2005/Styles/Presentation.css9
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/conceptual.config117
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/reference-core-componentized.config374
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/reference-core.config373
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/reference.config344
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-scbuild.config66
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-webref.config66
-rw-r--r--tools/Sandcastle/Presentation/vs2005/configuration/sandcastle.config330
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp20.xsl143
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp30.xsl183
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/globalTemplates.xsl112
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/htmlBody.xsl25
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/main_conceptual.xsl289
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/main_reference.xsl217
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/main_sandcastle.xsl817
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp20.xsl (renamed from tools/Sandcastle/Presentation/vs2005/transforms/utilities_metadata.xsl)114
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp30.xsl589
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/seeAlsoSection.xsl168
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/utilities_dduexml.xsl313
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/utilities_reference.xsl532
-rw-r--r--tools/Sandcastle/Presentation/vs2005/transforms/xamlSyntax.xsl34
-rw-r--r--tools/Sandcastle/ProductionTools/.gitignore4
-rw-r--r--tools/Sandcastle/ProductionTools/AggregateByNamespace.exebin29720 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/BuildAssembler.exebin29712 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/BuildAssemblerLibrary.dllbin42016 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/BuildComponents.dllbin177168 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/ChmBuilder.exebin37896 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/CommandLine.dllbin33800 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/DBCSFix.exebin29696 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/MrefBuilder.exebin672776 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/SegregateByAssembly.exebin29720 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/SyntaxComponents.dllbin115728 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/VersionBuilder.exebin33808 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/XslTransform.exebin33800 -> 0 bytes
-rw-r--r--tools/Sandcastle/ProductionTools/scbuild.ps164
-rw-r--r--tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl2
-rw-r--r--tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl721
-rw-r--r--tools/Sandcastle/ProductionTransforms/CreateHxt.xsl91
-rw-r--r--tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl9
-rw-r--r--tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl2
-rw-r--r--tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl13
-rw-r--r--tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl48
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssembler.csproj93
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssemblerConsole.cs110
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssembler/GlobalSuppressions.cs17
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssembler/Properties/AssemblyInfo.cs38
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssembler.cs320
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssemblerLibrary.csproj94
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponent.cs82
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponentUtilities.cs146
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildContext.cs176
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/GlobalSuppressions.cs45
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/Properties/AssemblyInfo.cs43
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/BuildComponents.csproj155
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/CloneComponent.cs44
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/CodeReference.cs117
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ComputeHashComponent.cs68
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs146
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFiles.cs95
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromIndexComponent.cs677
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/DisplayComponent.cs46
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ExampleComponent.cs543
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ForEachComponent.cs105
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/GlobalSuppressions.cs319
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/HxfGeneratorComponent.cs132
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/IfThenComponent.cs87
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/IndexedFileCache.cs192
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent.cs338
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent2.cs424
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/LiveExampleComponent.cs195
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnResolver.cs76
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnService.cs913
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/PlatformsComponent.cs674
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/AssemblyInfo.cs42
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.Designer.cs26
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.settings5
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/References.cs340
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveArtLinksComponent.cs195
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveConceptualLinksComponent.cs448
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveReferenceLinksComponent2.cs497
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/SaveComponent.cs149
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/SharedContentComponent.cs380
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/SnippetComponent.cs1223
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/SwitchComponent.cs77
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/SyntaxComponent.cs283
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/TargetCollection.cs2739
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/Targets.cs156
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/TaskGrabberComponent.cs371
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/TransformComponent.cs153
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/ValidateComponent.cs47
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/BuildComponents/WdxResolveConceptualLinksComponent.cs299
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/CopyComponents/CopyComponents.csproj80
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/CopyComponents/GlobalSuppressions.cs17
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/CopyComponents/InheritDocumentationComponent.cs373
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/CopyComponents/Properties/AssemblyInfo.cs46
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/AspNetSyntax.cs210
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CPlusPlusDeclarationSyntax.cs1065
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CSharpDeclarationSyntax.cs982
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs988
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/GlobalSuppressions.cs301
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JScriptDeclarationSyntax.cs475
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JSharpDeclarationSyntax.cs648
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/Properties/AssemblyInfo.cs42
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs614
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxComponents.csproj105
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxGenerators.cs435
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicDeclarationSyntax.cs961
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicUsageSyntax.cs778
-rw-r--r--tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/XamlUsageSyntax.cs953
-rw-r--r--tools/Sandcastle/Source/CCI/AssemblyCache.cs354
-rw-r--r--tools/Sandcastle/Source/CCI/CCI.csproj109
-rw-r--r--tools/Sandcastle/Source/CCI/CCI.subproj38
-rw-r--r--tools/Sandcastle/Source/CCI/DoubleVisitor.cs2617
-rw-r--r--tools/Sandcastle/Source/CCI/Duplicator.cs1926
-rw-r--r--tools/Sandcastle/Source/CCI/ExceptionStrings.cs480
-rw-r--r--tools/Sandcastle/Source/CCI/ExceptionStrings.resx228
-rw-r--r--tools/Sandcastle/Source/CCI/FastFileIO.cs606
-rw-r--r--tools/Sandcastle/Source/CCI/ILGenerator.cs1152
-rw-r--r--tools/Sandcastle/Source/CCI/ListTemplate.cs4556
-rw-r--r--tools/Sandcastle/Source/CCI/MemoryMappedFile.cs462
-rw-r--r--tools/Sandcastle/Source/CCI/Metadata.cs3849
-rw-r--r--tools/Sandcastle/Source/CCI/Nodes.cs21996
-rw-r--r--tools/Sandcastle/Source/CCI/OpCode.cs280
-rw-r--r--tools/Sandcastle/Source/CCI/Properties/AssemblyInfo.cs43
-rw-r--r--tools/Sandcastle/Source/CCI/Reader.cs6074
-rw-r--r--tools/Sandcastle/Source/CCI/Specializer.cs1054
-rw-r--r--tools/Sandcastle/Source/CCI/StandardIds.cs154
-rw-r--r--tools/Sandcastle/Source/CCI/StandardVisitor.cs2225
-rw-r--r--tools/Sandcastle/Source/CCI/SystemTypes.cs2154
-rw-r--r--tools/Sandcastle/Source/CCI/Unstacker.cs383
-rw-r--r--tools/Sandcastle/Source/CCI/Updater.cs2979
-rw-r--r--tools/Sandcastle/Source/CCI/Writer.cs6397
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/ChmBuilder.config (renamed from tools/Sandcastle/ProductionTools/ChmBuilder.config)17
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/ChmBuilder.cs739
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/ChmBuilder.csproj74
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/ChmBuilderArgs.cs41
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/GlobalSuppressions.cs53
-rw-r--r--tools/Sandcastle/Source/ChmBuilder/Properties/AssemblyInfo.cs40
-rw-r--r--tools/Sandcastle/Source/CommandLine/BooleanOption.cs36
-rw-r--r--tools/Sandcastle/Source/CommandLine/CommandLine.csproj93
-rw-r--r--tools/Sandcastle/Source/CommandLine/ConsoleApplication.cs64
-rw-r--r--tools/Sandcastle/Source/CommandLine/GlobalSuppressions.cs29
-rw-r--r--tools/Sandcastle/Source/CommandLine/ListOption.cs47
-rw-r--r--tools/Sandcastle/Source/CommandLine/LogLevel.cs18
-rw-r--r--tools/Sandcastle/Source/CommandLine/Option.cs97
-rw-r--r--tools/Sandcastle/Source/CommandLine/OptionCollection.cs182
-rw-r--r--tools/Sandcastle/Source/CommandLine/OutputWriter.cs27
-rw-r--r--tools/Sandcastle/Source/CommandLine/ParseArgumentsResult.cs63
-rw-r--r--tools/Sandcastle/Source/CommandLine/ParseResult.cs18
-rw-r--r--tools/Sandcastle/Source/CommandLine/Properties/AssemblyInfo.cs42
-rw-r--r--tools/Sandcastle/Source/CommandLine/StringOption.cs48
-rw-r--r--tools/Sandcastle/Source/CommandLine/SwitchOption.cs31
-rw-r--r--tools/Sandcastle/Source/DBCSFix/DBCSFix.csproj83
-rw-r--r--tools/Sandcastle/Source/DBCSFix/GlobalSuppressions.cs16
-rw-r--r--tools/Sandcastle/Source/DBCSFix/Program.cs210
-rw-r--r--tools/Sandcastle/Source/DBCSFix/Properties/AssemblyInfo.cs37
-rw-r--r--tools/Sandcastle/Source/DBCSFix/Properties/Settings.Designer.cs26
-rw-r--r--tools/Sandcastle/Source/DBCSFix/Properties/Settings.settings5
-rw-r--r--tools/Sandcastle/Source/DBCSFix/Settings.cs34
-rw-r--r--tools/Sandcastle/Source/DBCSFix/app.config (renamed from tools/Sandcastle/ProductionTools/DBCSFix.exe.config)0
-rw-r--r--tools/Sandcastle/Source/DBCSFix/readme.txt42
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs328
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs81
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config (renamed from tools/Sandcastle/ProductionTools/MRefBuilder.config)18
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs339
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj113
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs23
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs19
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs1316
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs273
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs40
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs28
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/TextStrings.txt4
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs243
-rw-r--r--tools/Sandcastle/Source/MRefBuilder/reflection.xsd686
-rw-r--r--tools/Sandcastle/Source/Reflection/AllDocumentedFilter.cs90
-rw-r--r--tools/Sandcastle/Source/Reflection/AllTopicFilter.cs23
-rw-r--r--tools/Sandcastle/Source/Reflection/ApiFilter.cs208
-rw-r--r--tools/Sandcastle/Source/Reflection/ApiNamer.cs30
-rw-r--r--tools/Sandcastle/Source/Reflection/ApiVisitor.cs339
-rw-r--r--tools/Sandcastle/Source/Reflection/AssemblyReferenceEventArgs.cs36
-rw-r--r--tools/Sandcastle/Source/Reflection/AssemblyResolver.cs89
-rw-r--r--tools/Sandcastle/Source/Reflection/ExternalDocumentedFilter.cs82
-rw-r--r--tools/Sandcastle/Source/Reflection/ExternalFilter.cs31
-rw-r--r--tools/Sandcastle/Source/Reflection/ExternalTopicFilter.cs23
-rw-r--r--tools/Sandcastle/Source/Reflection/GlobalSuppressions.cs55
-rw-r--r--tools/Sandcastle/Source/Reflection/MemberFilter.cs50
-rw-r--r--tools/Sandcastle/Source/Reflection/NamespaceFilter.cs143
-rw-r--r--tools/Sandcastle/Source/Reflection/NoFilter.cs28
-rw-r--r--tools/Sandcastle/Source/Reflection/Notes.txt215
-rw-r--r--tools/Sandcastle/Source/Reflection/OrcasNamer.cs376
-rw-r--r--tools/Sandcastle/Source/Reflection/Properties/AssemblyInfo.cs40
-rw-r--r--tools/Sandcastle/Source/Reflection/Reflection.cs298
-rw-r--r--tools/Sandcastle/Source/Reflection/Reflection.csproj107
-rw-r--r--tools/Sandcastle/Source/Reflection/RootFilter.cs126
-rw-r--r--tools/Sandcastle/Source/Reflection/TestResolver.cs22
-rw-r--r--tools/Sandcastle/Source/Reflection/TypeFilter.cs120
-rw-r--r--tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs275
-rw-r--r--tools/Sandcastle/Source/Sandcastle.sln155
-rw-r--r--tools/Sandcastle/Source/XmlCat/GlobalSuppressions.cs17
-rw-r--r--tools/Sandcastle/Source/XmlCat/MergeXml.csproj67
-rw-r--r--tools/Sandcastle/Source/XmlCat/Program.cs166
-rw-r--r--tools/Sandcastle/Source/XmlCat/Properties/AssemblyInfo.cs38
-rw-r--r--tools/Sandcastle/Source/XslTransform/GlobalSuppressions.cs21
-rw-r--r--tools/Sandcastle/Source/XslTransform/Properties/AssemblyInfo.cs40
-rw-r--r--tools/Sandcastle/Source/XslTransform/XslTransform.cs275
-rw-r--r--tools/Sandcastle/Source/XslTransform/XslTransform.csproj89
-rw-r--r--tools/Sandcastle/Source/build.proj17
-rw-r--r--tools/sandcastle.targets8
783 files changed, 122284 insertions, 17210 deletions
diff --git a/.gitignore b/.gitignore
index 9d5c1a7..a994e00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,4 @@ PrecompiledWeb
*.mdf
*.swx
.dotest
+*.Publish.xml
diff --git a/ILMergeInternalizeExceptions.txt b/ILMergeInternalizeExceptions.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ILMergeInternalizeExceptions.txt
diff --git a/LICENSE.txt b/LICENSE.txt
index a3f32e1..906ff2c 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -4,7 +4,7 @@ Every file is bound by the following copyright and license unless explicitly
indicated otherwise in and/or for any individual file.
-Copyright (c) 2008, Andrew Arnott
+Copyright (c) 2008-2009, Andrew Arnott
All rights reserved.
Microsoft Public License (Ms-PL)
diff --git a/build.proj b/build.proj
index 8e34a8d..33f6aa8 100644
--- a/build.proj
+++ b/build.proj
@@ -3,16 +3,28 @@
<PropertyGroup>
<AutomatedBuild>true</AutomatedBuild>
<SolutionPath>$(ProjectRoot)\src\$(ProductName).sln</SolutionPath>
+ <ILMergeOutputAssemblyDirectory>$(OutputPath)\unified\</ILMergeOutputAssemblyDirectory>
+ <ILMergeOutputAssembly>$(ILMergeOutputAssemblyDirectory)\$(ProductName).dll</ILMergeOutputAssembly>
+ <ProjectTemplatesLayoutPath>$(ProjectRoot)\obj\$(Configuration)\projecttemplates\</ProjectTemplatesLayoutPath>
</PropertyGroup>
<Import Project="$(ProjectRoot)\tools\$(ProductName).Versioning.targets"/>
<Import Project="$(ProjectRoot)\tools\Documentation.targets"/>
<Import Project="$(ProjectRoot)\tools\Publish.targets"/>
<UsingTask AssemblyFile="$(ProjectRoot)\lib\MSBuild.Community.Tasks.dll" TaskName="Zip"/>
+ <UsingTask AssemblyFile="$(ProjectRoot)\lib\MSBuild.Community.Tasks.dll" TaskName="ILMerge"/>
<ItemGroup>
<SampleProjects Include="$(ProjectRoot)\samples\**\*.csproj" />
<SampleSites Include="OAuthConsumer;OAuthServiceProvider;InfoCardRelyingParty" />
+ <ProjectTemplates Include="$(ProjectRoot)\projecttemplates\**\*.csproj" />
+ <ILMergeInputAssemblies Include="$(OutputPath)\$(ProductName).dll;
+ $(ProjectRoot)\lib\Microsoft.Contracts.dll; "/>
+ <DelaySignedAssemblies Include="$(ILMergeOutputAssembly);
+ $(OutputPath)\$(ProductName).dll;
+ $(OutputPath)\$(ProductName).Contracts.dll;
+ $(OutputPath)\$(ProductName).Test.dll;
+ $(ProjectRoot)\samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe" />
</ItemGroup>
<Target Name="Clean" DependsOnTargets="CleanDocumentation;UnpublishSamples;UnpublishDocumentation">
@@ -22,8 +34,9 @@
$(ProjectRoot)\bin;
$(ProjectRoot)\**\obj;
$(ProjectRoot)\doc\api;
- $(ProjectRoot)\drops;
+ $(DropsRoot);
$(ProjectRoot)\src\PrecompiledWeb;
+ $(ProjectTemplatesLayoutPath);
" />
<DirtyDirectories Include="@(SampleDirectories->'%(FullPath)\bin')" />
<DirtyDirectories Include="@(SampleDirectories->'%(FullPath)\obj')" />
@@ -37,50 +50,66 @@
<RemoveDir Directories="@(DirtyDirectories)" />
</Target>
- <Target Name="BuildProduct">
+ <Target Name="SkipVerification" Condition="'$(IsElevated)' == 'true'">
+ <SignatureVerification SkipVerification="true" AssemblyName="*" PublicKeyToken="$(PublicKeyToken)" />
+ </Target>
+
+ <Target Name="BuildProduct" DependsOnTargets="SkipVerification">
<MSBuild Projects="$(ProjectRoot)\src\$(ProductName)\$(ProductName).csproj" />
</Target>
- <Target Name="BuildTests">
+ <Target Name="BuildTests" DependsOnTargets="SkipVerification">
<MSBuild Projects="$(ProjectRoot)\src\$(ProductName).Test\$(ProductName).Test.csproj" />
</Target>
- <Target Name="BuildSamples">
+ <Target Name="BuildSamples" DependsOnTargets="SkipVerification">
<MSBuild Projects="@(SampleProjects)" />
- <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" Properties="Sign=$(Sign)" />
+ <MSBuild Projects="$(SolutionPath)" Targets="@(SampleSites)" />
</Target>
- <Target Name="Build">
- <!-- We explicitly pass the Sign property in because if properties are set
- inside this very .proj file instead of being passed on the command-line, their
- values won't propagate automatically. -->
- <MSBuild Projects="$(SolutionPath)" Properties="Sign=$(Sign)" />
+ <Target Name="Build" DependsOnTargets="SkipVerification">
+ <MSBuild Projects="$(SolutionPath)" />
</Target>
- <Target Name="Rebuild">
- <!-- We explicitly pass the Sign property in because if properties are set
- inside this very .proj file instead of being passed on the command-line, their
- values won't propagate automatically. -->
- <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" Properties="Sign=$(Sign)" />
+ <Target Name="Rebuild" DependsOnTargets="SkipVerification">
+ <MSBuild Projects="$(SolutionPath)" Targets="Rebuild" />
</Target>
- <Target Name="_EnsureCleanTools" DependsOnTargets="_SetToolsProperties" Condition="'$(NoClean)' != 'true'">
- <!-- clean up any previous drop with the same name so we don't aggregate files. -->
- <RemoveDir Directories="$(ToolsDirectory)" />
+ <Target Name="BuildUnifiedProduct"
+ DependsOnTargets="BuildProduct"
+ Inputs="@(ILMergeInputAssemblies)"
+ Outputs="$(ILMergeOutputAssembly)">
+ <MakeDir Directories="$(ILMergeOutputAssemblyDirectory)" />
+ <ILMerge ExcludeFile="$(ProjectRoot)\ILMergeInternalizeExceptions.txt"
+ InputAssemblies="@(ILMergeInputAssemblies)"
+ OutputFile="$(ILMergeOutputAssembly)"
+ KeyFile="$(PublicKeyFile)"
+ DelaySign="true"
+ />
+ </Target>
+
+ <Target Name="ReSignDelaySignedAssemblies">
+ <Message Text="Signing delay-signed assemblies." />
+ <ReSignDelaySignedAssemblies
+ KeyContainer="$(KeyPairContainer)"
+ Assemblies="@(DelaySignedAssemblies)"
+ Condition="Exists(%(Identity))" />
</Target>
- <Target Name="_SetToolsProperties">
+ <Target Name="ToolsLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct">
<PropertyGroup>
- <ToolsDirectory>$(ProjectRoot)\drops\$(ProductName)-Tools-$(BuildVersion)</ToolsDirectory>
+ <ToolsDirectory>$(DropsRoot)\$(ProductName)-Tools-$(BuildVersion)</ToolsDirectory>
</PropertyGroup>
- </Target>
- <Target Name="ToolsLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;_SetToolsProperties;_EnsureCleanTools">
<ItemGroup>
<ToolProjects Include="$(ProjectRoot)\Samples\OpenIdOfflineProvider\OpenIdOfflineProvider.csproj" />
<OfflineProvider Include="
$(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\**\*.dll;
- $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe" />
+ $(ILMergeOutputAssembly).*;
+ $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\OpenIdOfflineProvider.exe"
+ Exclude="
+ $(ProjectRoot)\Samples\OpenIdOfflineProvider\bin\$(Configuration)\$(ProductName).*;
+ "/>
<OfflineProviderTargets Include="
@(OfflineProvider->'$(ToolsDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
@@ -88,8 +117,10 @@
<AllToolTargets Include="@(OfflineProviderTargets)" />
</ItemGroup>
- <MSBuild Projects="@(ToolProjects)" Properties="Sign=$(Sign)" />
+ <MSBuild Projects="@(ToolProjects)" />
+ <!-- clean up any previous drop with the same name so we don't aggregate files. -->
+ <RemoveDir Directories="$(ToolsDirectory)" Condition="'$(NoClean)' != 'true'" />
<MakeDir Directories="@(ToolsDirectory)" />
<Copy SourceFiles="@(AllToolSources)" DestinationFiles="@(AllToolTargets)" SkipUnchangedFiles="true" />
</Target>
@@ -105,6 +136,87 @@
WorkingDirectory="$(ToolsDirectory)" />
</Target>
+ <Target Name="BuildProjectTemplates">
+ <MSBuild Projects="@(ProjectTemplates)" />
+ </Target>
+
+ <Target Name="ProjectTemplatesLayout" DependsOnTargets="BuildUnifiedProduct;ReSignDelaySignedAssemblies;BuildProjectTemplates">
+ <ItemGroup>
+ <ProjectTemplatesSource Include="$(ProjectRoot)\projecttemplates\**\*"
+ Exclude="
+ $(ProjectRoot)\projecttemplates\**\*.sln.cache;
+ $(ProjectRoot)\projecttemplates\**\*.suo;
+ $(ProjectRoot)\projecttemplates\**\*.gitignore;
+ $(ProjectRoot)\projecttemplates\**\*.log*;
+ $(ProjectRoot)\projecttemplates\**\*~;
+ $(ProjectRoot)\projecttemplates\**\Settings.StyleCop;
+ $(ProjectRoot)\projecttemplates\**\StyleCop.Cache;
+ $(ProjectRoot)\projecttemplates\**\*.user;
+ $(ProjectRoot)\projecttemplates\**\obj\**;
+ $(ProjectRoot)\projecttemplates\**\bin\DotNetOpenAuth.dll;
+ $(ProjectRoot)\projecttemplates\**\bin\DotNetOpenAuth.pdb;
+ $(ProjectRoot)\projecttemplates\**\bin\Microsoft.Contracts.dll;
+ $(ProjectRoot)\projecttemplates\**\*.ldf;
+ $(ProjectRoot)\projecttemplates\**\*.mdf;
+ "/>
+ <_ProjectTemplatesTransformSource Include="@(ProjectTemplatesSource)" Condition="
+ '%(Extension)' == '.cs'
+ or '%(Extension)' == '.csproj'
+ or '%(Extension)' == '.config'
+ or '%(Extension)' == '.Master'
+ or '%(Extension)' == '.aspx'
+ or '%(Extension)' == '.asax'
+ ">
+ <BeforeTokens>%(RecursiveDir)</BeforeTokens>
+ <AfterTokens>$safeprojectname$</AfterTokens>
+ </_ProjectTemplatesTransformSource>
+ <ProjectTemplatesSource Remove="@(_ProjectTemplatesTransformSource)" />
+
+ <ProjectTemplatesLayout Include="@(ProjectTemplatesSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/>
+ <ProjectTemplatesTransformLayout Include="@(_ProjectTemplatesTransformSource->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)%(FileName)%(Extension)')"/>
+
+ <!-- Include the template icon -->
+ <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ProjectRoot)\doc\logo\dotnetopenid.ico')" />
+ <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)__TemplateIcon.ico')" />
+
+ <!-- Include the unified, signed version of the library -->
+ <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ILMergeOutputAssembly)')" />
+ <ProjectTemplatesSource Include="@(ProjectTemplates->'$(ILMergeOutputAssemblyDirectory)\$(ProductName).pdb')" />
+ <ProjectTemplatesSource Include="@(ProjectTemplates->'$(OutputPath)\$(ProductName).Contracts.dll')" />
+ <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).dll')" />
+ <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).pdb')" />
+ <ProjectTemplatesLayout Include="@(ProjectTemplates->'$(ProjectTemplatesLayoutPath)%(RecursiveDir)bin\$(ProductName).Contracts.dll')" />
+ </ItemGroup>
+ <Trim Inputs="@(_ProjectTemplatesTransformSource)" MetadataName="BeforeTokens" AllAfter="\">
+ <Output TaskParameter="Outputs" ItemName="ProjectTemplatesTransformSource" />
+ </Trim>
+ <MSBuild Projects="@(ProjectTemplates)" />
+ <RemoveDir Directories="$(ProjectTemplatesLayoutPath)" Condition="'$(NoClean)' != 'true'" />
+ <Copy SourceFiles="@(ProjectTemplatesSource)" DestinationFiles="@(ProjectTemplatesLayout)" SkipUnchangedFiles="true" />
+ <CopyWithTokenSubstitution SourceFiles="@(ProjectTemplatesTransformSource)" DestinationFiles="@(ProjectTemplatesTransformLayout)" SkipUnchangedFiles="true">
+ <Output TaskParameter="CopiedFiles" ItemName="CopiedProjectTemplateFiles" />
+ </CopyWithTokenSubstitution>
+ <ChangeProjectReferenceToAssemblyReference
+ Projects="@(CopiedProjectTemplateFiles)"
+ Condition="'%(Extension)' == '.csproj'"
+ ProjectReference="..\..\src\$(ProductName)\$(ProductName).csproj"
+ Reference="Bin\$(ProductName).dll" />
+ </Target>
+
+ <Target Name="ProjectTemplates" DependsOnTargets="ProjectTemplatesLayout">
+ <PropertyGroup>
+ <WebFormsRelyingPartyZipFile>$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty.zip</WebFormsRelyingPartyZipFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <WebFormsRelyingPartyProjectTemplateLayout Include="$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty\**\*" />
+ </ItemGroup>
+ <Delete Files="$(WebFormsRelyingPartyZipFile)" />
+ <Zip
+ Files="@(WebFormsRelyingPartyProjectTemplateLayout)"
+ ZipFileName="$(WebFormsRelyingPartyZipFile)"
+ WorkingDirectory="$(ProjectTemplatesLayoutPath)\WebFormsRelyingParty" />
+ </Target>
+
<Target Name="Documentation" DependsOnTargets="BuildProduct;Chm" Condition="'$(NoDocumentation)' != 'true'">
</Target>
@@ -119,31 +231,17 @@
<Target Name="_SetDropProperties">
<!-- This target is necessary because PropertyGroups within the same Target as
where CallTarget is fired do NOT affect those called targets. -->
- <PropertyGroup>
- <Sign Condition="'$(Sign)' == ''">true</Sign>
- </PropertyGroup>
-
<!-- The rest of these are here so that other DependsOn targets have access to these properties. -->
<PropertyGroup>
- <DropDirectory>$(ProjectRoot)\drops\$(ProductName)-$(BuildVersion)</DropDirectory>
+ <DropDirectory>$(DropsRoot)\$(ProductName)-$(BuildVersion)</DropDirectory>
</PropertyGroup>
</Target>
- <Target Name="_EnsureCleanDrop" Condition="'$(NoClean)' != 'true'">
- <!-- This target only does a clean sufficient to guarantee that our DotNetOpenAuth.dll is rebuilt, but
- we don't usually want to clean our documentation because that takes forever to build froms scratch. -->
- <MSBuild Projects="$(SolutionPath)" Targets="Clean" />
-
- <!-- clean up any previous drop with the same name so we don't aggregate files. -->
- <RemoveDir Directories="$(DropDirectory)" />
- </Target>
-
- <Target Name="DropLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;_EnsureCleanDrop;BuildProduct;BuildSamples;Documentation">
- <Warning Condition=" '$(Configuration)' != 'release' " Text="Building $(Configuration) instead of Release!" />
- <Warning Condition=" '$(Sign)' != 'true' " Text="Building unsigned!" />
+ <Target Name="DropLayout" DependsOnTargets="GetBuildVersion;_SetDropProperties;BuildUnifiedProduct;ReSignDelaySignedAssemblies;BuildSamples;ProjectTemplates;Documentation">
<PropertyGroup>
<DropBinDirectory>$(DropDirectory)\Bin</DropBinDirectory>
<DropLibDirectory>$(DropDirectory)\Lib</DropLibDirectory>
+ <DropProjectTemplatesDirectory>$(DropDirectory)\Project Templates</DropProjectTemplatesDirectory>
<DropSamplesDirectory>$(DropDirectory)\Samples</DropSamplesDirectory>
<DropSpecsDirectory>$(DropDirectory)\Specs</DropSpecsDirectory>
</PropertyGroup>
@@ -152,6 +250,7 @@
$(DropDirectory);
$(DropBinDirectory);
$(DropLibDirectory);
+ $(DropProjectTemplatesDirectory);
$(DropSamplesDirectory);
$(DropSpecsDirectory);
" />
@@ -164,16 +263,19 @@
"
Exclude="$(ProjectRoot)\Doc\README.*.html;" />
<DropBinSourceFiles Include="
- $(OutputPath)\$(ProductName).???;
+ $(ILMergeOutputAssemblyDirectory)\$(ProductName).???;
+ $(OutputPath)\**\$(ProductName).resources.dll;
+ $(OutputPath)\$(ProductName).xml;
+ $(OutputPath)\$(ProductName).Contracts.???;
$(ProjectRoot)\Doc\README.Bin.html;
$(ProjectRoot)\src\$(ProductName)\Configuration\$(ProductName).xsd;
" />
<DropLibSourceFiles Include="
$(ProjectRoot)\Lib\log4net.*;
" />
+ <DropProjectTemplatesSourceFiles Include="$(ProjectTemplatesLayoutPath)\*.zip" />
<DropSamplesSourceFiles Include="$(ProjectRoot)\Samples\**" Exclude="
$(ProjectRoot)\**\obj\**;
- $(ProjectRoot)\**\*.user;
$(ProjectRoot)\**\*.sln.cache;
$(ProjectRoot)\**\*.suo;
$(ProjectRoot)\**\*.user;
@@ -183,6 +285,7 @@
$(ProjectRoot)\**\*~;
$(ProjectRoot)\**\Debug\**;
$(ProjectRoot)\**\Settings.StyleCop;
+ $(ProjectRoot)\**\StyleCop.Cache;
$(ProjectRoot)\Samples\**\DotNetOpenAuth.???;
$(ProjectRoot)\Samples\**\log4net.???;
$(ProjectRoot)\Samples\**\PresentationCore.dll;
@@ -196,6 +299,7 @@
<DropFiles Include="@(DropSourceFiles->'$(DropDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
<DropBinFiles Include="@(DropBinSourceFiles->'$(DropBinDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
<DropLibFiles Include="@(DropLibSourceFiles->'$(DropLibDirectory)\%(RecurisveDir)%(FileName)%(Extension)')"/>
+ <DropProjectTemplatesFiles Include="@(DropProjectTemplatesSourceFiles->'$(DropProjectTemplatesDirectory)\%(FileName)%(Extension)')" />
<DropSamplesFiles Include="@(DropSamplesSourceFiles->'$(DropSamplesDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
<DropSamplesRefreshFiles Include="@(DropSamplesRefreshSourceFiles->'$(DropSamplesDirectory)\%(RecursiveDir)%(FileName).refresh')"/>
<DropSpecsFiles Include="@(DropSpecsSourceFiles->'$(DropSpecsDirectory)\%(RecursiveDir)%(FileName)%(Extension)')"/>
@@ -204,6 +308,7 @@
@(DropSourceFiles);
@(DropBinSourceFiles);
@(DropLibSourceFiles);
+ @(DropProjectTemplatesSourceFiles);
@(DropSamplesSourceFiles);
@(DropSamplesRefreshSourceFiles);
@(DropDocSourceFiles);
@@ -214,6 +319,7 @@
@(DropFiles);
@(DropBinFiles);
@(DropLibFiles);
+ @(DropProjectTemplatesFiles);
@(DropSamplesFiles);
@(DropSamplesRefreshFiles);
@(DropDocFiles);
@@ -221,6 +327,8 @@
" />
</ItemGroup>
+ <!-- clean up any previous drop with the same name so we don't aggregate files. -->
+ <RemoveDir Directories="$(DropDirectory)" Condition="'$(NoClean)' != 'true'" />
<MakeDir Directories="@(DropDirectories)" />
<Copy SourceFiles="@(AllDropSources)" DestinationFiles="@(AllDropTargets)" SkipUnchangedFiles="true" />
<!-- fix up the samples so that they will compile right out of the drop -->
@@ -236,7 +344,7 @@
<DropZip>$(DropDirectory).zip</DropZip>
</PropertyGroup>
<Delete Files="$(DropZip)" />
- <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(ProjectRoot)\drops" />
+ <Zip Files="@(AllDropTargets)" ZipFileName="$(DropZip)" WorkingDirectory="$(DropsRoot)" />
</Target>
<!-- Although Nightly includes publishing samples and docs, those targets are conditioned for
@@ -244,5 +352,4 @@
<Target Name="Nightly" DependsOnTargets="Drop;Tools;PublishSamples;PublishDocumentation">
</Target>
-
</Project>
diff --git a/doc/logo/dotnetopenid.ico b/doc/logo/dotnetopenid.ico
index beb3cb5..5cd6121 100644
--- a/doc/logo/dotnetopenid.ico
+++ b/doc/logo/dotnetopenid.ico
Binary files differ
diff --git a/lib/DotNetOpenAuth.BuildTasks.dll b/lib/DotNetOpenAuth.BuildTasks.dll
index d11865f..a246041 100644
--- a/lib/DotNetOpenAuth.BuildTasks.dll
+++ b/lib/DotNetOpenAuth.BuildTasks.dll
Binary files differ
diff --git a/lib/DotNetOpenAuth.BuildTasks.pdb b/lib/DotNetOpenAuth.BuildTasks.pdb
index dda205e..96ea71a 100644
--- a/lib/DotNetOpenAuth.BuildTasks.pdb
+++ b/lib/DotNetOpenAuth.BuildTasks.pdb
Binary files differ
diff --git a/lib/DotNetOpenAuth.BuildTasks.targets b/lib/DotNetOpenAuth.BuildTasks.targets
index 024b43a..cfc9e18 100644
--- a/lib/DotNetOpenAuth.BuildTasks.targets
+++ b/lib/DotNetOpenAuth.BuildTasks.targets
@@ -15,5 +15,7 @@
<UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="DeleteWebApplication" />
<UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="Trim" />
<UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="FilterItems" />
+ <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="JsPack" />
+ <UsingTask AssemblyFile="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.dll" TaskName="CopyWithTokenSubstitution" />
</Project>
diff --git a/lib/Microsoft.Contracts.dll b/lib/Microsoft.Contracts.dll
index ee1160c..012c506 100644
--- a/lib/Microsoft.Contracts.dll
+++ b/lib/Microsoft.Contracts.dll
Binary files differ
diff --git a/projecttemplates/Settings.StyleCop b/projecttemplates/Settings.StyleCop
new file mode 100644
index 0000000..f6b59ac
--- /dev/null
+++ b/projecttemplates/Settings.StyleCop
@@ -0,0 +1,44 @@
+<StyleCopSettings Version="4.3">
+ <Analyzers>
+ <Analyzer AnalyzerId="Microsoft.StyleCop.CSharp.DocumentationRules">
+ <Rules>
+ <Rule Name="FileMustHaveHeader">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="ElementsMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ <Rule Name="PartialElementsMustBeDocumented">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="Microsoft.StyleCop.CSharp.MaintainabilityRules">
+ <Rules>
+ <Rule Name="FieldsMustBePrivate">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ <Analyzer AnalyzerId="Microsoft.StyleCop.CSharp.NamingRules">
+ <Rules>
+ <Rule Name="ElementMustBeginWithUpperCaseLetter">
+ <RuleSettings>
+ <BooleanProperty Name="Enabled">False</BooleanProperty>
+ </RuleSettings>
+ </Rule>
+ </Rules>
+ <AnalyzerSettings />
+ </Analyzer>
+ </Analyzers>
+</StyleCopSettings> \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master
new file mode 100644
index 0000000..c50b73c
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master
@@ -0,0 +1,7 @@
+<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Admin.master.cs" Inherits="WebFormsRelyingParty.Admin.Admin"
+ MasterPageFile="~/Site.Master" %>
+
+<asp:Content ContentPlaceHolderID="Body" runat="server">
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+</asp:Content>
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.cs b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.cs
new file mode 100644
index 0000000..85f7608
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.cs
@@ -0,0 +1,19 @@
+//-----------------------------------------------------------------------
+// <copyright file="Admin.Master.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Admin {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ public partial class Admin : System.Web.UI.MasterPage {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.designer.cs b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.designer.cs
new file mode 100644
index 0000000..fa5ccb9
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Admin.Master.designer.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Admin {
+
+
+ public partial class Admin {
+
+ /// <summary>
+ /// Body control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ContentPlaceHolder Body;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql b/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql
new file mode 100644
index 0000000..99ac9db
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/CreateDatabase.sql
@@ -0,0 +1,128 @@
+/****** Object: Table [dbo].[User] Script Date: 10/08/2009 18:10:17 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[User](
+ [Id] [int] IDENTITY(1,1) NOT NULL,
+ [FirstName] [nvarchar](50) NULL,
+ [LastName] [nvarchar](50) NULL,
+ [EmailAddress] [nvarchar](100) NULL,
+ CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
+(
+ [Id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+GO
+/****** Object: Table [dbo].[Role] Script Date: 10/08/2009 18:10:17 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[Role](
+ [Id] [int] IDENTITY(1,1) NOT NULL,
+ [Name] [nvarchar](50) NOT NULL,
+ CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED
+(
+ [Id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+GO
+/****** Object: Table [dbo].[UserRole] Script Date: 10/08/2009 18:10:17 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[UserRole](
+ [UserId] [int] NOT NULL,
+ [RoleId] [int] NOT NULL,
+ CONSTRAINT [PK_UserRole] PRIMARY KEY CLUSTERED
+(
+ [UserId] ASC,
+ [RoleId] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+GO
+/****** Object: Table [dbo].[AuthenticationToken] Script Date: 10/08/2009 18:10:17 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE TABLE [dbo].[AuthenticationToken](
+ [Id] [int] IDENTITY(1,1) NOT NULL,
+ [UserId] [int] NOT NULL,
+ [OpenIdClaimedIdentifier] [nvarchar](250) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL, -- very important that claimed_id comparisons be case sensitive
+ [OpenIdFriendlyIdentifier] [nvarchar](250) NULL,
+ CONSTRAINT [PK_AuthenticationToken] PRIMARY KEY CLUSTERED
+(
+ [Id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+GO
+/****** Object: StoredProcedure [dbo].[AddUser] Script Date: 10/08/2009 18:10:32 ******/
+SET ANSI_NULLS ON
+GO
+SET QUOTED_IDENTIFIER ON
+GO
+CREATE PROCEDURE [dbo].[AddUser]
+ (
+ @firstName nvarchar(50),
+ @lastName nvarchar(50),
+ @openid nvarchar(255),
+ @role nvarchar(255)
+ )
+AS
+ DECLARE
+ @roleid int,
+ @userid int
+
+ BEGIN TRANSACTION
+
+ INSERT INTO [dbo].[User] (FirstName, LastName) VALUES (@firstName, @lastName)
+ SET @userid = (SELECT @@IDENTITY)
+
+ IF (SELECT COUNT(*) FROM dbo.Role WHERE [Name] = @role) = 0
+ BEGIN
+ INSERT INTO dbo.Role (Name) VALUES (@role)
+ SET @roleid = (SELECT @@IDENTITY)
+ END
+ ELSE
+ BEGIN
+ SET @roleid = (SELECT Id FROM dbo.Role WHERE [Name] = @role)
+ END
+
+ INSERT INTO dbo.UserRole (UserId, RoleId) VALUES (@userId, @roleid)
+
+ INSERT INTO dbo.AuthenticationToken
+ (UserId, OpenIdClaimedIdentifier, OpenIdFriendlyIdentifier)
+ VALUES
+ (@userid, @openid, @openid)
+
+ COMMIT TRANSACTION
+
+ RETURN @userid
+GO
+/****** Object: ForeignKey [FK_UserRole_Role] Script Date: 10/08/2009 18:10:17 ******/
+ALTER TABLE [dbo].[UserRole] WITH CHECK ADD CONSTRAINT [FK_UserRole_Role] FOREIGN KEY([RoleId])
+REFERENCES [dbo].[Role] ([Id])
+ON UPDATE CASCADE
+ON DELETE CASCADE
+GO
+ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_Role]
+GO
+/****** Object: ForeignKey [FK_UserRole_User] Script Date: 10/08/2009 18:10:17 ******/
+ALTER TABLE [dbo].[UserRole] WITH CHECK ADD CONSTRAINT [FK_UserRole_User] FOREIGN KEY([UserId])
+REFERENCES [dbo].[User] ([Id])
+ON UPDATE CASCADE
+ON DELETE CASCADE
+GO
+ALTER TABLE [dbo].[UserRole] CHECK CONSTRAINT [FK_UserRole_User]
+GO
+/****** Object: ForeignKey [FK_AuthenticationToken_User] Script Date: 10/08/2009 18:10:17 ******/
+ALTER TABLE [dbo].[AuthenticationToken] WITH CHECK ADD CONSTRAINT [FK_AuthenticationToken_User] FOREIGN KEY([UserId])
+REFERENCES [dbo].[User] ([Id])
+ON UPDATE CASCADE
+ON DELETE CASCADE
+GO
+ALTER TABLE [dbo].[AuthenticationToken] CHECK CONSTRAINT [FK_AuthenticationToken_User]
+GO
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx
new file mode 100644
index 0000000..7e3a03d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx
@@ -0,0 +1,52 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormsRelyingParty.Admin.Default" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ This is the specially-privileged Admin area. You can only reach here if you are
+ a member of the Admin role.
+ </div>
+ <asp:Repeater runat="server" ID="usersRepeater">
+ <HeaderTemplate>
+ <table border="1">
+ <thead>
+ <tr>
+ <td>
+ Email
+ </td>
+ <td>
+ Claimed IDs
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ </HeaderTemplate>
+ <ItemTemplate>
+ <tr>
+ <td>
+ <%# HttpUtility.HtmlEncode((string)Eval("EmailAddress")) %>
+ </td>
+ <td>
+ <asp:Repeater runat="server" DataSource='<%# Eval("AuthenticationTokens") %>'>
+ <ItemTemplate>
+ <%# HttpUtility.HtmlEncode((string)Eval("ClaimedIdentifier")) %>
+ </ItemTemplate>
+ <SeparatorTemplate>
+ <br />
+ </SeparatorTemplate>
+ </asp:Repeater>
+ </td>
+ </tr>
+ </ItemTemplate>
+ <FooterTemplate>
+ </tbody> </table>
+ </FooterTemplate>
+ </asp:Repeater>
+ </form>
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs
new file mode 100644
index 0000000..cc9abf1
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.cs
@@ -0,0 +1,24 @@
+//-----------------------------------------------------------------------
+// <copyright file="Default.aspx.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Admin {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Data.SqlClient;
+ using System.IO;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ public partial class Default : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.usersRepeater.DataSource = Global.DataContext.User.Include("AuthenticationTokens");
+ this.usersRepeater.DataBind();
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.designer.cs
new file mode 100644
index 0000000..aa45ea1
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Default.aspx.designer.cs
@@ -0,0 +1,34 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Admin {
+
+
+ public partial class Default {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// usersRepeater control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Repeater usersRepeater;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Admin/Web.config b/projecttemplates/WebFormsRelyingParty/Admin/Web.config
new file mode 100644
index 0000000..52a5faf
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Admin/Web.config
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <authorization>
+ <allow roles="Admin"/>
+ <deny users="*"/>
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs b/projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs
new file mode 100644
index 0000000..8117e4b
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Code/DataRoleProvider.cs
@@ -0,0 +1,123 @@
+//-----------------------------------------------------------------------
+// <copyright file="DataRoleProvider.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Security;
+
+ public class DataRoleProvider : RoleProvider {
+ public override string ApplicationName {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public override void AddUsersToRoles(string[] usernames, string[] roleNames) {
+ var users = from token in Global.DataContext.AuthenticationToken
+ where usernames.Contains(token.ClaimedIdentifier)
+ select token.User;
+ var roles = from role in Global.DataContext.Role
+ where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase)
+ select role;
+ foreach (User user in users) {
+ foreach (Role role in roles) {
+ user.Roles.Add(role);
+ }
+ }
+ }
+
+ public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) {
+ var users = from token in Global.DataContext.AuthenticationToken
+ where usernames.Contains(token.ClaimedIdentifier)
+ select token.User;
+ var roles = from role in Global.DataContext.Role
+ where roleNames.Contains(role.Name, StringComparer.OrdinalIgnoreCase)
+ select role;
+ foreach (User user in users) {
+ foreach (Role role in roles) {
+ user.Roles.Remove(role);
+ }
+ }
+ }
+
+ public override void CreateRole(string roleName) {
+ Global.DataContext.AddToRole(new Role { Name = roleName });
+ }
+
+ /// <summary>
+ /// Removes a role from the data source for the configured applicationName.
+ /// </summary>
+ /// <param name="roleName">The name of the role to delete.</param>
+ /// <param name="throwOnPopulatedRole">If true, throw an exception if <paramref name="roleName"/> has one or more members and do not delete <paramref name="roleName"/>.</param>
+ /// <returns>
+ /// true if the role was successfully deleted; otherwise, false.
+ /// </returns>
+ public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) {
+ Role role = Global.DataContext.Role.SingleOrDefault(r => r.Name == roleName);
+ if (role == null) {
+ return false;
+ }
+
+ if (throwOnPopulatedRole && role.Users.Count > 0) {
+ throw new InvalidOperationException();
+ }
+
+ Global.DataContext.DeleteObject(roleName);
+ return true;
+ }
+
+ /// <summary>
+ /// Gets an array of user names in a role where the user name contains the specified user name to match.
+ /// </summary>
+ /// <param name="roleName">The role to search in.</param>
+ /// <param name="usernameToMatch">The user name to search for.</param>
+ /// <returns>
+ /// A string array containing the names of all the users where the user name matches <paramref name="usernameToMatch"/> and the user is a member of the specified role.
+ /// </returns>
+ public override string[] FindUsersInRole(string roleName, string usernameToMatch) {
+ return (from role in Global.DataContext.Role
+ where role.Name == roleName
+ from user in role.Users
+ from authTokens in user.AuthenticationTokens
+ where authTokens.ClaimedIdentifier == usernameToMatch
+ select authTokens.ClaimedIdentifier).ToArray();
+ }
+
+ public override string[] GetAllRoles() {
+ return Global.DataContext.Role.Select(role => role.Name).ToArray();
+ }
+
+ public override string[] GetRolesForUser(string username) {
+ return (from authToken in Global.DataContext.AuthenticationToken
+ where authToken.ClaimedIdentifier == username
+ from role in authToken.User.Roles
+ select role.Name).ToArray();
+ }
+
+ public override string[] GetUsersInRole(string roleName) {
+ return (from role in Global.DataContext.Role
+ where string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase)
+ from user in role.Users
+ from token in user.AuthenticationTokens
+ select token.ClaimedIdentifier).ToArray();
+ }
+
+ public override bool IsUserInRole(string username, string roleName) {
+ Role role = Global.DataContext.Role.SingleOrDefault(r => string.Equals(r.Name, roleName, StringComparison.OrdinalIgnoreCase));
+ if (role != null) {
+ return role.Users.Any(user => user.AuthenticationTokens.Any(token => token.ClaimedIdentifier == username));
+ }
+
+ return false;
+ }
+
+ public override bool RoleExists(string roleName) {
+ return Global.DataContext.Role.Any(role => string.Equals(role.Name, roleName, StringComparison.OrdinalIgnoreCase));
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Default.aspx b/projecttemplates/WebFormsRelyingParty/Default.aspx
new file mode 100644
index 0000000..e470320
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Default.aspx
@@ -0,0 +1,12 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormsRelyingParty._Default"
+ MasterPageFile="~/Site.Master" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth" TagPrefix="dnoa" %>
+<asp:Content runat="server" ContentPlaceHolderID="head">
+ <dnoa:XrdsPublisher runat="server" XrdsUrl="~/xrds.aspx" XrdsAdvertisement="Both" />
+</asp:Content>
+<asp:Content runat="server" ContentPlaceHolderID="Body">
+ <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
+ <asp:HyperLink ID="HyperLink1" NavigateUrl="~/Members/Default.aspx" Text="Visit the Members Only area"
+ runat="server" />
+</asp:Content>
diff --git a/projecttemplates/WebFormsRelyingParty/Default.aspx.cs b/projecttemplates/WebFormsRelyingParty/Default.aspx.cs
new file mode 100644
index 0000000..a72fce1
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Default.aspx.cs
@@ -0,0 +1,21 @@
+//-----------------------------------------------------------------------
+// <copyright file="Default.aspx.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ public partial class _Default : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ User user = Global.LoggedInUser;
+ this.Label1.Text = user != null ? user.FirstName : "<not logged in>";
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Default.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Default.aspx.designer.cs
new file mode 100644
index 0000000..9c12f15
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Default.aspx.designer.cs
@@ -0,0 +1,34 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class _Default {
+
+ /// <summary>
+ /// Label1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label Label1;
+
+ /// <summary>
+ /// HyperLink1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HyperLink HyperLink1;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/GettingStarted.htm b/projecttemplates/WebFormsRelyingParty/GettingStarted.htm
new file mode 100644
index 0000000..9a3fbb7
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/GettingStarted.htm
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head>
+ <title>Getting started</title>
+</head>
+<body>
+
+ <p>
+ Your OpenID and InfoCard relying party web site is nearly ready to go. You just
+ need to create your SQL database where user accounts will be stored.&nbsp; <b>
+ Just build and start your web site </b>and visit Default.aspx.&nbsp; You&#39;ll get
+ further instructions there.&nbsp;
+ </p>
+ <p>
+ Creating your database is almost totally automated, so it should be a piece of
+ cake.</p>
+
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/Global.asax b/projecttemplates/WebFormsRelyingParty/Global.asax
new file mode 100644
index 0000000..ff6cdb1
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="WebFormsRelyingParty.Global" Language="C#" %>
diff --git a/projecttemplates/WebFormsRelyingParty/Global.asax.cs b/projecttemplates/WebFormsRelyingParty/Global.asax.cs
new file mode 100644
index 0000000..15a1047
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Global.asax.cs
@@ -0,0 +1,178 @@
+//-----------------------------------------------------------------------
+// <copyright file="Global.asax.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Data;
+ using System.Data.SqlClient;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.Web;
+
+ public class Global : System.Web.HttpApplication {
+ private const string DataContextKey = "DataContext";
+
+ private const string DataContextTransactionKey = "DataContextTransaction";
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ private static log4net.ILog logger = log4net.LogManager.GetLogger("DotNetOpenAuth.ConsumerSample");
+
+ public static log4net.ILog Logger {
+ get { return logger; }
+ }
+
+ public static User LoggedInUser {
+ get { return Global.DataContext.AuthenticationToken.Where(token => token.ClaimedIdentifier == HttpContext.Current.User.Identity.Name).Select(token => token.User).FirstOrDefault(); }
+ }
+
+ public static string ApplicationPath {
+ get {
+ string path = HttpContext.Current.Request.ApplicationPath;
+ if (!path.EndsWith("/")) {
+ path += "/";
+ }
+
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Gets the transaction-protected database connection for the current request.
+ /// </summary>
+ public static DatabaseEntities DataContext {
+ get {
+ DatabaseEntities dataContext = DataContextSimple;
+ if (dataContext == null) {
+ dataContext = new DatabaseEntities();
+ try {
+ dataContext.Connection.Open();
+ } catch (EntityException entityEx) {
+ var sqlEx = entityEx.InnerException as SqlException;
+ if (sqlEx != null) {
+ if (sqlEx.Class == 14 && sqlEx.Number == 15350) {
+ // Most likely the database schema hasn't been created yet.
+ HttpContext.Current.Response.Redirect("~/Setup.aspx");
+ }
+ }
+
+ throw;
+ }
+
+ DataContextTransactionSimple = dataContext.Connection.BeginTransaction();
+ DataContextSimple = dataContext;
+ }
+
+ return dataContext;
+ }
+ }
+
+ private static DatabaseEntities DataContextSimple {
+ get {
+ if (HttpContext.Current != null) {
+ return HttpContext.Current.Items[DataContextKey] as DatabaseEntities;
+ } else if (OperationContext.Current != null) {
+ object data;
+ if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextKey, out data)) {
+ return data as DatabaseEntities;
+ } else {
+ return null;
+ }
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ set {
+ if (HttpContext.Current != null) {
+ HttpContext.Current.Items[DataContextKey] = value;
+ } else if (OperationContext.Current != null) {
+ OperationContext.Current.IncomingMessageProperties[DataContextKey] = value;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ private static IDbTransaction DataContextTransactionSimple {
+ get {
+ if (HttpContext.Current != null) {
+ return HttpContext.Current.Items[DataContextTransactionKey] as IDbTransaction;
+ } else if (OperationContext.Current != null) {
+ object data;
+ if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextTransactionKey, out data)) {
+ return data as IDbTransaction;
+ } else {
+ return null;
+ }
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ set {
+ if (HttpContext.Current != null) {
+ HttpContext.Current.Items[DataContextTransactionKey] = value;
+ } else if (OperationContext.Current != null) {
+ OperationContext.Current.IncomingMessageProperties[DataContextTransactionKey] = value;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ protected void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Web application starting...");
+ }
+
+ protected void Session_Start(object sender, EventArgs e) {
+ }
+
+ protected void Application_BeginRequest(object sender, EventArgs e) {
+ }
+
+ protected void Application_EndRequest(object sender, EventArgs e) {
+ CommitAndCloseDatabaseIfNecessary();
+ }
+
+ protected void Application_AuthenticateRequest(object sender, EventArgs e) {
+ }
+
+ protected void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+ if (DataContextTransactionSimple != null) {
+ DataContextTransactionSimple.Rollback();
+ DataContextTransactionSimple.Dispose();
+ }
+ }
+
+ protected void Session_End(object sender, EventArgs e) {
+ }
+
+ protected void Application_End(object sender, EventArgs e) {
+ Logger.Info("Web application shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ private static void CommitAndCloseDatabaseIfNecessary() {
+ var dataContext = DataContextSimple;
+ if (dataContext != null) {
+ dataContext.SaveChanges();
+ if (DataContextTransactionSimple != null) {
+ DataContextTransactionSimple.Commit();
+ DataContextTransactionSimple.Dispose();
+ }
+
+ dataContext.Dispose();
+ DataContextSimple = null;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/Login.aspx b/projecttemplates/WebFormsRelyingParty/Login.aspx
new file mode 100644
index 0000000..ae3599d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Login.aspx
@@ -0,0 +1,10 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebFormsRelyingParty.Login"
+ MasterPageFile="~/Site.Master" ValidateRequest="false" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.InfoCard" TagPrefix="ic" %>
+<asp:Content runat="server" ContentPlaceHolderID="Body">
+ <h2>Login</h2>
+ <iframe src="LoginFrame.aspx" frameborder="0" width="355" height="273"></iframe>
+</asp:Content>
diff --git a/projecttemplates/WebFormsRelyingParty/Login.aspx.cs b/projecttemplates/WebFormsRelyingParty/Login.aspx.cs
new file mode 100644
index 0000000..5c57d35
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Login.aspx.cs
@@ -0,0 +1,23 @@
+//-----------------------------------------------------------------------
+// <copyright file="Login.aspx.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Security;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public partial class Login : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Login.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Login.aspx.designer.cs
new file mode 100644
index 0000000..30a38cb
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Login.aspx.designer.cs
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class Login {
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx
new file mode 100644
index 0000000..b074076
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx
@@ -0,0 +1,65 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="LoginFrame.aspx.cs" Inherits="WebFormsRelyingParty.LoginFrame"
+ EnableViewState="false" ValidateRequest="false" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- COPYRIGHT (C) 2009 Andrew Arnott. All rights reserved. -->
+<!-- LICENSE: Microsoft Public License available at http://opensource.org/licenses/ms-pl.html -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <link type="text/css" href="theme/ui.all.css" rel="Stylesheet" />
+ <link href="styles/loginpopup.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<% if (Request.Url.IsLoopback) { %>
+ <script type="text/javascript" src="scripts/jquery-1.3.1.js"></script>
+ <script type="text/javascript" src="scripts/jquery-ui-personalized-1.6rc6.js"></script>
+<% } else { %>
+ <script type="text/javascript" language="javascript" src="http://www.google.com/jsapi"></script>
+ <script type="text/javascript" language="javascript">
+ google.load("jquery", "1.3.2");
+ google.load("jqueryui", "1.7.2");
+ </script>
+<% } %>
+
+ <script type="text/javascript" src="scripts/jquery.cookie.js"></script>
+
+ <form runat="server" id="form1" target="_top">
+ <div class="wrapper">
+ <p>
+ Login with an account you already use!
+ </p>
+ <rp:OpenIdSelector runat="server" ID="openIdSelector" OnLoggedIn="openIdSelector_LoggedIn"
+ OnFailed="openIdSelector_Failed" OnCanceled="openIdSelector_Failed" OnReceivedToken="openIdSelector_ReceivedToken"
+ OnTokenProcessingError="openIdSelector_TokenProcessingError">
+ <Buttons>
+ <rp:SelectorProviderButton OPIdentifier="https://me.yahoo.com/" Image="images/yahoo.gif" />
+ <rp:SelectorProviderButton OPIdentifier="https://www.google.com/accounts/o8/id" Image="images/google.gif" />
+ <rp:SelectorProviderButton OPIdentifier="https://www.myopenid.com/" Image="images/myopenid.png" />
+ <rp:SelectorProviderButton OPIdentifier="https://pip.verisignlabs.com/" Image="images/verisign.gif" SkipBackgroundAuthentication="true" />
+ <rp:SelectorOpenIdButton Image="images/openid.gif" />
+ <rp:SelectorInfoCardButton />
+ </Buttons>
+ </rp:OpenIdSelector>
+ <asp:HiddenField runat="server" ID="topWindowUrl" />
+ <asp:Panel ID="errorPanel" runat="server" EnableViewState="false" Visible="false" ForeColor="Red">
+ Oops. Something went wrong while logging you in. Trying again may work. <a href="#" onclick="$('#errorMessage').show()">
+ What went wrong?</a>
+ <span id="errorMessage" style="display: none">
+ <asp:Label ID="errorMessageLabel" runat="server" Text="Login canceled." />
+ </span>
+ </asp:Panel>
+ <div class="helpDoc">
+ <p>
+ If you have logged in previously, click the same button you did last time.
+ </p>
+ <p>
+ If you don't have an account with any of these services, just pick Google. They'll
+ help you set up an account.
+ </p>
+ </div>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs
new file mode 100644
index 0000000..2528b36
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.cs
@@ -0,0 +1,98 @@
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Security;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.InfoCard;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public partial class LoginFrame : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ // Because this page can appear as an iframe in a popup of another page,
+ // we need to record which page the hosting page is in order to redirect back
+ // to it after login is complete.
+ this.ClientScript.RegisterOnSubmitStatement(
+ this.GetType(),
+ "getTopWindowUrl",
+ "document.getElementById('topWindowUrl').value = window.parent.location.href;");
+ }
+ }
+
+ protected void openIdSelector_LoggedIn(object sender, OpenIdEventArgs e) {
+ this.LoginUser(e.ClaimedIdentifier, e.Response.FriendlyIdentifierForDisplay, e.Response.GetExtension<ClaimsResponse>());
+ }
+
+ protected void openIdSelector_ReceivedToken(object sender, DotNetOpenAuth.InfoCard.ReceivedTokenEventArgs e) {
+ this.LoginUser(AuthenticationToken.SynthesizeClaimedIdentifierFromInfoCard(e.Token.UniqueId), e.Token.SiteSpecificId, null);
+ }
+
+ protected void openIdSelector_Failed(object sender, OpenIdEventArgs e) {
+ if (e.Response.Exception != null) {
+ this.errorMessageLabel.Text = e.Response.Exception.Message;
+ }
+ this.errorPanel.Visible = true;
+ }
+
+ protected void openIdSelector_TokenProcessingError(object sender, TokenProcessingErrorEventArgs e) {
+ this.errorMessageLabel.Text = e.Exception.Message;
+ this.errorPanel.Visible = true;
+ }
+
+ private void LoginUser(string claimedIdentifier, string friendlyIdentifier, ClaimsResponse claims) {
+ // Create an account for this user if we don't already have one.
+ AuthenticationToken openidToken = Global.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedIdentifier);
+ if (openidToken == null) {
+ // this is a user we haven't seen before.
+ User user = new User();
+ openidToken = new AuthenticationToken {
+ ClaimedIdentifier = claimedIdentifier,
+ FriendlyIdentifier = friendlyIdentifier,
+ };
+ user.AuthenticationTokens.Add(openidToken);
+
+ // Gather information about the user if it's available.
+ if (claims != null) {
+ if (!string.IsNullOrEmpty(claims.Email)) {
+ user.EmailAddress = claims.Email;
+ }
+ if (!string.IsNullOrEmpty(claims.FullName)) {
+ if (claims.FullName.IndexOf(' ') > 0) {
+ user.FirstName = claims.FullName.Substring(0, claims.FullName.IndexOf(' ')).Trim();
+ user.LastName = claims.FullName.Substring(claims.FullName.IndexOf(' ')).Trim();
+ } else {
+ user.FirstName = claims.FullName;
+ }
+ }
+ }
+
+ Global.DataContext.AddToUser(user);
+ }
+
+ bool persistentCookie = false;
+ if (string.IsNullOrEmpty(this.Request.QueryString["ReturnUrl"])) {
+ FormsAuthentication.SetAuthCookie(openidToken.ClaimedIdentifier, persistentCookie);
+ if (!string.IsNullOrEmpty(this.topWindowUrl.Value)) {
+ Uri topWindowUri = new Uri(this.topWindowUrl.Value);
+ string returnUrl = HttpUtility.ParseQueryString(topWindowUri.Query)["ReturnUrl"];
+ if (string.IsNullOrEmpty(returnUrl)) {
+ Response.Redirect(this.topWindowUrl.Value);
+ } else {
+ Response.Redirect(returnUrl);
+ }
+ } else {
+ // This happens for unsolicited assertions.
+ Response.Redirect("~/");
+ }
+ } else {
+ FormsAuthentication.RedirectFromLoginPage(openidToken.ClaimedIdentifier, persistentCookie);
+ }
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.designer.cs
new file mode 100644
index 0000000..469b8a6
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/LoginFrame.aspx.designer.cs
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class LoginFrame {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// openIdSelector control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector openIdSelector;
+
+ /// <summary>
+ /// topWindowUrl control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HiddenField topWindowUrl;
+
+ /// <summary>
+ /// errorPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel errorPanel;
+
+ /// <summary>
+ /// errorMessageLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label errorMessageLabel;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Logout.aspx b/projecttemplates/WebFormsRelyingParty/Logout.aspx
new file mode 100644
index 0000000..abba0c1
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Logout.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Logout.aspx.cs" Inherits="WebFormsRelyingParty.Logout" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+
+ </div>
+ </form>
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/Logout.aspx.cs b/projecttemplates/WebFormsRelyingParty/Logout.aspx.cs
new file mode 100644
index 0000000..0e53fac
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Logout.aspx.cs
@@ -0,0 +1,11 @@
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Web.Security;
+
+ public partial class Logout : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ FormsAuthentication.SignOut();
+ Response.Redirect("~/");
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Logout.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Logout.aspx.designer.cs
new file mode 100644
index 0000000..19ef79d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Logout.aspx.designer.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class Logout {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx
new file mode 100644
index 0000000..46040ff
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx
@@ -0,0 +1,99 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AccountInfo.aspx.cs" Inherits="WebFormsRelyingParty.Members.AccountInfo"
+ MasterPageFile="~/Site.Master" ValidateRequest="false" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.InfoCard" TagPrefix="ic" %>
+<%@ Register Assembly="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
+ Namespace="System.Web.UI.WebControls" TagPrefix="asp" %>
+<asp:Content runat="server" ContentPlaceHolderID="Body">
+ <asp:ScriptManager ID="ScriptManager1" runat="server" />
+ <h3>
+ Personal information
+ </h3>
+ <asp:UpdatePanel ID="UpdatePanel1" runat="server">
+ <ContentTemplate>
+ <table>
+ <tr>
+ <td>
+ First name
+ </td>
+ <td>
+ <asp:TextBox ID="firstNameBox" runat="server" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Last name
+ </td>
+ <td>
+ <asp:TextBox ID="lastNameBox" runat="server" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Email
+ </td>
+ <td>
+ <asp:TextBox ID="emailBox" runat="server" Columns="40" ValidationGroup="Profile" />
+ <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="emailBox"
+ ErrorMessage="Invalid email address" ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
+ ValidationGroup="Profile">invalid</asp:RegularExpressionValidator>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>
+ <asp:Button ID="saveChanges" runat="server" Text="Save profile changes" OnClick="saveChanges_Click"
+ ValidationGroup="Profile" />
+ <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"
+ DynamicLayout="true">
+ <ProgressTemplate>
+ Saving...
+ </ProgressTemplate>
+ </asp:UpdateProgress>
+ </td>
+ </tr>
+ </table>
+ </ContentTemplate>
+ <Triggers>
+ <asp:AsyncPostBackTrigger ControlID="saveChanges" EventName="Click" />
+ </Triggers>
+ </asp:UpdatePanel>
+ <h3>
+ OpenIDs &amp; InfoCards
+ </h3>
+ <asp:Repeater ID="Repeater1" runat="server">
+ <HeaderTemplate>
+ <ul class="AuthTokens">
+ </HeaderTemplate>
+ <ItemTemplate>
+ <li class='<%# ((bool)Eval("IsInfoCard")) ? "InfoCard" : "OpenID" %>'>
+ <asp:Label ID="OpenIdClaimedIdentifierLabel" runat="server" Text='<%# Eval("FriendlyIdentifier") %>'
+ ToolTip='<%# Eval("ClaimedIdentifier") %>' />
+ <asp:Label runat="server" ForeColor="Gray" Text="(current login token)" ToolTip="To delete this token, you must log in using some other token."
+ Visible='<%# String.Equals((string)Eval("ClaimedIdentifier"), Page.User.Identity.Name, StringComparison.Ordinal) %>' />
+ <asp:LinkButton runat="server" Text="remove" CommandName="delete" CommandArgument='<%# Eval("ClaimedIdentifier") %>'
+ ID="deleteOpenId" OnCommand="deleteOpenId_Command" Visible='<%# !String.Equals((string)Eval("ClaimedIdentifier"), Page.User.Identity.Name, StringComparison.Ordinal) %>' />
+ </li>
+ </ItemTemplate>
+ <FooterTemplate>
+ </ul>
+ </FooterTemplate>
+ </asp:Repeater>
+ <asp:Panel ID="Panel1" runat="server">
+ <rp:OpenIdAjaxTextBox runat="server" ID="openIdBox" OnLoggedIn="openIdBox_LoggedIn"
+ AutoPostBack="true" />
+ <asp:Label ID="differentAccountLabel" runat="server" EnableViewState="False" ForeColor="Red"
+ Text="This identifier already belongs to a different user account." Visible="False" />
+ <asp:Label ID="alreadyLinkedLabel" runat="server" EnableViewState="False" ForeColor="Red"
+ Text="This identifier is already linked to your account." Visible="False" />
+ </asp:Panel>
+ <asp:Panel ID="Panel2" runat="server">
+ <ic:InfoCardSelector ID="InfoCardSelector1" runat="server" ImageSize="Size92x64"
+ ToolTip="Log in with your Information Card" OnReceivedToken="InfoCardSelector1_ReceivedToken">
+ <ic:ClaimType Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier" />
+ </ic:InfoCardSelector>
+ </asp:Panel>
+</asp:Content>
diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs
new file mode 100644
index 0000000..f35a0ce
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.cs
@@ -0,0 +1,82 @@
+//-----------------------------------------------------------------------
+// <copyright file="AccountInfo.aspx.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Members {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.InfoCard;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public partial class AccountInfo : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ Global.LoggedInUser.AuthenticationTokens.Load();
+ this.Repeater1.DataSource = Global.LoggedInUser.AuthenticationTokens;
+ if (!IsPostBack) {
+ this.Repeater1.DataBind();
+ this.emailBox.Text = Global.LoggedInUser.EmailAddress;
+ this.firstNameBox.Text = Global.LoggedInUser.FirstName;
+ this.lastNameBox.Text = Global.LoggedInUser.LastName;
+ }
+
+ this.firstNameBox.Focus();
+ }
+
+ protected void openIdBox_LoggedIn(object sender, OpenIdEventArgs e) {
+ this.AddIdentifier(e.ClaimedIdentifier, e.Response.FriendlyIdentifierForDisplay);
+ this.openIdBox.Focus();
+ }
+
+ protected void deleteOpenId_Command(object sender, CommandEventArgs e) {
+ string claimedId = (string)e.CommandArgument;
+ var token = Global.DataContext.AuthenticationToken.First(t => t.ClaimedIdentifier == claimedId && t.User.Id == Global.LoggedInUser.Id);
+ Global.DataContext.DeleteObject(token);
+ Global.DataContext.SaveChanges();
+ this.Repeater1.DataBind();
+ }
+
+ protected void saveChanges_Click(object sender, EventArgs e) {
+ if (!IsValid) {
+ return;
+ }
+
+ Global.LoggedInUser.EmailAddress = this.emailBox.Text;
+ Global.LoggedInUser.FirstName = this.firstNameBox.Text;
+ Global.LoggedInUser.LastName = this.lastNameBox.Text;
+ }
+
+ protected void InfoCardSelector1_ReceivedToken(object sender, ReceivedTokenEventArgs e) {
+ this.AddIdentifier(AuthenticationToken.SynthesizeClaimedIdentifierFromInfoCard(e.Token.UniqueId), e.Token.SiteSpecificId);
+ }
+
+ private void AddIdentifier(string claimedId, string friendlyId) {
+ // Check that this identifier isn't already tied to a user account.
+ // We do this again here in case the LoggingIn event couldn't verify
+ // and in case somehow the OP changed it anyway.
+ var existingToken = Global.DataContext.AuthenticationToken.FirstOrDefault(token => token.ClaimedIdentifier == claimedId);
+ if (existingToken == null) {
+ var token = new AuthenticationToken();
+ token.ClaimedIdentifier = claimedId;
+ token.FriendlyIdentifier = friendlyId;
+ Global.LoggedInUser.AuthenticationTokens.Add(token);
+ Global.DataContext.SaveChanges();
+ this.Repeater1.DataBind();
+
+ // Clear the box for the next entry
+ this.openIdBox.Text = string.Empty;
+ } else {
+ if (existingToken.User == Global.LoggedInUser) {
+ this.alreadyLinkedLabel.Visible = true;
+ } else {
+ this.differentAccountLabel.Visible = true;
+ }
+ }
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs
new file mode 100644
index 0000000..c3f5b15
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/AccountInfo.aspx.designer.cs
@@ -0,0 +1,151 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Members {
+
+
+ public partial class AccountInfo {
+
+ /// <summary>
+ /// ScriptManager1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.ScriptManager ScriptManager1;
+
+ /// <summary>
+ /// UpdatePanel1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.UpdatePanel UpdatePanel1;
+
+ /// <summary>
+ /// firstNameBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox firstNameBox;
+
+ /// <summary>
+ /// lastNameBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox lastNameBox;
+
+ /// <summary>
+ /// emailBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox emailBox;
+
+ /// <summary>
+ /// RegularExpressionValidator1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidator1;
+
+ /// <summary>
+ /// saveChanges control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button saveChanges;
+
+ /// <summary>
+ /// UpdateProgress1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.UpdateProgress UpdateProgress1;
+
+ /// <summary>
+ /// Repeater1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Repeater Repeater1;
+
+ /// <summary>
+ /// Panel1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel Panel1;
+
+ /// <summary>
+ /// openIdBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox openIdBox;
+
+ /// <summary>
+ /// differentAccountLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label differentAccountLabel;
+
+ /// <summary>
+ /// alreadyLinkedLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label alreadyLinkedLabel;
+
+ /// <summary>
+ /// Panel2 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel Panel2;
+
+ /// <summary>
+ /// InfoCardSelector1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.InfoCard.InfoCardSelector InfoCardSelector1;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Members/Default.aspx b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx
new file mode 100644
index 0000000..157237f
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx
@@ -0,0 +1,9 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormsRelyingParty.Members.Default"
+ MasterPageFile="~/Site.Master" %>
+
+<asp:Content runat="server" ContentPlaceHolderID="Body">
+ <h2>Members Only</h2>
+ <div>
+ You've made it to the Members Only area.
+ </div>
+</asp:Content>
diff --git a/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.cs b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.cs
new file mode 100644
index 0000000..8460541
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.cs
@@ -0,0 +1,13 @@
+namespace WebFormsRelyingParty.Members {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ public partial class Default : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.designer.cs
new file mode 100644
index 0000000..2daf037
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/Default.aspx.designer.cs
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty.Members {
+
+
+ public partial class Default {
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Members/Web.config b/projecttemplates/WebFormsRelyingParty/Members/Web.config
new file mode 100644
index 0000000..aafc323
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Members/Web.config
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Note: As an alternative to hand editing this file you can use the
+ web admin tool to configure settings for your application. Use
+ the Website->Asp.Net Configuration option in Visual Studio.
+ A full list of settings and comments can be found in
+ machine.config.comments usually located in
+ \Windows\Microsoft.Net\Framework\v2.x\Config
+-->
+<configuration>
+ <appSettings/>
+ <connectionStrings/>
+ <system.web>
+ <authorization>
+ <deny users="?" />
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/projecttemplates/WebFormsRelyingParty/Model.Designer.cs b/projecttemplates/WebFormsRelyingParty/Model.Designer.cs
new file mode 100644
index 0000000..5c7b138
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Model.Designer.cs
@@ -0,0 +1,494 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()]
+[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserRole", "Role", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.Role), "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.User))]
+[assembly: global::System.Data.Objects.DataClasses.EdmRelationshipAttribute("DatabaseModel", "UserAuthenticationToken", "User", global::System.Data.Metadata.Edm.RelationshipMultiplicity.One, typeof(WebFormsRelyingParty.User), "AuthenticationToken", global::System.Data.Metadata.Edm.RelationshipMultiplicity.Many, typeof(WebFormsRelyingParty.AuthenticationToken))]
+
+// Original file name:
+// Generation date: 10/10/2009 9:43:51 AM
+namespace WebFormsRelyingParty
+{
+
+ /// <summary>
+ /// There are no comments for DatabaseEntities in the schema.
+ /// </summary>
+ public partial class DatabaseEntities : global::System.Data.Objects.ObjectContext
+ {
+ /// <summary>
+ /// Initializes a new DatabaseEntities object using the connection string found in the 'DatabaseEntities' section of the application configuration file.
+ /// </summary>
+ public DatabaseEntities() :
+ base("name=DatabaseEntities", "DatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ /// <summary>
+ /// Initialize a new DatabaseEntities object.
+ /// </summary>
+ public DatabaseEntities(string connectionString) :
+ base(connectionString, "DatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ /// <summary>
+ /// Initialize a new DatabaseEntities object.
+ /// </summary>
+ public DatabaseEntities(global::System.Data.EntityClient.EntityConnection connection) :
+ base(connection, "DatabaseEntities")
+ {
+ this.OnContextCreated();
+ }
+ partial void OnContextCreated();
+ /// <summary>
+ /// There are no comments for Role in the schema.
+ /// </summary>
+ public global::System.Data.Objects.ObjectQuery<Role> Role
+ {
+ get
+ {
+ if ((this._Role == null))
+ {
+ this._Role = base.CreateQuery<Role>("[Role]");
+ }
+ return this._Role;
+ }
+ }
+ private global::System.Data.Objects.ObjectQuery<Role> _Role;
+ /// <summary>
+ /// There are no comments for User in the schema.
+ /// </summary>
+ public global::System.Data.Objects.ObjectQuery<User> User
+ {
+ get
+ {
+ if ((this._User == null))
+ {
+ this._User = base.CreateQuery<User>("[User]");
+ }
+ return this._User;
+ }
+ }
+ private global::System.Data.Objects.ObjectQuery<User> _User;
+ /// <summary>
+ /// There are no comments for AuthenticationToken in the schema.
+ /// </summary>
+ public global::System.Data.Objects.ObjectQuery<AuthenticationToken> AuthenticationToken
+ {
+ get
+ {
+ if ((this._AuthenticationToken == null))
+ {
+ this._AuthenticationToken = base.CreateQuery<AuthenticationToken>("[AuthenticationToken]");
+ }
+ return this._AuthenticationToken;
+ }
+ }
+ private global::System.Data.Objects.ObjectQuery<AuthenticationToken> _AuthenticationToken;
+ /// <summary>
+ /// There are no comments for Role in the schema.
+ /// </summary>
+ public void AddToRole(Role role)
+ {
+ base.AddObject("Role", role);
+ }
+ /// <summary>
+ /// There are no comments for User in the schema.
+ /// </summary>
+ public void AddToUser(User user)
+ {
+ base.AddObject("User", user);
+ }
+ /// <summary>
+ /// There are no comments for AuthenticationToken in the schema.
+ /// </summary>
+ public void AddToAuthenticationToken(AuthenticationToken authenticationToken)
+ {
+ base.AddObject("AuthenticationToken", authenticationToken);
+ }
+ }
+ /// <summary>
+ /// There are no comments for DatabaseModel.AuthenticationToken in the schema.
+ /// </summary>
+ /// <KeyProperties>
+ /// Id
+ /// </KeyProperties>
+ [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DatabaseModel", Name="AuthenticationToken")]
+ [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
+ [global::System.Serializable()]
+ public partial class AuthenticationToken : global::System.Data.Objects.DataClasses.EntityObject
+ {
+ /// <summary>
+ /// Create a new AuthenticationToken object.
+ /// </summary>
+ /// <param name="id">Initial value of Id.</param>
+ /// <param name="claimedIdentifier">Initial value of ClaimedIdentifier.</param>
+ public static AuthenticationToken CreateAuthenticationToken(int id, string claimedIdentifier)
+ {
+ AuthenticationToken authenticationToken = new AuthenticationToken();
+ authenticationToken.Id = id;
+ authenticationToken.ClaimedIdentifier = claimedIdentifier;
+ return authenticationToken;
+ }
+ /// <summary>
+ /// There are no comments for Property Id in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public int Id
+ {
+ get
+ {
+ return this._Id;
+ }
+ set
+ {
+ this.OnIdChanging(value);
+ this.ReportPropertyChanging("Id");
+ this._Id = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("Id");
+ this.OnIdChanged();
+ }
+ }
+ private int _Id;
+ partial void OnIdChanging(int value);
+ partial void OnIdChanged();
+ /// <summary>
+ /// There are no comments for Property ClaimedIdentifier in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string ClaimedIdentifier
+ {
+ get
+ {
+ return this._ClaimedIdentifier;
+ }
+ set
+ {
+ this.OnClaimedIdentifierChanging(value);
+ this.ReportPropertyChanging("ClaimedIdentifier");
+ this._ClaimedIdentifier = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
+ this.ReportPropertyChanged("ClaimedIdentifier");
+ this.OnClaimedIdentifierChanged();
+ }
+ }
+ private string _ClaimedIdentifier;
+ partial void OnClaimedIdentifierChanging(string value);
+ partial void OnClaimedIdentifierChanged();
+ /// <summary>
+ /// There are no comments for Property FriendlyIdentifier in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string FriendlyIdentifier
+ {
+ get
+ {
+ return this._FriendlyIdentifier;
+ }
+ set
+ {
+ this.OnFriendlyIdentifierChanging(value);
+ this.ReportPropertyChanging("FriendlyIdentifier");
+ this._FriendlyIdentifier = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
+ this.ReportPropertyChanged("FriendlyIdentifier");
+ this.OnFriendlyIdentifierChanged();
+ }
+ }
+ private string _FriendlyIdentifier;
+ partial void OnFriendlyIdentifierChanging(string value);
+ partial void OnFriendlyIdentifierChanged();
+ /// <summary>
+ /// There are no comments for User in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DatabaseModel", "UserAuthenticationToken", "User")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public User User
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<User>("DatabaseModel.UserAuthenticationToken", "User").Value;
+ }
+ set
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<User>("DatabaseModel.UserAuthenticationToken", "User").Value = value;
+ }
+ }
+ /// <summary>
+ /// There are no comments for User in the schema.
+ /// </summary>
+ [global::System.ComponentModel.BrowsableAttribute(false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityReference<User> UserReference
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedReference<User>("DatabaseModel.UserAuthenticationToken", "User");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedReference<User>("DatabaseModel.UserAuthenticationToken", "User", value);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// There are no comments for DatabaseModel.Role in the schema.
+ /// </summary>
+ /// <KeyProperties>
+ /// Id
+ /// </KeyProperties>
+ [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DatabaseModel", Name="Role")]
+ [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
+ [global::System.Serializable()]
+ public partial class Role : global::System.Data.Objects.DataClasses.EntityObject
+ {
+ /// <summary>
+ /// Create a new Role object.
+ /// </summary>
+ /// <param name="id">Initial value of Id.</param>
+ /// <param name="name">Initial value of Name.</param>
+ public static Role CreateRole(int id, string name)
+ {
+ Role role = new Role();
+ role.Id = id;
+ role.Name = name;
+ return role;
+ }
+ /// <summary>
+ /// There are no comments for Property Id in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public int Id
+ {
+ get
+ {
+ return this._Id;
+ }
+ private set
+ {
+ this.OnIdChanging(value);
+ this.ReportPropertyChanging("Id");
+ this._Id = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("Id");
+ this.OnIdChanged();
+ }
+ }
+ private int _Id;
+ partial void OnIdChanging(int value);
+ partial void OnIdChanged();
+ /// <summary>
+ /// There are no comments for Property Name in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ this.OnNameChanging(value);
+ this.ReportPropertyChanging("Name");
+ this._Name = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
+ this.ReportPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ private string _Name;
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ /// <summary>
+ /// There are no comments for Users in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DatabaseModel", "UserRole", "User")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityCollection<User> Users
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<User>("DatabaseModel.UserRole", "User");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<User>("DatabaseModel.UserRole", "User", value);
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// There are no comments for DatabaseModel.User in the schema.
+ /// </summary>
+ /// <KeyProperties>
+ /// Id
+ /// </KeyProperties>
+ [global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="DatabaseModel", Name="User")]
+ [global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
+ [global::System.Serializable()]
+ public partial class User : global::System.Data.Objects.DataClasses.EntityObject
+ {
+ /// <summary>
+ /// Create a new User object.
+ /// </summary>
+ /// <param name="id">Initial value of Id.</param>
+ public static User CreateUser(int id)
+ {
+ User user = new User();
+ user.Id = id;
+ return user;
+ }
+ /// <summary>
+ /// There are no comments for Property Id in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public int Id
+ {
+ get
+ {
+ return this._Id;
+ }
+ private set
+ {
+ this.OnIdChanging(value);
+ this.ReportPropertyChanging("Id");
+ this._Id = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value);
+ this.ReportPropertyChanged("Id");
+ this.OnIdChanged();
+ }
+ }
+ private int _Id;
+ partial void OnIdChanging(int value);
+ partial void OnIdChanged();
+ /// <summary>
+ /// There are no comments for Property FirstName in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string FirstName
+ {
+ get
+ {
+ return this._FirstName;
+ }
+ set
+ {
+ this.OnFirstNameChanging(value);
+ this.ReportPropertyChanging("FirstName");
+ this._FirstName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
+ this.ReportPropertyChanged("FirstName");
+ this.OnFirstNameChanged();
+ }
+ }
+ private string _FirstName;
+ partial void OnFirstNameChanging(string value);
+ partial void OnFirstNameChanged();
+ /// <summary>
+ /// There are no comments for Property LastName in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string LastName
+ {
+ get
+ {
+ return this._LastName;
+ }
+ set
+ {
+ this.OnLastNameChanging(value);
+ this.ReportPropertyChanging("LastName");
+ this._LastName = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
+ this.ReportPropertyChanged("LastName");
+ this.OnLastNameChanged();
+ }
+ }
+ private string _LastName;
+ partial void OnLastNameChanging(string value);
+ partial void OnLastNameChanged();
+ /// <summary>
+ /// There are no comments for Property EmailAddress in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public string EmailAddress
+ {
+ get
+ {
+ return this._EmailAddress;
+ }
+ set
+ {
+ this.OnEmailAddressChanging(value);
+ this.ReportPropertyChanging("EmailAddress");
+ this._EmailAddress = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, true);
+ this.ReportPropertyChanged("EmailAddress");
+ this.OnEmailAddressChanged();
+ }
+ }
+ private string _EmailAddress;
+ partial void OnEmailAddressChanging(string value);
+ partial void OnEmailAddressChanged();
+ /// <summary>
+ /// There are no comments for Roles in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DatabaseModel", "UserRole", "Role")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityCollection<Role> Roles
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<Role>("DatabaseModel.UserRole", "Role");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<Role>("DatabaseModel.UserRole", "Role", value);
+ }
+ }
+ }
+ /// <summary>
+ /// There are no comments for AuthenticationTokens in the schema.
+ /// </summary>
+ [global::System.Data.Objects.DataClasses.EdmRelationshipNavigationPropertyAttribute("DatabaseModel", "UserAuthenticationToken", "AuthenticationToken")]
+ [global::System.Xml.Serialization.XmlIgnoreAttribute()]
+ [global::System.Xml.Serialization.SoapIgnoreAttribute()]
+ [global::System.Runtime.Serialization.DataMemberAttribute()]
+ public global::System.Data.Objects.DataClasses.EntityCollection<AuthenticationToken> AuthenticationTokens
+ {
+ get
+ {
+ return ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.GetRelatedCollection<AuthenticationToken>("DatabaseModel.UserAuthenticationToken", "AuthenticationToken");
+ }
+ set
+ {
+ if ((value != null))
+ {
+ ((global::System.Data.Objects.DataClasses.IEntityWithRelationships)(this)).RelationshipManager.InitializeRelatedCollection<AuthenticationToken>("DatabaseModel.UserAuthenticationToken", "AuthenticationToken", value);
+ }
+ }
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Model.cs b/projecttemplates/WebFormsRelyingParty/Model.cs
new file mode 100644
index 0000000..53ca10f
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Model.cs
@@ -0,0 +1,21 @@
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ public partial class AuthenticationToken {
+ public bool IsInfoCard {
+ get { return this.ClaimedIdentifier.StartsWith(UriPrefixForInfoCard); }
+ }
+
+ private static string UriPrefixForInfoCard {
+ get { return new Uri(HttpContext.Current.Request.Url, Global.ApplicationPath + "infocard/").AbsoluteUri; }
+ }
+
+ public static string SynthesizeClaimedIdentifierFromInfoCard(string uniqueId) {
+ string synthesizedClaimedId = UriPrefixForInfoCard + Uri.EscapeDataString(uniqueId);
+ return synthesizedClaimedId;
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Model.edmx b/projecttemplates/WebFormsRelyingParty/Model.edmx
new file mode 100644
index 0000000..c23b3df
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Model.edmx
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="utf-8"?>
+<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
+ <!-- EF Runtime content -->
+ <edmx:Runtime>
+ <!-- SSDL content -->
+ <edmx:StorageModels>
+ <Schema Namespace="DatabaseModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
+ <EntityContainer Name="DatabaseModelStoreContainer">
+ <EntitySet Name="AuthenticationToken" EntityType="DatabaseModel.Store.AuthenticationToken" store:Type="Tables" Schema="dbo" />
+ <EntitySet Name="Role" EntityType="DatabaseModel.Store.Role" store:Type="Tables" Schema="dbo" />
+ <EntitySet Name="User" EntityType="DatabaseModel.Store.User" store:Type="Tables" Schema="dbo" />
+ <EntitySet Name="UserRole" EntityType="DatabaseModel.Store.UserRole" store:Type="Tables" Schema="dbo" />
+ <AssociationSet Name="FK_AuthenticationToken_User" Association="DatabaseModel.Store.FK_AuthenticationToken_User">
+ <End Role="User" EntitySet="User" />
+ <End Role="AuthenticationToken" EntitySet="AuthenticationToken" />
+ </AssociationSet>
+ <AssociationSet Name="FK_UserRole_Role" Association="DatabaseModel.Store.FK_UserRole_Role">
+ <End Role="Role" EntitySet="Role" />
+ <End Role="UserRole" EntitySet="UserRole" />
+ </AssociationSet>
+ <AssociationSet Name="FK_UserRole_User" Association="DatabaseModel.Store.FK_UserRole_User">
+ <End Role="User" EntitySet="User" />
+ <End Role="UserRole" EntitySet="UserRole" />
+ </AssociationSet>
+ </EntityContainer>
+ <EntityType Name="AuthenticationToken">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+ <Property Name="UserId" Type="int" Nullable="false" />
+ <Property Name="OpenIdClaimedIdentifier" Type="nvarchar" Nullable="false" MaxLength="250" />
+ <Property Name="OpenIdFriendlyIdentifier" Type="nvarchar" MaxLength="250" />
+ </EntityType>
+ <EntityType Name="Role">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+ <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
+ </EntityType>
+ <EntityType Name="User">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
+ <Property Name="FirstName" Type="nvarchar" MaxLength="50" />
+ <Property Name="LastName" Type="nvarchar" MaxLength="50" />
+ <Property Name="EmailAddress" Type="nvarchar" MaxLength="100" />
+ </EntityType>
+ <EntityType Name="UserRole">
+ <Key>
+ <PropertyRef Name="UserId" />
+ <PropertyRef Name="RoleId" />
+ </Key>
+ <Property Name="UserId" Type="int" Nullable="false" />
+ <Property Name="RoleId" Type="int" Nullable="false" />
+ </EntityType>
+ <Association Name="FK_AuthenticationToken_User">
+ <End Role="User" Type="DatabaseModel.Store.User" Multiplicity="1">
+ <OnDelete Action="Cascade" />
+ </End>
+ <End Role="AuthenticationToken" Type="DatabaseModel.Store.AuthenticationToken" Multiplicity="*" />
+ <ReferentialConstraint>
+ <Principal Role="User">
+ <PropertyRef Name="Id" />
+ </Principal>
+ <Dependent Role="AuthenticationToken">
+ <PropertyRef Name="UserId" />
+ </Dependent>
+ </ReferentialConstraint>
+ </Association>
+ <Association Name="FK_UserRole_Role">
+ <End Role="Role" Type="DatabaseModel.Store.Role" Multiplicity="1">
+ <OnDelete Action="Cascade" />
+ </End>
+ <End Role="UserRole" Type="DatabaseModel.Store.UserRole" Multiplicity="*" />
+ <ReferentialConstraint>
+ <Principal Role="Role">
+ <PropertyRef Name="Id" />
+ </Principal>
+ <Dependent Role="UserRole">
+ <PropertyRef Name="RoleId" />
+ </Dependent>
+ </ReferentialConstraint>
+ </Association>
+ <Association Name="FK_UserRole_User">
+ <End Role="User" Type="DatabaseModel.Store.User" Multiplicity="1">
+ <OnDelete Action="Cascade" />
+ </End>
+ <End Role="UserRole" Type="DatabaseModel.Store.UserRole" Multiplicity="*" />
+ <ReferentialConstraint>
+ <Principal Role="User">
+ <PropertyRef Name="Id" />
+ </Principal>
+ <Dependent Role="UserRole">
+ <PropertyRef Name="UserId" />
+ </Dependent>
+ </ReferentialConstraint>
+ </Association>
+ </Schema></edmx:StorageModels>
+ <!-- CSDL content -->
+ <edmx:ConceptualModels>
+ <Schema Namespace="DatabaseModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
+ <EntityContainer Name="DatabaseEntities">
+ <EntitySet Name="Role" EntityType="DatabaseModel.Role" />
+ <EntitySet Name="User" EntityType="DatabaseModel.User" />
+ <AssociationSet Name="UserRole" Association="DatabaseModel.UserRole">
+ <End Role="Role" EntitySet="Role" />
+ <End Role="User" EntitySet="User" />
+ </AssociationSet>
+ <EntitySet Name="AuthenticationToken" EntityType="DatabaseModel.AuthenticationToken" />
+ <AssociationSet Name="UserAuthenticationToken" Association="DatabaseModel.UserAuthenticationToken">
+ <End Role="User" EntitySet="User" />
+ <End Role="AuthenticationToken" EntitySet="AuthenticationToken" /></AssociationSet>
+ </EntityContainer>
+ <EntityType Name="AuthenticationToken" Abstract="false">
+ <Key>
+ <PropertyRef Name="Id" /></Key>
+ <Property Name="Id" Type="Int32" Nullable="false" a:SetterAccess="Public" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
+ <NavigationProperty Name="User" Relationship="DatabaseModel.UserAuthenticationToken" FromRole="AuthenticationToken" ToRole="User" />
+ <Property Name="ClaimedIdentifier" Type="String" Nullable="false" />
+ <Property Name="FriendlyIdentifier" Type="String" Nullable="true" /></EntityType>
+ <EntityType Name="Role">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="Int32" Nullable="false" a:SetterAccess="Private" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
+ <Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
+ <NavigationProperty Name="Users" Relationship="DatabaseModel.UserRole" FromRole="Role" ToRole="User" />
+ </EntityType>
+ <EntityType Name="User">
+ <Key>
+ <PropertyRef Name="Id" />
+ </Key>
+ <Property Name="Id" Type="Int32" Nullable="false" a:SetterAccess="Private" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
+ <Property Name="FirstName" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
+ <Property Name="LastName" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
+ <Property Name="EmailAddress" Type="String" MaxLength="100" Unicode="true" FixedLength="false" />
+ <NavigationProperty Name="Roles" Relationship="DatabaseModel.UserRole" FromRole="User" ToRole="Role" />
+ <NavigationProperty Name="AuthenticationTokens" Relationship="DatabaseModel.UserAuthenticationToken" FromRole="User" ToRole="AuthenticationToken" /></EntityType>
+ <Association Name="UserRole">
+ <End Role="Role" Type="DatabaseModel.Role" Multiplicity="*" />
+ <End Role="User" Type="DatabaseModel.User" Multiplicity="*" />
+ </Association>
+ <Association Name="UserAuthenticationToken">
+ <End Type="DatabaseModel.User" Role="User" Multiplicity="1" />
+ <End Type="DatabaseModel.AuthenticationToken" Role="AuthenticationToken" Multiplicity="*" /></Association></Schema>
+ </edmx:ConceptualModels>
+ <!-- C-S mapping content -->
+ <edmx:Mappings>
+ <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
+ <EntityContainerMapping StorageEntityContainer="DatabaseModelStoreContainer" CdmEntityContainer="DatabaseEntities">
+ <EntitySetMapping Name="Role">
+ <EntityTypeMapping TypeName="IsTypeOf(DatabaseModel.Role)">
+ <MappingFragment StoreEntitySet="Role">
+ <ScalarProperty Name="Id" ColumnName="Id" />
+ <ScalarProperty Name="Name" ColumnName="Name" />
+ </MappingFragment>
+ </EntityTypeMapping>
+ </EntitySetMapping>
+ <EntitySetMapping Name="User">
+ <EntityTypeMapping TypeName="IsTypeOf(DatabaseModel.User)">
+ <MappingFragment StoreEntitySet="User">
+ <ScalarProperty Name="Id" ColumnName="Id" />
+ <ScalarProperty Name="FirstName" ColumnName="FirstName" />
+ <ScalarProperty Name="LastName" ColumnName="LastName" />
+ <ScalarProperty Name="EmailAddress" ColumnName="EmailAddress" />
+ </MappingFragment>
+ </EntityTypeMapping>
+ </EntitySetMapping>
+ <AssociationSetMapping Name="UserRole" TypeName="DatabaseModel.UserRole" StoreEntitySet="UserRole">
+ <EndProperty Name="Role">
+ <ScalarProperty Name="Id" ColumnName="RoleId" />
+ </EndProperty>
+ <EndProperty Name="User">
+ <ScalarProperty Name="Id" ColumnName="UserId" />
+ </EndProperty>
+ </AssociationSetMapping>
+ <EntitySetMapping Name="AuthenticationToken"><EntityTypeMapping TypeName="IsTypeOf(DatabaseModel.AuthenticationToken)">
+ <MappingFragment StoreEntitySet="AuthenticationToken">
+ <ScalarProperty Name="FriendlyIdentifier" ColumnName="OpenIdFriendlyIdentifier" />
+ <ScalarProperty Name="ClaimedIdentifier" ColumnName="OpenIdClaimedIdentifier" />
+ <ScalarProperty Name="Id" ColumnName="Id" />
+ </MappingFragment>
+ </EntityTypeMapping>
+ </EntitySetMapping>
+ <AssociationSetMapping Name="UserAuthenticationToken" TypeName="DatabaseModel.UserAuthenticationToken" StoreEntitySet="AuthenticationToken">
+ <EndProperty Name="AuthenticationToken">
+ <ScalarProperty Name="Id" ColumnName="Id" /></EndProperty>
+ <EndProperty Name="User">
+ <ScalarProperty Name="Id" ColumnName="UserId" /></EndProperty></AssociationSetMapping>
+ </EntityContainerMapping>
+ </Mapping>
+ </edmx:Mappings>
+ </edmx:Runtime>
+ <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
+ <edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
+ <edmx:Connection>
+ <DesignerInfoPropertySet>
+ <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
+ </DesignerInfoPropertySet>
+ </edmx:Connection>
+ <edmx:Options>
+ <DesignerInfoPropertySet>
+ <DesignerProperty Name="ValidateOnBuild" Value="true" />
+ </DesignerInfoPropertySet>
+ </edmx:Options>
+ <!-- Diagram content (shape and connector positions) -->
+ <edmx:Diagrams>
+ <Diagram Name="Model">
+ <EntityTypeShape EntityType="DatabaseModel.AuthenticationToken" Width="1.875" PointX="5.25" PointY="1.125" Height="1.4033821614583335" IsExpanded="true" />
+ <EntityTypeShape EntityType="DatabaseModel.Role" Width="1.5" PointX="0.75" PointY="1.25" Height="1.5956835937500002" IsExpanded="true" />
+ <EntityTypeShape EntityType="DatabaseModel.User" Width="1.75" PointX="2.875" PointY="0.875" Height="2.364889322916667" IsExpanded="true" />
+ <AssociationConnector Association="DatabaseModel.UserRole" ManuallyRouted="false">
+ <ConnectorPoint PointX="2.25" PointY="2.0478417968750002" />
+ <ConnectorPoint PointX="2.875" PointY="2.0478417968750002" /></AssociationConnector>
+ <InheritanceConnector EntityType="DatabaseModel.AuthenticationToken">
+ <ConnectorPoint PointX="6.5625" PointY="3.375" />
+ <ConnectorPoint PointX="6.5625" PointY="2.9129850260416665" /></InheritanceConnector>
+ <AssociationConnector Association="DatabaseModel.UserAuthenticationToken">
+ <ConnectorPoint PointX="4.625" PointY="1.8266910807291668" />
+ <ConnectorPoint PointX="5.25" PointY="1.8266910807291668" /></AssociationConnector></Diagram></edmx:Diagrams>
+ </edmx:Designer>
+</edmx:Edmx> \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate b/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate
new file mode 100644
index 0000000..b960809
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/MyTemplate.vstemplate
@@ -0,0 +1,132 @@
+<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
+ <TemplateData>
+ <Name>ASP.NET OpenID-InfoCard RP</Name>
+ <RequiredFrameworkVersion>3.5</RequiredFrameworkVersion>
+ <Description>An ASP.NET web forms web site that accepts OpenID and InfoCard logins</Description>
+ <ProjectType>CSharp</ProjectType>
+ <ProjectSubType>Web</ProjectSubType>
+ <NumberOfParentCategoriesToRollUp>2</NumberOfParentCategoriesToRollUp>
+ <SortOrder>1000</SortOrder>
+ <CreateNewFolder>true</CreateNewFolder>
+ <DefaultName>WebRPApplication</DefaultName>
+ <ProvideDefaultName>true</ProvideDefaultName>
+ <LocationField>Enabled</LocationField>
+ <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
+ <Icon>__TemplateIcon.ico</Icon>
+ </TemplateData>
+ <TemplateContent>
+ <Project TargetFileName="WebFormsRelyingParty.csproj" File="WebFormsRelyingParty.csproj" ReplaceParameters="true">
+ <Folder Name="Admin" TargetFolderName="Admin">
+ <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master">Admin.Master</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master.cs">Admin.Master.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Admin.Master.designer.cs">Admin.Master.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="CreateDatabase.sql">CreateDatabase.sql</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem>
+ </Folder>
+ <Folder Name="App_Data" TargetFolderName="App_Data" />
+ <Folder Name="bin" TargetFolderName="bin">
+ <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.dll">DotNetOpenAuth.dll</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.Contracts.dll">DotNetOpenAuth.Contracts.dll</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="DotNetOpenAuth.pdb">DotNetOpenAuth.pdb</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="DotNetOpenAuth.xml">DotNetOpenAuth.xml</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="log4net.dll">log4net.dll</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="log4net.xml">log4net.xml</ProjectItem>
+ </Folder>
+ <Folder Name="Code" TargetFolderName="Code">
+ <ProjectItem ReplaceParameters="true" TargetFileName="DataRoleProvider.cs">DataRoleProvider.cs</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Global.asax">Global.asax</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Global.asax.cs">Global.asax.cs</ProjectItem>
+ <Folder Name="images" TargetFolderName="images">
+ <ProjectItem ReplaceParameters="false" TargetFileName="google.gif">google.gif</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="infocard_23x16.png">infocard_23x16.png</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="openid_login.gif">openid_login.gif</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="yahoo.gif">yahoo.gif</ProjectItem>
+ <ProjectItem>myopenid.png</ProjectItem>
+ <ProjectItem>openid.gif</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="yahoo_login.png">yahoo_login.png</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx">Login.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx.cs">Login.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Login.aspx.designer.cs">Login.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx">LoginFrame.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx.cs">LoginFrame.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="LoginFrame.aspx.designer.cs">LoginFrame.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx">Logout.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx.cs">Logout.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Logout.aspx.designer.cs">Logout.aspx.designer.cs</ProjectItem>
+ <Folder Name="Members" TargetFolderName="Members">
+ <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx">AccountInfo.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx.cs">AccountInfo.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="AccountInfo.aspx.designer.cs">AccountInfo.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx">Default.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.cs">Default.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Default.aspx.designer.cs">Default.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Model.cs">Model.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="false" TargetFileName="Model.edmx">Model.edmx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Model.Designer.cs">Model.Designer.cs</ProjectItem>
+ <Folder Name="Properties" TargetFolderName="Properties">
+ <ProjectItem ReplaceParameters="true" TargetFileName="AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
+ </Folder>
+ <Folder Name="scripts" TargetFolderName="scripts">
+ <ProjectItem>jquery-1.3.1.js</ProjectItem>
+ <ProjectItem>jquery-ui-personalized-1.6rc6.js</ProjectItem>
+ <ProjectItem>jquery-ui-personalized-1.6rc6.min.js</ProjectItem>
+ <ProjectItem>jquery.cookie.js</ProjectItem>
+ <ProjectItem>LoginLink.js</ProjectItem>
+ </Folder>
+ <Folder Name="styles">
+ <ProjectItem>loginpopup.css</ProjectItem>
+ <ProjectItem>Standard.css</ProjectItem>
+ </Folder>
+ <Folder Name="theme">
+ <Folder Name="images">
+ <ProjectItem>ui-bg_flat_55_999999_40x100.png</ProjectItem>
+ <ProjectItem>ui-bg_flat_75_aaaaaa_40x100.png</ProjectItem>
+ <ProjectItem>ui-bg_glass_45_0078ae_1x400.png</ProjectItem>
+ <ProjectItem>ui-bg_glass_55_f8da4e_1x400.png</ProjectItem>
+ <ProjectItem>ui-bg_glass_75_79c9ec_1x400.png</ProjectItem>
+ <ProjectItem>ui-bg_gloss-wave_45_e14f1c_500x100.png</ProjectItem>
+ <ProjectItem>ui-bg_gloss-wave_50_6eac2c_500x100.png</ProjectItem>
+ <ProjectItem>ui-bg_gloss-wave_75_2191c0_500x100.png</ProjectItem>
+ <ProjectItem>ui-bg_inset-hard_100_fcfdfd_1x100.png</ProjectItem>
+ <ProjectItem>ui-icons_0078ae_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_056b93_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_d8e7f3_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_e0fdff_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_f5e175_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_f7a50d_256x240.png</ProjectItem>
+ <ProjectItem>ui-icons_fcd113_256x240.png</ProjectItem>
+ </Folder>
+ <ProjectItem>ui.accordion.css</ProjectItem>
+ <ProjectItem>ui.all.css</ProjectItem>
+ <ProjectItem>ui.base.css</ProjectItem>
+ <ProjectItem>ui.core.css</ProjectItem>
+ <ProjectItem>ui.datepicker.css</ProjectItem>
+ <ProjectItem>ui.dialog.css</ProjectItem>
+ <ProjectItem>ui.progressbar.css</ProjectItem>
+ <ProjectItem>ui.resizable.css</ProjectItem>
+ <ProjectItem>ui.slider.css</ProjectItem>
+ <ProjectItem>ui.tabs.css</ProjectItem>
+ <ProjectItem>ui.theme.css</ProjectItem>
+ </Folder>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx">Setup.aspx</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx.cs">Setup.aspx.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Setup.aspx.designer.cs">Setup.aspx.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master">Site.Master</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master.cs">Site.Master.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Site.Master.designer.cs">Site.Master.designer.cs</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="GettingStarted.htm" OpenInWebBrowser="true">GettingStarted.htm</ProjectItem>
+ <ProjectItem ReplaceParameters="true" TargetFileName="Web.config">Web.config</ProjectItem>
+ <ProjectItem>xrds.aspx</ProjectItem>
+ </Project>
+ </TemplateContent>
+</VSTemplate> \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/Properties/AssemblyInfo.cs b/projecttemplates/WebFormsRelyingParty/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..78ec7de
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Properties/AssemblyInfo.cs
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------
+// <copyright file="AssemblyInfo.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WebFormsRelyingParty")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WebFormsRelyingParty")]
+[assembly: AssemblyCopyright("Copyright © 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/projecttemplates/WebFormsRelyingParty/Setup.aspx b/projecttemplates/WebFormsRelyingParty/Setup.aspx
new file mode 100644
index 0000000..128bb6d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Setup.aspx
@@ -0,0 +1,43 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Setup.aspx.cs" Inherits="WebFormsRelyingParty.Setup" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>OpenID RP one-time setup</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h2>
+ First steps:
+ </h2>
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="View1" runat="server">
+ <p>
+ Before you can use this site, you must create your SQL database that will store
+ your user accounts and add an admin account to that database.
+ Just tell me what OpenID you will use to administer the site.
+ </p>
+ <rp:OpenIdLogin runat="server" ButtonText="Create database" ID="openidLogin"
+ OnLoggingIn="openidLogin_LoggingIn"
+ TabIndex="1" LabelText="Administrator's OpenID:"
+ ButtonToolTip="Clicking this button will create the database and initialize the OpenID you specify as an admin of this web site."
+ RegisterText="get an OpenID" />
+ <asp:Label ID="noOPIdentifierLabel" Visible="false" EnableViewState="false" ForeColor="Red" Font-Bold="true" runat="server" Text="Sorry. To help your admin account remain functional when you push this web site to production, directed identity is disabled on this page. Please use your personal claimed identifier." />
+ </asp:View>
+ <asp:View ID="View2" runat="server">
+ <p>
+ Your database has been successfully initialized.
+ </p>
+ <p>
+ <b>Remember to delete this Setup.aspx page.</b>
+ </p>
+ <p>
+ Visit the <a href="Default.aspx">home page</a>.
+ </p>
+ </asp:View>
+ </asp:MultiView>
+ </form>
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs b/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs
new file mode 100644
index 0000000..4f73c5f
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Setup.aspx.cs
@@ -0,0 +1,64 @@
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using Microsoft.SqlServer.Management.Common;
+ using Microsoft.SqlServer.Management.Smo;
+
+ public partial class Setup : System.Web.UI.Page {
+ private bool databaseCreated;
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!Page.IsPostBack) {
+ this.openidLogin.Focus();
+ }
+ }
+
+ protected void openidLogin_LoggingIn(object sender, OpenIdEventArgs e) {
+ // We don't actually want to log in... we just want the claimed identifier.
+ e.Cancel = true;
+ if (e.IsDirectedIdentity) {
+ this.noOPIdentifierLabel.Visible = true;
+ } else if (!this.databaseCreated) {
+ this.CreateDatabase(e.ClaimedIdentifier, this.openidLogin.Text);
+ this.MultiView1.ActiveViewIndex = 1;
+
+ // indicate we have already created the database so that if the
+ // identifier the user gave has multiple service endpoints,
+ // we won't try to recreate the database as the next one is considered.
+ this.databaseCreated = true;
+ }
+ }
+
+ private void CreateDatabase(Identifier claimedId, string friendlyId) {
+ const string SqlFormat = @"
+CREATE DATABASE [{0}] ON (NAME='{0}', FILENAME='{0}')
+GO
+USE ""{0}""
+GO
+{1}
+EXEC [dbo].[AddUser] 'admin', 'admin', '{2}', '{3}'
+GO
+";
+ string databasePath = HttpContext.Current.Server.MapPath("~/App_Data/Database.mdf");
+ string schemaSql = File.ReadAllText(HttpContext.Current.Server.MapPath("~/Admin/CreateDatabase.sql"));
+ string sql = string.Format(CultureInfo.InvariantCulture, SqlFormat, databasePath, schemaSql, claimedId, "Admin");
+
+ var serverConnection = new ServerConnection(".\\sqlexpress");
+ try {
+ serverConnection.ExecuteNonQuery(sql);
+ var server = new Server(serverConnection);
+ server.DetachDatabase(databasePath, true);
+ } finally {
+ serverConnection.Disconnect();
+ }
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Setup.aspx.designer.cs b/projecttemplates/WebFormsRelyingParty/Setup.aspx.designer.cs
new file mode 100644
index 0000000..a51ceed
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Setup.aspx.designer.cs
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class Setup {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// openidLogin control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdLogin openidLogin;
+
+ /// <summary>
+ /// noOPIdentifierLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label noOPIdentifierLabel;
+
+ /// <summary>
+ /// View2 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View2;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Site.Master b/projecttemplates/WebFormsRelyingParty/Site.Master
new file mode 100644
index 0000000..23241b7
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Site.Master
@@ -0,0 +1,49 @@
+<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebFormsRelyingParty.Site" %>
+
+<%@ Import Namespace="WebFormsRelyingParty" %>
+<%@ Import Namespace="System.Linq" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title><%=Page.Title %></title>
+ <link type="text/css" href="theme/ui.all.css" rel="Stylesheet" />
+ <link href="styles/Standard.css" rel="stylesheet" type="text/css" />
+ <asp:ContentPlaceHolder ID="head" runat="server" />
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div style="float: right">
+ <asp:LoginView runat="server">
+ <LoggedInTemplate>
+ <%= Global.DataContext.AuthenticationToken.First(token => token.ClaimedIdentifier == Page.User.Identity.Name).FriendlyIdentifier %>
+ | <asp:HyperLink runat="server" NavigateUrl="~/" Text="Home" /> | <asp:HyperLink
+ runat="server" NavigateUrl="~/Members/AccountInfo.aspx" Text="Account" /> |
+ <asp:LoginStatus ID="LoginStatus1" runat="server" />
+ </LoggedInTemplate>
+ <AnonymousTemplate>
+ <% if (Page.Request.Path != FormsAuthentication.LoginUrl) {%>
+ <a href="#" class="loginPopupLink">Login</a>
+ <% } %>
+ </AnonymousTemplate>
+ </asp:LoginView>
+ </div>
+ <div>
+ <h1><asp:HyperLink runat="server" NavigateUrl="~/" Text="Adventure Works" /></h1>
+ <asp:ContentPlaceHolder ID="Body" runat="server"/>
+ </div>
+ </form>
+
+<% if (Request.Url.IsLoopback) { %>
+ <script type="text/javascript" src="scripts/jquery-1.3.1.js"></script>
+ <script type="text/javascript" src="scripts/jquery-ui-personalized-1.6rc6.js"></script>
+<% } else { %>
+ <script type="text/javascript" language="javascript" src="http://www.google.com/jsapi"></script>
+ <script type="text/javascript" language="javascript">
+ google.load("jquery", "1.3.2");
+ google.load("jqueryui", "1.7.2");
+ </script>
+<% } %>
+
+ <script type="text/javascript" language="javascript" src="scripts/LoginLink.js"></script>
+</body>
+</html>
diff --git a/projecttemplates/WebFormsRelyingParty/Site.Master.cs b/projecttemplates/WebFormsRelyingParty/Site.Master.cs
new file mode 100644
index 0000000..b6a4f1d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Site.Master.cs
@@ -0,0 +1,19 @@
+//-----------------------------------------------------------------------
+// <copyright file="Site.Master.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ public partial class Site : System.Web.UI.MasterPage {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Site.Master.designer.cs b/projecttemplates/WebFormsRelyingParty/Site.Master.designer.cs
new file mode 100644
index 0000000..f6d2225
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Site.Master.designer.cs
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace WebFormsRelyingParty {
+
+
+ public partial class Site {
+
+ /// <summary>
+ /// head control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ContentPlaceHolder head;
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// Body control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ContentPlaceHolder Body;
+ }
+}
diff --git a/projecttemplates/WebFormsRelyingParty/Web.config b/projecttemplates/WebFormsRelyingParty/Web.config
new file mode 100644
index 0000000..3c7aaae
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/Web.config
@@ -0,0 +1,179 @@
+<?xml version="1.0"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true" />
+ <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
+ <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
+ <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
+ <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
+ <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
+ </sectionGroup>
+ </sectionGroup>
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <servicePointManager checkCertificateRevocationList="true" />
+ </settings>
+ </system.net>
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <openid>
+ <relyingParty>
+ <behaviors>
+ <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+ with OPs that use Attribute Exchange (in various formats). -->
+ <add type="DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth" />
+ </behaviors>
+ </relyingParty>
+ </openid>
+ </dotNetOpenAuth>
+ <!-- log4net is a 3rd party (free) logger library that dotnetopenid will use if present but does not require. -->
+ <log4net>
+ <!--<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
+ <file value="RelyingParty.log" />
+ <appendToFile value="true" />
+ <rollingStyle value="Size" />
+ <maxSizeRollBackups value="10" />
+ <maximumFileSize value="100KB" />
+ <staticLogFileName value="true" />
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
+ </layout>
+ </appender>-->
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="WARN" />
+ <appender-ref ref="RollingFileAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="WARN" />
+ </logger>
+ </log4net>
+ <appSettings />
+ <connectionStrings>
+ <add name="DatabaseEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
+ </connectionStrings>
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true">
+ <assemblies>
+ <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ <add assembly="System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <add assembly="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ </assemblies>
+ </compilation>
+ <!--
+ The <authentication> section enables configuration
+ of the security authentication mode used by
+ ASP.NET to identify an incoming user.
+ -->
+ <authentication mode="Forms">
+ <forms loginUrl="~/login.aspx" />
+ </authentication>
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+ -->
+ <pages>
+ <controls>
+ <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </controls>
+ </pages>
+ <httpHandlers>
+ <remove verb="*" path="*.asmx" />
+ <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
+ </httpHandlers>
+ <httpModules>
+ <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </httpModules>
+ <roleManager enabled="true" defaultProvider="Database">
+ <providers>
+ <add name="Database" type="WebFormsRelyingParty.Code.DataRoleProvider" />
+ </providers>
+ </roleManager>
+ </system.web>
+ <system.codedom>
+ <compilers>
+ <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <providerOption name="CompilerVersion" value="v3.5" />
+ <providerOption name="WarnAsError" value="false" />
+ </compiler>
+ </compilers>
+ </system.codedom>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false" />
+ <modules>
+ <remove name="ScriptModule" />
+ <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </modules>
+ <handlers>
+ <remove name="WebServiceHandlerFactory-Integrated" />
+ <remove name="ScriptHandlerFactory" />
+ <remove name="ScriptHandlerFactoryAppServices" />
+ <remove name="ScriptResource" />
+ <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <location path="default.aspx">
+ <system.web>
+ <authorization>
+ <allow users="*" />
+ </authorization>
+ </system.web>
+ </location>
+</configuration> \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj
new file mode 100644
index 0000000..824195a
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/WebFormsRelyingParty.csproj
@@ -0,0 +1,281 @@
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A78F8FC6-7B03-4230-BE41-761E400D6810}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WebFormsRelyingParty</RootNamespace>
+ <AssemblyName>WebFormsRelyingParty</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\lib\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.SqlServer.ConnectionInfo" />
+ <Reference Include="Microsoft.SqlServer.Smo" />
+ <Reference Include="Microsoft.SqlServer.Management.Sdk.Sfc" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.Entity">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Security" />
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\Windows\assembly\GAC_MSIL\System.Web.Entity\3.5.0.0__b77a5c561934e089\System.Web.Entity.dll</HintPath>
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Extensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Members\AccountInfo.aspx" />
+ <Content Include="Default.aspx" />
+ <Content Include="Login.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="LoginFrame.aspx.cs">
+ <DependentUpon>LoginFrame.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="LoginFrame.aspx.designer.cs">
+ <DependentUpon>LoginFrame.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Members\AccountInfo.aspx.cs">
+ <DependentUpon>AccountInfo.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\AccountInfo.aspx.designer.cs">
+ <DependentUpon>AccountInfo.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Admin\Admin.Master.cs">
+ <DependentUpon>Admin.Master</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Admin\Admin.Master.designer.cs">
+ <DependentUpon>Admin.Master</DependentUpon>
+ </Compile>
+ <Compile Include="Admin\Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Admin\Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Default.aspx.cs">
+ <SubType>ASPXCodeBehind</SubType>
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Login.aspx.cs">
+ <DependentUpon>Login.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Login.aspx.designer.cs">
+ <DependentUpon>Login.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Logout.aspx.cs">
+ <DependentUpon>Logout.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Logout.aspx.designer.cs">
+ <DependentUpon>Logout.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Members\Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Model.cs" />
+ <Compile Include="Model.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Model.edmx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EntityDeploy Include="Model.edmx">
+ <Generator>EntityModelCodeGenerator</Generator>
+ <LastGenOutput>Model.Designer.cs</LastGenOutput>
+ </EntityDeploy>
+ <Compile Include="Code\DataRoleProvider.cs">
+ </Compile>
+ <Compile Include="Setup.aspx.cs">
+ <DependentUpon>Setup.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Setup.aspx.designer.cs">
+ <DependentUpon>Setup.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Site.Master.cs">
+ <DependentUpon>Site.Master</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Site.Master.designer.cs">
+ <DependentUpon>Site.Master</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Admin\Default.aspx" />
+ <Content Include="Admin\Web.config" />
+ <Content Include="Global.asax" />
+ <Content Include="Site.Master" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Admin\Admin.Master" />
+ <Content Include="images\google.gif" />
+ <Content Include="images\yahoo.gif" />
+ <Content Include="styles\Standard.css" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="bin\DotNetOpenAuth.dll" />
+ <Content Include="bin\DotNetOpenAuth.pdb" />
+ <Content Include="bin\DotNetOpenAuth.xml" />
+ <Content Include="bin\log4net.dll" />
+ <Content Include="bin\log4net.xml" />
+ <Content Include="GettingStarted.htm" />
+ <Content Include="images\infocard_23x16.png" />
+ <Content Include="images\myopenid.png" />
+ <Content Include="images\openid.gif" />
+ <Content Include="images\openid_login.gif" />
+ <Content Include="images\yahoo_login.png" />
+ <Content Include="LoginFrame.aspx" />
+ <Content Include="Logout.aspx" />
+ <Content Include="Members\Default.aspx" />
+ <Content Include="Members\Web.config" />
+ <Content Include="scripts\jquery-1.3.1.js" />
+ <Content Include="scripts\jquery-ui-personalized-1.6rc6.js" />
+ <Content Include="scripts\jquery-ui-personalized-1.6rc6.min.js" />
+ <Content Include="scripts\jquery.cookie.js" />
+ <Content Include="scripts\LoginLink.js" />
+ <Content Include="Setup.aspx" />
+ <Content Include="styles\loginpopup.css" />
+ <Content Include="theme\images\ui-bg_flat_55_999999_40x100.png" />
+ <Content Include="theme\images\ui-bg_flat_75_aaaaaa_40x100.png" />
+ <Content Include="theme\images\ui-bg_glass_45_0078ae_1x400.png" />
+ <Content Include="theme\images\ui-bg_glass_55_f8da4e_1x400.png" />
+ <Content Include="theme\images\ui-bg_glass_75_79c9ec_1x400.png" />
+ <Content Include="theme\images\ui-bg_gloss-wave_45_e14f1c_500x100.png" />
+ <Content Include="theme\images\ui-bg_gloss-wave_50_6eac2c_500x100.png" />
+ <Content Include="theme\images\ui-bg_gloss-wave_75_2191c0_500x100.png" />
+ <Content Include="theme\images\ui-bg_inset-hard_100_fcfdfd_1x100.png" />
+ <Content Include="theme\images\ui-icons_0078ae_256x240.png" />
+ <Content Include="theme\images\ui-icons_056b93_256x240.png" />
+ <Content Include="theme\images\ui-icons_d8e7f3_256x240.png" />
+ <Content Include="theme\images\ui-icons_e0fdff_256x240.png" />
+ <Content Include="theme\images\ui-icons_f5e175_256x240.png" />
+ <Content Include="theme\images\ui-icons_f7a50d_256x240.png" />
+ <Content Include="theme\images\ui-icons_fcd113_256x240.png" />
+ <Content Include="theme\ui.accordion.css" />
+ <Content Include="theme\ui.all.css" />
+ <Content Include="theme\ui.base.css" />
+ <Content Include="theme\ui.core.css" />
+ <Content Include="theme\ui.datepicker.css" />
+ <Content Include="theme\ui.dialog.css" />
+ <Content Include="theme\ui.progressbar.css" />
+ <Content Include="theme\ui.resizable.css" />
+ <Content Include="theme\ui.slider.css" />
+ <Content Include="theme\ui.tabs.css" />
+ <Content Include="theme\ui.theme.css" />
+ <Content Include="xrds.aspx" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Admin\CreateDatabase.sql" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth\DotNetOpenAuth.csproj">
+ <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project>
+ <Name>DotNetOpenAuth</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>54189</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/images/google.gif b/projecttemplates/WebFormsRelyingParty/images/google.gif
new file mode 100644
index 0000000..1b6cd07
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/google.gif
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/infocard_23x16.png b/projecttemplates/WebFormsRelyingParty/images/infocard_23x16.png
new file mode 100644
index 0000000..9dbea9f
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/infocard_23x16.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/myopenid.png b/projecttemplates/WebFormsRelyingParty/images/myopenid.png
new file mode 100644
index 0000000..204caae
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/myopenid.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/openid.gif b/projecttemplates/WebFormsRelyingParty/images/openid.gif
new file mode 100644
index 0000000..c718b0e
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/openid.gif
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/openid_login.gif b/projecttemplates/WebFormsRelyingParty/images/openid_login.gif
new file mode 100644
index 0000000..cde836c
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/openid_login.gif
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/verisign.gif b/projecttemplates/WebFormsRelyingParty/images/verisign.gif
new file mode 100644
index 0000000..faa6aaa
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/verisign.gif
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/yahoo.gif b/projecttemplates/WebFormsRelyingParty/images/yahoo.gif
new file mode 100644
index 0000000..42adbfa
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/yahoo.gif
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/images/yahoo_login.png b/projecttemplates/WebFormsRelyingParty/images/yahoo_login.png
new file mode 100644
index 0000000..476fa64
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/images/yahoo_login.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/scripts/LoginLink.js b/projecttemplates/WebFormsRelyingParty/scripts/LoginLink.js
new file mode 100644
index 0000000..cf60ff3
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/scripts/LoginLink.js
@@ -0,0 +1,53 @@
+$(function() {
+ var loginContent = 'LoginFrame.aspx';
+ var popupWindowName = 'openidlogin';
+ var popupWidth = 355;
+ var popupHeight = 273; // use 205 for 1 row of OP buttons
+
+ {
+ var div = window.document.createElement('div');
+ div.style.padding = 0;
+ div.id = 'loginDialog';
+
+ var iframe = window.document.createElement('iframe');
+ iframe.src = loginContent;
+ iframe.frameBorder = 0;
+ iframe.width = popupWidth;
+ iframe.height = popupHeight;
+ div.appendChild(iframe);
+
+ window.document.body.appendChild(div);
+ }
+
+ $(document).ready(function() {
+ $("#loginDialog").dialog({
+ bgiframe: true,
+ modal: true,
+ title: 'Login or register',
+ resizable: false,
+ hide: 'clip',
+ width: popupWidth,
+ height: popupHeight + 50,
+ buttons: {},
+ closeOnEscape: true,
+ autoOpen: false,
+ focus: function(event, ui) {
+ // var box = $('#openid_identifier')[0];
+ // if (box.style.display != 'none') {
+ // box.focus();
+ // }
+ }
+ });
+
+ $('.loginPopupLink').click(function() {
+ $("#loginDialog").dialog('open');
+ });
+ $('.loginWindowLink').click(function() {
+ if (window.showModalDialog) {
+ window.showModalDialog(loginContent, popupWindowName, 'status:0;resizable:1;scroll:1;center:1;dialogHeight:' + popupHeight + 'px;dialogWidth:' + popupWidth + 'px');
+ } else {
+ window.open(loginContent, popupWindowName, 'modal=yes,status=0,location=1,toolbar=0,menubar=0,resizable=0,scrollbars=0,height=' + popupHeight + 'px,width=' + popupWidth + 'px');
+ }
+ });
+ });
+});
diff --git a/projecttemplates/WebFormsRelyingParty/scripts/jquery-1.3.1.js b/projecttemplates/WebFormsRelyingParty/scripts/jquery-1.3.1.js
new file mode 100644
index 0000000..3a4badd
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/scripts/jquery-1.3.1.js
@@ -0,0 +1,4241 @@
+/*!
+ * jQuery JavaScript Library v1.3.1
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-01-21 20:42:16 -0500 (Wed, 21 Jan 2009)
+ * Revision: 6158
+ */
+(function(){
+
+var
+ // Will speed up references to window, and allows munging its name.
+ window = this,
+ // Will speed up references to undefined, and allows munging its name.
+ undefined,
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ jQuery = window.jQuery = window.$ = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ this.context = selector;
+ return this;
+ }
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem && elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ var ret = jQuery( elem || [] );
+ ret.context = document;
+ ret.selector = selector;
+ return ret;
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return jQuery( document ).ready( selector );
+
+ // Make sure that old selector state is passed along
+ if ( selector.selector && selector.context ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return this.setArray(jQuery.makeArray(selector));
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.3.1",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num === undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" )
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ else if ( name )
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem && elem.jquery ? elem[0] : elem
+ , this );
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( typeof name === "string" )
+ if ( value === undefined )
+ return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text !== "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).clone();
+
+ if ( this[0].parentNode )
+ wrap.insertBefore( this[0] );
+
+ wrap.map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ // For internal use only.
+ // Behaves like an Array's .push method, not like a jQuery method.
+ push: [].push,
+
+ find: function( selector ) {
+ if ( this.length === 1 && !/,/.test(selector) ) {
+ var ret = this.pushStack( [], "find", selector );
+ ret.length = 0;
+ jQuery.find( selector, this[0], ret );
+ return ret;
+ } else {
+ var elems = jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ });
+
+ return this.pushStack( /[^+>] [^+>]/.test( selector ) ?
+ jQuery.unique( elems ) :
+ elems, "find", selector );
+ }
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var clone = this.cloneNode(true),
+ container = document.createElement("div");
+ container.appendChild(clone);
+ return jQuery.clean([container.innerHTML])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] !== undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true )
+ this.find("*").andSelf().each(function(i){
+ if (this.nodeType == 3)
+ return;
+ var events = jQuery.data( this, "events" );
+
+ for ( var type in events )
+ for ( var handler in events[ type ] )
+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
+ return elem.nodeType === 1;
+ }) ), "filter", selector );
+ },
+
+ closest: function( selector ) {
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null;
+
+ return this.map(function(){
+ var cur = this;
+ while ( cur && cur.ownerDocument ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) )
+ return cur;
+ cur = cur.parentNode;
+ }
+ });
+ },
+
+ not: function( selector ) {
+ if ( typeof selector === "string" )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return this.pushStack( jQuery.unique( jQuery.merge(
+ this.get(),
+ typeof selector === "string" ?
+ jQuery( selector ) :
+ jQuery.makeArray( selector )
+ )));
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+ },
+
+ hasClass: function( selector ) {
+ return !!selector && this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if( jQuery.nodeName( elem, 'option' ) )
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ if ( typeof value === "number" )
+ value += '';
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(value);
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value === undefined ?
+ (this[0] ?
+ this[0].innerHTML :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, +i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ),
+ "slice", Array.prototype.slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function( args, table, callback ) {
+ if ( this[0] ) {
+ var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
+ scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
+ first = fragment.firstChild,
+ extra = this.length > 1 ? fragment.cloneNode(true) : fragment;
+
+ if ( first )
+ for ( var i = 0, l = this.length; i < l; i++ )
+ callback.call( root(this[i], first), i > 0 ? extra.cloneNode(true) : fragment );
+
+ if ( scripts )
+ jQuery.each( scripts, evalScript );
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+function now(){
+ return +new Date;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ var src = target[ name ], copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType )
+ target[ name ] = jQuery.extend( deep,
+ // Never move original objects, clone them
+ src || ( copy.length != null ? [ ] : { } )
+ , copy );
+
+ // Don't bring in undefined values
+ else if ( copy !== undefined )
+ target[ name ] = copy;
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ // cache defaultView
+ defaultView = document.defaultView || {},
+ toString = Object.prototype.toString;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+
+ if ( data ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.support.scriptEval )
+ script.appendChild( document.createTextNode( data ) );
+ else
+ script.text = data;
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0, length = object.length;
+
+ if ( args ) {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( ; i < length; )
+ if ( callback.apply( object[ i++ ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use hasClass("class")
+ has: function( elem, className ) {
+ return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+ var padding = 0, border = 0;
+ jQuery.each( which, function() {
+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ val -= Math.round(padding + border);
+ }
+
+ if ( jQuery(elem).is(":visible") )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, val);
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style;
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && !jQuery.support.opacity ) {
+ ret = jQuery.attr( style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && style && style[ name ] )
+ ret = style[ name ];
+
+ else if ( defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle )
+ ret = computedStyle.getPropertyValue( name );
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = ret || 0;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context, fragment ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" )
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
+ var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
+ if ( match )
+ return [ context.createElement( match[1] ) ];
+ }
+
+ var ret = [], scripts = [], div = context.createElement("div");
+
+ jQuery.each(elems, function(i, elem){
+ if ( typeof elem === "number" )
+ elem += '';
+
+ if ( !elem )
+ return;
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = jQuery.trim( elem ).toLowerCase();
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ !jQuery.support.htmlSerialize &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType )
+ ret.push( elem );
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 )
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ fragment.appendChild( ret[i] );
+ }
+ }
+
+ return scripts;
+ }
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var notxml = !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ // IE elem.getAttribute passes even for style
+ if ( elem.tagName ) {
+
+ // These attributes require special treatment
+ var special = /href|src|style/.test( name );
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && elem.parentNode )
+ elem.parentNode.selectedIndex;
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ){
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name == "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+ return attributeNode && attributeNode.specified
+ ? attributeNode.value
+ : elem.nodeName.match(/(button|input|object|select|textarea)/i)
+ ? 0
+ : elem.nodeName.match(/^(a|area)$/i) && elem.href
+ ? 0
+ : undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ if ( set )
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special
+ // Some attributes require a special call on IE
+ ? elem.getAttribute( name, 2 )
+ : elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name == "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( set )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ if( array != null ){
+ var i = array.length;
+ // The window, strings (and functions) also have 'length'
+ if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
+ ret[0] = array;
+ else
+ while( i )
+ ret[--i] = array[i];
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ // Use === because on IE, window == document
+ if ( array[ i ] === elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+ var i = 0, elem, pos = first.length;
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( !jQuery.support.getAll ) {
+ while ( (elem = second[ i++ ]) != null )
+ if ( elem.nodeType != 8 )
+ first[ pos++ ] = elem;
+
+ } else
+ while ( (elem = second[ i++ ]) != null )
+ first[ pos++ ] = elem;
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv != !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value != null )
+ ret[ ret.length ] = value;
+ }
+
+ return ret.concat.apply( [], ret );
+ }
+});
+
+// Use of jQuery.browser is deprecated.
+// It's included for backwards compatibility and plugins,
+// although they should work to migrate away.
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ), name, selector );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function() {
+ var args = arguments;
+
+ return this.each(function(){
+ for ( var i = 0, length = args.length; i < length; i++ )
+ jQuery( args[ i ] )[ original ]( this );
+ });
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames, state ) {
+ if( typeof state !== "boolean" )
+ state = !jQuery.className.has( this, classNames );
+ jQuery.className[ state ? "add" : "remove" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add([this]).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery( ">*", this ).remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+// Helper function used by the dimensions and offset modules
+function num(elem, prop) {
+ return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
+}
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+ queue: function( elem, type, data ) {
+ if ( elem ){
+
+ type = (type || "fx") + "queue";
+
+ var q = jQuery.data( elem, type );
+
+ if ( !q || jQuery.isArray(data) )
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+ else if( data )
+ q.push( data );
+
+ }
+ return q;
+ },
+
+ dequeue: function( elem, type ){
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift();
+
+ if( !type || type === "fx" )
+ fn = queue[0];
+
+ if( fn !== undefined )
+ fn.call(elem);
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+ queue: function(type, data){
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined )
+ return jQuery.queue( this[0], type );
+
+ return this.each(function(){
+ var queue = jQuery.queue( this, type, data );
+
+ if( type == "fx" && queue.length == 1 )
+ queue[0].call(this);
+ });
+ },
+ dequeue: function(type){
+ return this.each(function(){
+ jQuery.dequeue( this, type );
+ });
+ }
+});/*!
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]+['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
+ done = 0,
+ toString = Object.prototype.toString;
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 )
+ return [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true;
+
+ // Reset the position of the chunker regexp (start from head)
+ chunker.lastIndex = 0;
+
+ while ( (m = chunker.exec(selector)) !== null ) {
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = RegExp.rightContext;
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
+ set = Sizzle.filter( ret.expr, ret.set );
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, isXML(context) );
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, context, results, seed );
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.match[ type ].exec( expr )) ) {
+ var left = RegExp.leftContext;
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound;
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ expr = expr.replace(/\s*,\s*/, "");
+
+ // Improper expression
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part){
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var cur = elem.previousSibling;
+ while ( cur && cur.nodeType !== 1 ) {
+ cur = cur.previousSibling;
+ }
+ checkSet[i] = typeof part === "string" ?
+ cur || false :
+ cur === part;
+ }
+ }
+
+ if ( typeof part === "string" ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = typeof part === "string" ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( typeof part === "string" ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = "done" + (done++), checkFn = dirCheck;
+
+ if ( !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = "done" + (done++), checkFn = dirCheck;
+
+ if ( typeof part === "string" && !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" && !isXML ) {
+ return context.getElementsByName(match[1]);
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ var elem;
+ for ( var i = 0; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (" " + elem.className + " ").indexOf(match) >= 0 ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = "done" + (done++);
+
+ return match;
+ },
+ ATTR: function(match){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( match[3].match(chunker).length > 1 ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ CHILD: function(elem, match){
+ var type = match[1], parent = elem.parentNode;
+
+ var doneName = match[0];
+
+ if ( parent && (!parent[ doneName ] || !elem.nodeIndex) ) {
+ var count = 1;
+
+ for ( var node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType == 1 ) {
+ node.nodeIndex = count++;
+ }
+ }
+
+ parent[ doneName ] = count - 1;
+ }
+
+ if ( type == "first" ) {
+ return elem.nodeIndex == 1;
+ } else if ( type == "last" ) {
+ return elem.nodeIndex == parent[ doneName ];
+ } else if ( type == "only" ) {
+ return parent[ doneName ] == 1;
+ } else if ( type == "nth" ) {
+ var add = false, first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ if ( first == 0 ) {
+ if ( elem.nodeIndex == last ) {
+ add = true;
+ }
+ } else if ( (elem.nodeIndex - last) % first == 0 && (elem.nodeIndex - last) / first >= 0 ) {
+ add = true;
+ }
+
+ return add;
+ }
+ },
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return match.test( elem.className );
+ },
+ ATTR: function(elem, match){
+ var result = Expr.attrHandle[ match[1] ] ? Expr.attrHandle[ match[1] ]( elem ) : elem[ match[1] ] || elem.getAttribute( match[1] ), value = result + "", type = match[2], check = match[4];
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !match[4] ?
+ result :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("form"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<input name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ Sizzle.find = oldSizzle.find;
+ Sizzle.filter = oldSizzle.filter;
+ Sizzle.selectors = oldSizzle.selectors;
+ Sizzle.matches = oldSizzle.matches;
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) {
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context) {
+ return context.getElementsByClassName(match[1]);
+ };
+}
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem && elem.nodeType ) {
+ var done = elem[doneName];
+ if ( done ) {
+ match = checkSet[ done ];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML )
+ elem[doneName] = i;
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem && elem.nodeType ) {
+ if ( elem[doneName] ) {
+ match = checkSet[ elem[doneName] ];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML )
+ elem[doneName] = i;
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && isXML( elem.ownerDocument );
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.filter = Sizzle.filter;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+
+Sizzle.selectors.filters.hidden = function(elem){
+ return "hidden" === elem.type ||
+ jQuery.css(elem, "display") === "none" ||
+ jQuery.css(elem, "visibility") === "hidden";
+};
+
+Sizzle.selectors.filters.visible = function(elem){
+ return "hidden" !== elem.type &&
+ jQuery.css(elem, "display") !== "none" &&
+ jQuery.css(elem, "visibility") !== "hidden";
+};
+
+Sizzle.selectors.filters.animated = function(elem){
+ return jQuery.grep(jQuery.timers, function(fn){
+ return elem === fn.elem;
+ }).length;
+};
+
+jQuery.multiFilter = function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return Sizzle.matches(expr, elems);
+};
+
+jQuery.dir = function( elem, dir ){
+ var matched = [], cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+};
+
+jQuery.nth = function(cur, result, dir, elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+};
+
+jQuery.sibling = function(n, elem){
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && n != elem )
+ r.push( n );
+ }
+
+ return r;
+};
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && elem != window )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = this.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply(arguments.callee.elem, arguments) :
+ undefined;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ handler.type = namespaces.slice().sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( var handle in events[type] )
+ // Handle the removal of namespaced events
+ if ( namespace.test(events[type][handle].type) )
+ delete events[type][handle];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].teardown.call(elem, namespaces);
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem, bubbling ) {
+ // Event object or event type
+ var type = event.type || event;
+
+ if( !bubbling ){
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery.each( jQuery.cache, function(){
+ if ( this.events && this.events[type] )
+ jQuery.event.trigger( event, data, this.handle.elem );
+ });
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data);
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data(elem, "handle");
+ if ( handle )
+ handle.apply( elem, data );
+
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ event.result = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+
+ if ( !event.isPropagationStopped() ) {
+ var parent = elem.parentNode || elem.ownerDocument;
+ if ( parent )
+ jQuery.event.trigger(event, data, parent, true);
+ }
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[event.type];
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply(this, arguments);
+
+ if( ret !== undefined ){
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if( event.isImmediatePropagationStopped() )
+ break;
+
+ }
+ }
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function(event) {
+ if ( event[expando] )
+ return event;
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ){
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = event.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ proxy: function( fn, proxy ){
+ proxy = proxy || function(){ return fn.apply(this, arguments); };
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: bindReady,
+ teardown: function() {}
+ }
+ },
+
+ specialAll: {
+ live: {
+ setup: function( selector, namespaces ){
+ jQuery.event.add( this, namespaces[0], liveHandler );
+ },
+ teardown: function( namespaces ){
+ if ( namespaces.length ) {
+ var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function(){
+ if ( name.test(this.type) )
+ remove++;
+ });
+
+ if ( remove < 1 )
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ){
+ // Allow instantiation without the 'new' keyword
+ if( !this.preventDefault )
+ return new jQuery.Event(src);
+
+ // Event object
+ if( src && src.type ){
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ }else
+ this.type = src;
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[expando] = true;
+};
+
+function returnFalse(){
+ return false;
+}
+function returnTrue(){
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault)
+ e.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation)
+ e.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation:function(){
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != this )
+ try { parent = parent.parentNode; }
+ catch(e) { parent = this; }
+
+ if( parent != this ){
+ // set the correct event type
+ event.type = event.data;
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+};
+
+jQuery.each({
+ mouseover: 'mouseenter',
+ mouseout: 'mouseleave'
+}, function( orig, fix ){
+ jQuery.event.special[ fix ] = {
+ setup: function(){
+ jQuery.event.add( this, orig, withinElement, fix );
+ },
+ teardown: function(){
+ jQuery.event.remove( this, orig, withinElement );
+ }
+ };
+});
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ var one = jQuery.event.proxy( fn || data, function(event) {
+ jQuery(this).unbind(event, one);
+ return (fn || data).apply( this, arguments );
+ });
+ return this.each(function(){
+ jQuery.event.add( this, type, one, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if( this[0] ){
+ var event = jQuery.Event(type);
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while( i < args.length )
+ jQuery.event.proxy( fn, args[i++] );
+
+ return this.click( jQuery.event.proxy( fn, function(event) {
+ // Figure out which function to execute
+ this.lastToggle = ( this.lastToggle || 0 ) % i;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ this.lastToggle++ ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.mouseenter(fnOver).mouseleave(fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( fn );
+
+ return this;
+ },
+
+ live: function( type, fn ){
+ var proxy = jQuery.event.proxy( fn );
+ proxy.guid += this.selector + type;
+
+ jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
+
+ return this;
+ },
+
+ die: function( type, fn ){
+ jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
+ return this;
+ }
+});
+
+function liveHandler( event ){
+ var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
+ stop = true,
+ elems = [];
+
+ jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
+ if ( check.test(fn.type) ) {
+ var elem = jQuery(event.target).closest(fn.data)[0];
+ if ( elem )
+ elems.push({ elem: elem, fn: fn });
+ }
+ });
+
+ jQuery.each(elems, function(){
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
+ stop = false;
+ });
+
+ return stop;
+}
+
+function liveConvert(type, selector){
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
+}
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.call( document, jQuery );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", function(){
+ document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
+ jQuery.ready();
+ }, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", function(){
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", arguments.callee );
+ jQuery.ready();
+ }
+ });
+
+ // If IE and not an iframe
+ // continually check to see if the document is ready
+ if ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (function(){
+ if ( jQuery.isReady ) return;
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
+ "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery( window ).bind( 'unload', function(){
+ for ( var id in jQuery.cache )
+ // Skip the window
+ if ( id != 1 && jQuery.cache[ id ].handle )
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+});
+(function(){
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+
+ div.style.display = "none";
+ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType == 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that you can get all elements in an <object> element
+ // IE 7 always returns no results
+ objectAll: !!div.getElementsByTagName("object")[0]
+ .getElementsByTagName("*").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ opacity: a.style.opacity === "0.5",
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Will be defined later
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e){}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function(){
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", arguments.callee);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function(){
+ var div = document.createElement("div");
+ div.style.width = "1px";
+ div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div );
+ });
+})();
+
+var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ tabindex: "tabIndex"
+};
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" )
+ return this._load( url );
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if( typeof params === "object" ) {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ if( callback )
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = now();
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr:function(){
+ return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ var jsonp, jsre = /=\?(&|$)/g, status, data,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( type == "GET" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && type == "GET" ) {
+ var ts = now();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type == "GET" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // Matches an absolute URL, and saves the domain
+ var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType == "script" && type == "GET" && parts
+ && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
+
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if( s.username )
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ else
+ xhr.open(type, s.url, s.async);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xhr.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xhr.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xhr, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The request was aborted, clear the interval and decrement jQuery.active
+ if (xhr.readyState == 0) {
+ if (ival) {
+ // clear poll interval
+ clearInterval(ival);
+ ival = null;
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" ? "timeout" :
+ !jQuery.httpSuccess( xhr ) ? "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xhr.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xhr, status);
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout )
+ xhr.abort();
+
+ // Stop memory leaks
+ if ( s.async )
+ xhr = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone )
+ onreadystatechange( "timeout" );
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xhr, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xhr, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol == "file:" ||
+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ try {
+ var xhrRes = xhr.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type"),
+ xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // Allow a pre-filtering function to sanitize the response
+ // s != null is checked to keep backwards compatibility
+ if( s && s.dataFilter )
+ data = s.dataFilter( data, type );
+
+ // The filter can actually parse the response
+ if( typeof data === "string" ){
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = window["eval"]("(" + data + ")");
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [ ];
+
+ function add( key, value ){
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
+ };
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( jQuery.isArray(a) || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ add( this.name, this.value );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( jQuery.isArray(a[j]) )
+ jQuery.each( a[j], function(){
+ add( j, this );
+ });
+ else
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+var elemdisplay = {},
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+function genFx( type, num ){
+ var obj = {};
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
+ obj[ this ] = type;
+ });
+ return obj;
+}
+
+jQuery.fn.extend({
+ show: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("show", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var tagName = this[i].tagName, display;
+
+ if ( elemdisplay[ tagName ] ) {
+ display = elemdisplay[ tagName ];
+ } else {
+ var elem = jQuery("<" + tagName + " />").appendTo("body");
+
+ display = elem.css("display");
+ if ( display === "none" )
+ display = "block";
+
+ elem.remove();
+
+ elemdisplay[ tagName ] = display;
+ }
+
+ this[i].style.display = jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" )
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ this[i].style.display = "none";
+ }
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ var bool = typeof fn === "boolean";
+
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle.apply( this, arguments ) :
+ fn == null || bool ?
+ this.each(function(){
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ }) :
+ this.animate(genFx("toggle", 3), fn, fn2);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return opt.complete.call(this);
+
+ if ( ( p == "height" || p == "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ){
+ jQuery.fn[ name ] = function( speed, callback ){
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.call( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.call( this.elem, this.now, this );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) == 1 ) {
+ timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( timerId );
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = now();
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ jQuery(this.elem).hide();
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.extend( jQuery.fx, {
+ speeds:{
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+ step: {
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ else
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+});
+if ( document.documentElement["getBoundingClientRect"] )
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+ return { top: top, left: left };
+ };
+else
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ jQuery.offset.initialized || jQuery.offset.initialize();
+
+ var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView.getComputedStyle(elem, null),
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ computedStyle = defaultView.getComputedStyle(elem, null);
+ top -= elem.scrollTop, left -= elem.scrollLeft;
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop, left += elem.offsetLeft;
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
+ top += body.offsetTop,
+ left += body.offsetLeft;
+
+ if ( prevComputedStyle.position === "fixed" )
+ top += Math.max(docElem.scrollTop, body.scrollTop),
+ left += Math.max(docElem.scrollLeft, body.scrollLeft);
+
+ return { top: top, left: left };
+ };
+
+jQuery.offset = {
+ initialize: function() {
+ if ( this.initialized ) return;
+ var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
+ html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
+
+ rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
+ for ( prop in rules ) container.style[prop] = rules[prop];
+
+ container.innerHTML = html;
+ body.insertBefore(container, body.firstChild);
+ innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ body.style.marginTop = '1px';
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
+ body.style.marginTop = bodyMarginTop;
+
+ body.removeChild(container);
+ this.initialized = true;
+ },
+
+ bodyOffset: function(body) {
+ jQuery.offset.initialized || jQuery.offset.initialize();
+ var top = body.offsetTop, left = body.offsetLeft;
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
+ top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
+ left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
+ return { top: top, left: left };
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ var left = 0, top = 0, results;
+
+ if ( this[0] ) {
+ // Get *real* offsetParent
+ var offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= num( this, 'marginTop' );
+ offset.left -= num( this, 'marginLeft' );
+
+ // Add offsetParent borders
+ parentOffset.top += num( offsetParent, 'borderTopWidth' );
+ parentOffset.left += num( offsetParent, 'borderLeftWidth' );
+
+ // Subtract the two offsets
+ results = {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ }
+
+ return results;
+ },
+
+ offsetParent: function() {
+ var offsetParent = this[0].offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
+ offsetParent = offsetParent.offsetParent;
+ return jQuery(offsetParent);
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ['Left', 'Top'], function(i, name) {
+ var method = 'scroll' + name;
+
+ jQuery.fn[ method ] = function(val) {
+ if (!this[0]) return null;
+
+ return val !== undefined ?
+
+ // Set the scroll offset
+ this.each(function() {
+ this == window || this == document ?
+ window.scrollTo(
+ !i ? val : jQuery(window).scrollLeft(),
+ i ? val : jQuery(window).scrollTop()
+ ) :
+ this[ method ] = val;
+ }) :
+
+ // Return the scroll offset
+ this[0] == window || this[0] == document ?
+ self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
+ jQuery.boxModel && document.documentElement[ method ] ||
+ document.body[ method ] :
+ this[0][ method ];
+ };
+});
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function(i, name){
+
+ var tl = i ? "Left" : "Top", // top or left
+ br = i ? "Right" : "Bottom"; // bottom or right
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function(){
+ return this[ name.toLowerCase() ]() +
+ num(this, "padding" + tl) +
+ num(this, "padding" + br);
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function(margin) {
+ return this["inner" + name]() +
+ num(this, "border" + tl + "Width") +
+ num(this, "border" + br + "Width") +
+ (margin ?
+ num(this, "margin" + tl) + num(this, "margin" + br) : 0);
+ };
+
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
+ document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ document.documentElement["client" + name],
+ document.body["scroll" + name], document.documentElement["scroll" + name],
+ document.body["offset" + name], document.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});})();
diff --git a/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.js b/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.js
new file mode 100644
index 0000000..71bea46
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.js
@@ -0,0 +1,4126 @@
+/*
+ * jQuery UI 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;(function($) {
+
+var _remove = $.fn.remove,
+ isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
+
+//Helper functions and ui object
+$.ui = {
+ version: "1.6rc6",
+
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function(module, option, set) {
+ var proto = $.ui[module].prototype;
+ for(var i in set) {
+ proto.plugins[i] = proto.plugins[i] || [];
+ proto.plugins[i].push([option, set[i]]);
+ }
+ },
+ call: function(instance, name, args) {
+ var set = instance.plugins[name];
+ if(!set) { return; }
+
+ for (var i = 0; i < set.length; i++) {
+ if (instance.options[set[i][0]]) {
+ set[i][1].apply(instance.element, args);
+ }
+ }
+ }
+ },
+
+ contains: function(a, b) {
+ return document.compareDocumentPosition
+ ? a.compareDocumentPosition(b) & 16
+ : a !== b && a.contains(b);
+ },
+
+ cssCache: {},
+ css: function(name) {
+ if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
+ var tmp = $('<div class="ui-gen"></div>').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
+
+ //if (!$.browser.safari)
+ //tmp.appendTo('body');
+
+ //Opera and Safari set width and height to 0px instead of auto
+ //Safari returns rgba(0,0,0,0) when bgcolor is not set
+ $.ui.cssCache[name] = !!(
+ (!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) ||
+ !(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
+ );
+ try { $('body').get(0).removeChild(tmp.get(0)); } catch(e){}
+ return $.ui.cssCache[name];
+ },
+
+ hasScroll: function(el, a) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ($(el).css('overflow') == 'hidden') { return false; }
+
+ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
+ has = false;
+
+ if (el[scroll] > 0) { return true; }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[scroll] = 1;
+ has = (el[scroll] > 0);
+ el[scroll] = 0;
+ return has;
+ },
+
+ isOverAxis: function(x, reference, size) {
+ //Determines when x coordinate is over "b" element axis
+ return (x > reference) && (x < (reference + size));
+ },
+
+ isOver: function(y, x, top, left, height, width) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
+ },
+
+ keyCode: {
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38
+ }
+};
+
+// WAI-ARIA normalization
+if (isFF2) {
+ var attr = $.attr,
+ removeAttr = $.fn.removeAttr,
+ ariaNS = "http://www.w3.org/2005/07/aaa",
+ ariaState = /^aria-/,
+ ariaRole = /^wairole:/;
+
+ $.attr = function(elem, name, value) {
+ var set = value !== undefined;
+
+ return (name == 'role'
+ ? (set
+ ? attr.call(this, elem, name, "wairole:" + value)
+ : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
+ : (ariaState.test(name)
+ ? (set
+ ? elem.setAttributeNS(ariaNS,
+ name.replace(ariaState, "aaa:"), value)
+ : attr.call(this, elem, name.replace(ariaState, "aaa:")))
+ : attr.apply(this, arguments)));
+ };
+
+ $.fn.removeAttr = function(name) {
+ return (ariaState.test(name)
+ ? this.each(function() {
+ this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
+ }) : removeAttr.call(this, name));
+ };
+}
+
+//jQuery plugins
+$.fn.extend({
+ remove: function() {
+ // Safari has a native remove event which actually removes DOM elements,
+ // so we have to use triggerHandler instead of trigger (#3037).
+ $("*", this).add(this).each(function() {
+ $(this).triggerHandler("remove");
+ });
+ return _remove.apply(this, arguments );
+ },
+
+ enableSelection: function() {
+ return this
+ .attr('unselectable', 'off')
+ .css('MozUserSelect', '')
+ .unbind('selectstart.ui');
+ },
+
+ disableSelection: function() {
+ return this
+ .attr('unselectable', 'on')
+ .css('MozUserSelect', 'none')
+ .bind('selectstart.ui', function() { return false; });
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ }
+});
+
+
+//Additional selectors
+$.extend($.expr[':'], {
+ data: function(elem, i, match) {
+ return !!$.data(elem, match[3]);
+ },
+
+ focusable: function(element) {
+ var nodeName = element.nodeName.toLowerCase(),
+ tabIndex = $.attr(element, 'tabindex');
+ return (/input|select|textarea|button|object/.test(nodeName)
+ ? !element.disabled
+ : 'a' == nodeName || 'area' == nodeName
+ ? element.href || !isNaN(tabIndex)
+ : !isNaN(tabIndex))
+ // the element and all of its ancestors must be visible
+ // the browser may report that the area is hidden
+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
+ },
+
+ tabbable: function(element) {
+ var tabIndex = $.attr(element, 'tabindex');
+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
+ }
+});
+
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+function getter(namespace, plugin, method, args) {
+ function getMethods(type) {
+ var methods = $[namespace][plugin][type] || [];
+ return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
+ }
+
+ var methods = getMethods('getter');
+ if (args.length == 1 && typeof args[0] == 'string') {
+ methods = methods.concat(getMethods('getterSetter'));
+ }
+ return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+ var namespace = name.split(".")[0];
+ name = name.split(".")[1];
+
+ // create plugin method
+ $.fn[name] = function(options) {
+ var isMethodCall = (typeof options == 'string'),
+ args = Array.prototype.slice.call(arguments, 1);
+
+ // prevent calls to internal methods
+ if (isMethodCall && options.substring(0, 1) == '_') {
+ return this;
+ }
+
+ // handle getter methods
+ if (isMethodCall && getter(namespace, name, options, args)) {
+ var instance = $.data(this[0], name);
+ return (instance ? instance[options].apply(instance, args)
+ : undefined);
+ }
+
+ // handle initialization and non-getter methods
+ return this.each(function() {
+ var instance = $.data(this, name);
+
+ // constructor
+ (!instance && !isMethodCall &&
+ $.data(this, name, new $[namespace][name](this, options))._init());
+
+ // method call
+ (instance && isMethodCall && $.isFunction(instance[options]) &&
+ instance[options].apply(instance, args));
+ });
+ };
+
+ // create widget constructor
+ $[namespace] = $[namespace] || {};
+ $[namespace][name] = function(element, options) {
+ var self = this;
+
+ this.namespace = namespace;
+ this.widgetName = name;
+ this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
+ this.widgetBaseClass = namespace + '-' + name;
+
+ this.options = $.extend({},
+ $.widget.defaults,
+ $[namespace][name].defaults,
+ $.metadata && $.metadata.get(element)[name],
+ options);
+
+ this.element = $(element)
+ .bind('setData.' + name, function(event, key, value) {
+ if (event.target == element) {
+ return self._setData(key, value);
+ }
+ })
+ .bind('getData.' + name, function(event, key) {
+ if (event.target == element) {
+ return self._getData(key);
+ }
+ })
+ .bind('remove', function() {
+ return self.destroy();
+ });
+ };
+
+ // add widget prototype
+ $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
+
+ // TODO: merge getter and getterSetter properties from widget prototype
+ // and plugin prototype
+ $[namespace][name].getterSetter = 'option';
+};
+
+$.widget.prototype = {
+ _init: function() {},
+ destroy: function() {
+ this.element.removeData(this.widgetName)
+ .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
+ .removeAttr('aria-disabled');
+ },
+
+ option: function(key, value) {
+ var options = key,
+ self = this;
+
+ if (typeof key == "string") {
+ if (value === undefined) {
+ return this._getData(key);
+ }
+ options = {};
+ options[key] = value;
+ }
+
+ $.each(options, function(key, value) {
+ self._setData(key, value);
+ });
+ },
+ _getData: function(key) {
+ return this.options[key];
+ },
+ _setData: function(key, value) {
+ this.options[key] = value;
+
+ if (key == 'disabled') {
+ this.element
+ [value ? 'addClass' : 'removeClass'](
+ this.widgetBaseClass + '-disabled' + ' ' +
+ this.namespace + '-state-disabled')
+ .attr("aria-disabled", value);
+ }
+ },
+
+ enable: function() {
+ this._setData('disabled', false);
+ },
+ disable: function() {
+ this._setData('disabled', true);
+ },
+
+ _trigger: function(type, event, data) {
+ var callback = this.options[type],
+ eventName = (type == this.widgetEventPrefix
+ ? type : this.widgetEventPrefix + type);
+
+ event = $.Event(event);
+ event.type = eventName;
+
+ // copy original event properties over to the new event
+ // this would happen if we could call $.event.fix instead of $.Event
+ // but we don't have a way to force an event to be fixed multiple times
+ if (event.originalEvent) {
+ for (var i = $.event.props.length, prop; i;) {
+ prop = $.event.props[--i];
+ event[prop] = event.originalEvent[prop];
+ }
+ }
+
+ this.element.trigger(event, data);
+
+ return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
+ || event.isDefaultPrevented());
+ }
+};
+
+$.widget.defaults = {
+ disabled: false
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if(self._preventClickEvent) {
+ self._preventClickEvent = false;
+ return false;
+ }
+ });
+
+ // Prevent text selection in IE
+ if ($.browser.msie) {
+ this._mouseUnselectable = this.element.attr('unselectable');
+ this.element.attr('unselectable', 'on');
+ }
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+
+ // Restore text selection in IE
+ ($.browser.msie
+ && this.element.attr('unselectable', this._mouseUnselectable));
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ if (event.originalEvent.mouseHandled) { return; }
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ // preventDefault() is used to prevent the selection of text here -
+ // however, in Safari, this causes select boxes not to be selectable
+ // anymore, so this fix is needed
+ ($.browser.safari || event.preventDefault());
+
+ event.originalEvent.mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+ this._preventClickEvent = true;
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+};
+
+$.ui.mouse.defaults = {
+ cancel: null,
+ distance: 1,
+ delay: 0
+};
+
+})(jQuery);
+/*
+ * jQuery UI Draggable 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+$.widget("ui.draggable", $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
+ this.element[0].style.position = 'relative';
+
+ (this.options.cssNamespace && this.element.addClass(this.options.cssNamespace+"-draggable"));
+ (this.options.disabled && this.element.addClass(this.options.cssNamespace+'-draggable-disabled'));
+
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ if(!this.element.data('draggable')) return;
+ this.element.removeData("draggable").unbind(".draggable").removeClass(this.options.cssNamespace+'-draggable '+this.options.cssNamespace+'-draggable-dragging '+this.options.cssNamespace+'-draggable-disabled');
+ this._mouseDestroy();
+ },
+
+ _mouseCapture: function(event) {
+
+ var o = this.options;
+
+ if (this.helper || o.disabled || $(event.target).is('.'+this.options.cssNamespace+'-resizable-handle'))
+ return false;
+
+ //Quit if we're not on a valid handle
+ this.handle = this._getHandle(event);
+ if (!this.handle)
+ return false;
+
+ return true;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options;
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ //If ddmanager is used for droppables, set the global draggable
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Store the helper's css position
+ this.cssPosition = this.helper.css("position");
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.element.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ if(o.cursorAt)
+ this._adjustOffsetFromHelper(o.cursorAt);
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ //Call plugins and callbacks
+ this._trigger("start", event);
+
+ //Recache the helper size
+ this._cacheHelperProportions();
+
+ //Prepare the droppable offsets
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.helper.addClass(o.cssNamespace+"-draggable-dragging");
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+ return true;
+ },
+
+ _mouseDrag: function(event, noPropagation) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Call plugins and callbacks and use the resulting position if something is returned
+ if (!noPropagation) {
+ var ui = this._uiHash();
+ this._trigger('drag', event, ui);
+ this.position = ui.position;
+ }
+
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ //If we are using droppables, inform the manager about the drop
+ var dropped = false;
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ dropped = $.ui.ddmanager.drop(this, event);
+
+ //if a drop comes from outside (a sortable)
+ if(this.dropped) {
+ dropped = this.dropped;
+ this.dropped = false;
+ }
+
+ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+ var self = this;
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+ self._trigger("stop", event);
+ self._clear();
+ });
+ } else {
+ this._trigger("stop", event);
+ this._clear();
+ }
+
+ return false;
+ },
+
+ _getHandle: function(event) {
+
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+ $(this.options.handle, this.element)
+ .find("*")
+ .andSelf()
+ .each(function() {
+ if(this == event.target) handle = true;
+ });
+
+ return handle;
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
+
+ if(!helper.parents('body').length)
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
+ helper.css("position", "absolute");
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
+ if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
+ if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ },
+
+ _getParentOffset: function() {
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body && $.browser.mozilla) //Ugly FF3 fix
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.element.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _cacheMargins: function() {
+ this.margins = {
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
+ top: (parseInt(this.element.css("marginTop"),10) || 0)
+ };
+ },
+
+ _cacheHelperProportions: function() {
+ this.helperProportions = {
+ width: this.helper.outerWidth(),
+ height: this.helper.outerHeight()
+ };
+ },
+
+ _setContainment: function() {
+
+ var o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ 0 - this.offset.relative.left - this.offset.parent.left,
+ 0 - this.offset.relative.top - this.offset.parent.top,
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
+ var ce = $(o.containment)[0]; if(!ce) return;
+ var co = $(o.containment).offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+ ];
+ } else if(o.containment.constructor == Array) {
+ this.containment = o.containment;
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ // This is another very weird special case that only happens for relative elements:
+ // 1. If the css position is relative
+ // 2. and the scroll parent is the document or similar to the offset parent
+ // we have to refresh the relative offset during the scroll so there are no jumps
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+ this.offset.relative = this._getRelativeOffset();
+ }
+
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+ if(this.containment) {
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )
+ )
+ };
+
+ },
+
+ _clear: function() {
+ this.helper.removeClass(this.options.cssNamespace+"-draggable-dragging");
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
+ this.helper = null;
+ this.cancelHelperRemoval = false;
+ },
+
+ // From now on bulk stuff - mainly helpers
+
+ _trigger: function(type, event, ui) {
+ ui = ui || this._uiHash();
+ $.ui.plugin.call(this, type, [event, ui]);
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+ return $.widget.prototype._trigger.call(this, type, event, ui);
+ },
+
+ plugins: {},
+
+ _uiHash: function(event) {
+ return {
+ helper: this.helper,
+ position: this.position,
+ absolutePosition: this.positionAbs, //deprecated
+ offset: this.positionAbs
+ };
+ }
+
+}));
+
+$.extend($.ui.draggable, {
+ version: "1.6rc6",
+ eventPrefix: "drag",
+ defaults: {
+ appendTo: "parent",
+ axis: false,
+ cancel: ":input,option",
+ connectToSortable: false,
+ containment: false,
+ cssNamespace: "ui",
+ cursor: "default",
+ cursorAt: false,
+ delay: 0,
+ distance: 1,
+ grid: false,
+ handle: false,
+ helper: "original",
+ iframeFix: false,
+ opacity: false,
+ refreshPositions: false,
+ revert: false,
+ revertDuration: 500,
+ scope: "default",
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ snap: false,
+ snapMode: "both",
+ snapTolerance: 20,
+ stack: false,
+ zIndex: false
+ }
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+ start: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options;
+ inst.sortables = [];
+ $(o.connectToSortable).each(function() {
+ // 'this' points to a string, and should therefore resolved as query, but instead, if the string is assigned to a variable, it loops through the strings properties,
+ // so we have to append '' to make it anonymous again
+ $(typeof this == 'string' ? this+'': this).each(function() {
+ if($.data(this, 'sortable')) {
+ var sortable = $.data(this, 'sortable');
+ inst.sortables.push({
+ instance: sortable,
+ shouldRevert: sortable.options.revert
+ });
+ sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
+ sortable._trigger("activate", event, inst);
+ }
+ });
+ });
+
+ },
+ stop: function(event, ui) {
+
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+ var inst = $(this).data("draggable");
+
+ $.each(inst.sortables, function() {
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
+ if(this.shouldRevert) this.instance.options.revert = true;
+
+ //Trigger the stop of the sortable
+ this.instance._mouseStop(event);
+
+ this.instance.options.helper = this.instance.options._helper;
+
+ //If the helper has been the original item, restore properties in the sortable
+ if(inst.options.helper == 'original')
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
+
+ } else {
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+ this.instance._trigger("deactivate", event, inst);
+ }
+
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), self = this;
+
+ var checkPos = function(o) {
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
+ var itemHeight = o.height, itemWidth = o.width;
+ var itemTop = o.top, itemLeft = o.left;
+
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
+ };
+
+ $.each(inst.sortables, function(i) {
+
+ if(checkPos.call(inst, this.instance.containerCache)) {
+
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+ if(!this.instance.isOver) {
+ this.instance.isOver = 1;
+ //Now we fake the start of dragging for the sortable instance,
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+ this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+ this.instance.options.helper = function() { return ui.helper[0]; };
+
+ event.target = this.instance.currentItem[0];
+ this.instance._mouseCapture(event, true);
+ this.instance._mouseStart(event, true, true);
+
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+ this.instance.offset.click.top = inst.offset.click.top;
+ this.instance.offset.click.left = inst.offset.click.left;
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+ inst._trigger("toSortable", event);
+ inst.dropped = this.instance.element; //draggable revert needs that
+ this.instance.fromOutside = inst; //Little hack so receive/update callbacks work
+
+ }
+
+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
+
+ } else {
+
+ //If it doesn't intersect with the sortable, and it intersected before,
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+ if(this.instance.isOver) {
+ this.instance.isOver = 0;
+ this.instance.cancelHelperRemoval = true;
+ this.instance.options.revert = false; //No revert here
+ this.instance._mouseStop(event, true);
+ this.instance.options.helper = this.instance.options._helper;
+
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+ this.instance.currentItem.remove();
+ if(this.instance.placeholder) this.instance.placeholder.remove();
+
+ inst._trigger("fromSortable", event);
+ inst.dropped = false; //draggable revert needs that
+ }
+
+ };
+
+ });
+
+ }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+ start: function(event, ui) {
+ var t = $('body'), o = $(this).data('draggable').options;
+ if (t.css("cursor")) o._cursor = t.css("cursor");
+ t.css("cursor", o.cursor);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if (o._cursor) $('body').css("cursor", o._cursor);
+ }
+});
+
+$.ui.plugin.add("draggable", "iframeFix", {
+ start: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+ .css({
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+ position: "absolute", opacity: "0.001", zIndex: 1000
+ })
+ .css($(this).offset())
+ .appendTo("body");
+ });
+ },
+ stop: function(event, ui) {
+ $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
+ }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data('draggable').options;
+ if(t.css("opacity")) o._opacity = t.css("opacity");
+ t.css('opacity', o.opacity);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
+ }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+ start: function(event, ui) {
+ var i = $(this).data("draggable");
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
+ },
+ drag: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
+
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
+
+ if(!o.axis || o.axis != 'x') {
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+ }
+
+ } else {
+
+ if(!o.axis || o.axis != 'x') {
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+ }
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(i, event);
+
+ }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+ start: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options;
+ i.snapElements = [];
+
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+ var $t = $(this); var $o = $t.offset();
+ if(this != i.element[0]) i.snapElements.push({
+ item: this,
+ width: $t.outerWidth(), height: $t.outerHeight(),
+ top: $o.top, left: $o.left
+ });
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options;
+ var d = o.snapTolerance;
+
+ var x1 = ui.absolutePosition.left, x2 = x1 + inst.helperProportions.width,
+ y1 = ui.absolutePosition.top, y2 = y1 + inst.helperProportions.height;
+
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
+
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+
+ //Yes, I know, this is insane ;)
+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = false;
+ continue;
+ }
+
+ if(o.snapMode != 'inner') {
+ var ts = Math.abs(t - y2) <= d;
+ var bs = Math.abs(b - y1) <= d;
+ var ls = Math.abs(l - x2) <= d;
+ var rs = Math.abs(r - x1) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+ }
+
+ var first = (ts || bs || ls || rs);
+
+ if(o.snapMode != 'outer') {
+ var ts = Math.abs(t - y1) <= d;
+ var bs = Math.abs(b - y2) <= d;
+ var ls = Math.abs(l - x1) <= d;
+ var rs = Math.abs(r - x2) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+ }
+
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+ };
+
+ }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+ start: function(event, ui) {
+
+ var o = $(this).data("draggable").options;
+
+ var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
+ return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
+ });
+
+ $(group).each(function(i) {
+ this.style.zIndex = o.stack.min + i;
+ });
+
+ this[0].style.zIndex = o.stack.min + group.length;
+
+ }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data("draggable").options;
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
+ t.css('zIndex', o.zIndex);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data("draggable").options;
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
+ }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Resizable 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ var self = this, o = this.options;
+ this.element.addClass("ui-resizable");
+
+ $.extend(this, {
+ _aspectRatio: !!(o.aspectRatio),
+ aspectRatio: o.aspectRatio,
+ originalElement: this.element,
+ proportionallyResize: o.proportionallyResize ? [o.proportionallyResize] : [],
+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+ });
+
+ //Wrap the element if it cannot hold child nodes
+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+ //Opera fix for relative positioning
+ if (/relative/.test(this.element.css('position')) && $.browser.opera)
+ this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ //Create a wrapper element and set the wrapper to the new current internal element
+ this.element.wrap(
+ $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+ position: this.element.css('position'),
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight(),
+ top: this.element.css('top'),
+ left: this.element.css('left')
+ })
+ );
+
+ //Overwrite the original this.element
+ this.element = this.element.parent();
+ this.elementIsWrapper = true;
+
+ //Move margins to the wrapper
+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+ //Prevent Safari textarea resize
+ if ($.browser.safari && o.preventDefault) this.originalElement.css('resize', 'none');
+
+ //Push the actual element to our proportionallyResize internal array
+ this.proportionallyResize.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+ // avoid IE jump (hard set the margin)
+ this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+ // fix handlers offset
+ this._proportionallyResize();
+
+ }
+
+ this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
+ if(this.handles.constructor == String) {
+
+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+ var n = this.handles.split(","); this.handles = {};
+
+ for(var i = 0; i < n.length; i++) {
+
+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+ // increase zIndex of sw, se, ne, nw axis
+ //TODO : this modifies original option
+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+ //TODO : What's going on here?
+ if ('se' == handle) {
+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+ };
+
+ //Insert into internal handles object and append to element
+ this.handles[handle] = '.ui-resizable-'+handle;
+ this.element.append(axis);
+ }
+
+ }
+
+ this._renderAxis = function(target) {
+
+ target = target || this.element;
+
+ for(var i in this.handles) {
+
+ if(this.handles[i].constructor == String)
+ this.handles[i] = $(this.handles[i], this.element).show();
+
+ if (o.transparent)
+ this.handles[i].css({ opacity: 0 });
+
+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+ var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+ //Checking the correct pad and border
+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+ //The padding type i have to apply...
+ var padPos = [ 'padding',
+ /ne|nw|n/.test(i) ? 'Top' :
+ /se|sw|s/.test(i) ? 'Bottom' :
+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+ if (!o.transparent)
+ target.css(padPos, padWrapper);
+
+ this._proportionallyResize();
+
+ }
+
+ //TODO: What's that good for? There's not anything to be executed left
+ if(!$(this.handles[i]).length)
+ continue;
+
+ }
+ };
+
+ //TODO: make renderAxis a prototype function
+ this._renderAxis(this.element);
+
+ this._handles = $('.ui-resizable-handle', this.element);
+
+ if (o.disableSelection)
+ this._handles.disableSelection();
+
+ //Matching axis name
+ this._handles.mouseover(function() {
+ if (!self.resizing) {
+ if (this.className)
+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+ //Axis, default = se
+ self.axis = axis && axis[1] ? axis[1] : 'se';
+ }
+ });
+
+ //If we want to auto hide the elements
+ if (o.autoHide) {
+ this._handles.hide();
+ $(this.element)
+ .addClass("ui-resizable-autohide")
+ .hover(function() {
+ $(this).removeClass("ui-resizable-autohide");
+ self._handles.show();
+ },
+ function(){
+ if (!self.resizing) {
+ $(this).addClass("ui-resizable-autohide");
+ self._handles.hide();
+ }
+ });
+ }
+
+ //Initialize the mouse interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+
+ this._mouseDestroy();
+
+ var _destroy = function(exp) {
+ $(exp).removeClass("ui-resizable ui-resizable-disabled")
+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+ };
+
+ //TODO: Unwrap at same DOM position
+ if (this.elementIsWrapper) {
+ _destroy(this.element);
+ this.wrapper.parent().append(
+ this.originalElement.css({
+ position: this.wrapper.css('position'),
+ width: this.wrapper.outerWidth(),
+ height: this.wrapper.outerHeight(),
+ top: this.wrapper.css('top'),
+ left: this.wrapper.css('left')
+ })
+ ).end().remove();
+ }
+
+ _destroy(this.originalElement);
+
+ },
+
+ _mouseCapture: function(event) {
+
+ var handle = false;
+ for(var i in this.handles) {
+ if($(this.handles[i])[0] == event.target) handle = true;
+ }
+
+ return this.options.disabled || !!handle;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options, iniPos = this.element.position(), el = this.element;
+
+ this.resizing = true;
+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+ // bugfix for http://dev.jquery.com/ticket/1749
+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+ }
+
+ //Opera fixing relative position
+ if ($.browser.opera && (/relative/).test(el.css('position')))
+ el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ this._renderProxy();
+
+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+ if (o.containment) {
+ curleft += $(o.containment).scrollLeft() || 0;
+ curtop += $(o.containment).scrollTop() || 0;
+ }
+
+ //Store needed variables
+ this.offset = this.helper.offset();
+ this.position = { left: curleft, top: curtop };
+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalPosition = { left: curleft, top: curtop };
+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+ //Aspect Ratio
+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+ if (o.preserveCursor) {
+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+ }
+
+ this._propagate("start", event);
+ return true;
+ },
+
+ _mouseDrag: function(event) {
+
+ //Increase performance, avoid regex
+ var el = this.helper, o = this.options, props = {},
+ self = this, smp = this.originalMousePosition, a = this.axis;
+
+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+ var trigger = this._change[a];
+ if (!trigger) return false;
+
+ // Calculate the attrs that will be change
+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+ if (this._aspectRatio || event.shiftKey)
+ data = this._updateRatio(data, event);
+
+ data = this._respectSize(data, event);
+
+ // plugins callbacks need to be called first
+ this._propagate("resize", event);
+
+ el.css({
+ top: this.position.top + "px", left: this.position.left + "px",
+ width: this.size.width + "px", height: this.size.height + "px"
+ });
+
+ if (!this._helper && this.proportionallyResize.length)
+ this._proportionallyResize();
+
+ this._updateCache(data);
+
+ // calling the user callback at the end
+ this._trigger('resize', event, this.ui());
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ this.resizing = false;
+ var o = this.options, self = this;
+
+ if(this._helper) {
+ var pr = this.proportionallyResize, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ if (!o.animate)
+ this.element.css($.extend(s, { top: top, left: left }));
+
+ if (this._helper && !o.animate) this._proportionallyResize();
+ }
+
+ if (o.preserveCursor)
+ $('body').css('cursor', 'auto');
+
+ this._propagate("stop", event);
+
+ if (this._helper) this.helper.remove();
+ return false;
+
+ },
+
+ _updateCache: function(data) {
+ var o = this.options;
+ this.offset = this.helper.offset();
+ if (data.left) this.position.left = data.left;
+ if (data.top) this.position.top = data.top;
+ if (data.height) this.size.height = data.height;
+ if (data.width) this.size.width = data.width;
+ },
+
+ _updateRatio: function(data, event) {
+
+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+ if (data.height) data.width = (csize.height * this.aspectRatio);
+ else if (data.width) data.height = (csize.width / this.aspectRatio);
+
+ if (a == 'sw') {
+ data.left = cpos.left + (csize.width - data.width);
+ data.top = null;
+ }
+ if (a == 'nw') {
+ data.top = cpos.top + (csize.height - data.height);
+ data.left = cpos.left + (csize.width - data.width);
+ }
+
+ return data;
+ },
+
+ _respectSize: function(data, event) {
+
+ var isNumber = function(value) {
+ return !isNaN(parseInt(value, 10))
+ };
+
+ var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+ if (isminw) data.width = o.minWidth;
+ if (isminh) data.height = o.minHeight;
+ if (ismaxw) data.width = o.maxWidth;
+ if (ismaxh) data.height = o.maxHeight;
+
+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+ if (isminw && cw) data.left = dw - o.minWidth;
+ if (ismaxw && cw) data.left = dw - o.maxWidth;
+ if (isminh && ch) data.top = dh - o.minHeight;
+ if (ismaxh && ch) data.top = dh - o.maxHeight;
+
+ // fixing jump error on top/left - bug #2330
+ var isNotwh = !data.width && !data.height;
+ if (isNotwh && !data.left && data.top) data.top = null;
+ else if (isNotwh && !data.top && data.left) data.left = null;
+
+ return data;
+ },
+
+ _proportionallyResize: function() {
+
+ var o = this.options;
+ if (!this.proportionallyResize.length) return;
+ var element = this.helper || this.element;
+
+ for (var i=0; i < this.proportionallyResize.length; i++) {
+
+ var prel = this.proportionallyResize[i];
+
+ if (!this.borderDif) {
+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+ this.borderDif = $.map(b, function(v, i) {
+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+ return border + padding;
+ });
+ }
+
+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+ continue;
+
+ prel.css({
+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+ });
+
+ };
+
+ },
+
+ _renderProxy: function() {
+
+ var el = this.element, o = this.options;
+ this.elementOffset = el.offset();
+
+ if(this._helper) {
+
+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+ // fix ie6 offset TODO: This seems broken
+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+ pxyoffset = ( ie6 ? 2 : -1 );
+
+ this.helper.addClass(this._helper).css({
+ width: this.element.outerWidth() + pxyoffset,
+ height: this.element.outerHeight() + pxyoffset,
+ position: 'absolute',
+ left: this.elementOffset.left - ie6offset +'px',
+ top: this.elementOffset.top - ie6offset +'px',
+ zIndex: ++o.zIndex //TODO: Don't modify option
+ });
+
+ this.helper.appendTo("body");
+
+ if (o.disableSelection)
+ this.helper.disableSelection();
+
+ } else {
+ this.helper = this.element;
+ }
+
+ },
+
+ _change: {
+ e: function(event, dx, dy) {
+ return { width: this.originalSize.width + dx };
+ },
+ w: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { left: sp.left + dx, width: cs.width - dx };
+ },
+ n: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { top: sp.top + dy, height: cs.height - dy };
+ },
+ s: function(event, dx, dy) {
+ return { height: this.originalSize.height + dy };
+ },
+ se: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ sw: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ },
+ ne: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ nw: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ }
+ },
+
+ _propagate: function(n, event) {
+ $.ui.plugin.call(this, n, [event, this.ui()]);
+ (n != "resize" && this._trigger(n, event, this.ui()));
+ },
+
+ plugins: {},
+
+ ui: function() {
+ return {
+ originalElement: this.originalElement,
+ element: this.element,
+ helper: this.helper,
+ position: this.position,
+ size: this.size,
+ originalSize: this.originalSize,
+ originalPosition: this.originalPosition
+ };
+ }
+
+}));
+
+$.extend($.ui.resizable, {
+ version: "1.6rc6",
+ eventPrefix: "resize",
+ defaults: {
+ alsoResize: false,
+ animate: false,
+ animateDuration: "slow",
+ animateEasing: "swing",
+ aspectRatio: false,
+ autoHide: false,
+ cancel: ":input,option",
+ containment: false,
+ delay: 0,
+ disableSelection: true,
+ distance: 1,
+ ghost: false,
+ grid: false,
+ handles: "e,s,se",
+ helper: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ preserveCursor: true,
+ preventDefault: true,
+ proportionallyResize: false,
+ transparent: false,
+ zIndex: 1000
+ }
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options;
+
+ _store = function(exp) {
+ $(exp).each(function() {
+ $(this).data("resizable-alsoresize", {
+ width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
+ left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
+ });
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+ else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
+ }else{
+ _store(o.alsoResize);
+ }
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+ var delta = {
+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+ },
+
+ _alsoResize = function(exp, c) {
+ $(exp).each(function() {
+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
+
+ $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
+ var sum = (start[prop]||0) + (delta[prop]||0);
+ if (sum && sum >= 0)
+ style[prop] = sum || null;
+ });
+
+ //Opera fixing relative position
+ if (/relative/.test(el.css('position')) && $.browser.opera) {
+ self._revertToRelativePosition = true;
+ el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+ }
+
+ el.css(style);
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
+ }else{
+ _alsoResize(o.alsoResize);
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable");
+
+ //Opera fixing relative position
+ if (self._revertToRelativePosition && $.browser.opera) {
+ self._revertToRelativePosition = false;
+ el.css({ position: 'relative' });
+ }
+
+ $(this).removeData("resizable-alsoresize-start");
+ }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+ stop: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
+ soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ self.element.animate(
+ $.extend(style, top && left ? { top: top, left: left } : {}), {
+ duration: o.animateDuration,
+ easing: o.animateEasing,
+ step: function() {
+
+ var data = {
+ width: parseInt(self.element.css('width'), 10),
+ height: parseInt(self.element.css('height'), 10),
+ top: parseInt(self.element.css('top'), 10),
+ left: parseInt(self.element.css('left'), 10)
+ };
+
+ if (pr) pr.css({ width: data.width, height: data.height });
+
+ // propagating resize, and updating values for each animation step
+ self._updateCache(data);
+ self._propagate("resize", event);
+
+ }
+ }
+ );
+ }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+ start: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, el = self.element;
+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+ if (!ce) return;
+
+ self.containerElement = $(ce);
+
+ if (/document/.test(oc) || oc == document) {
+ self.containerOffset = { left: 0, top: 0 };
+ self.containerPosition = { left: 0, top: 0 };
+
+ self.parentData = {
+ element: $(document), left: 0, top: 0,
+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+ };
+ }
+
+ // i'm a node, so compute top, left, right, bottom
+ else {
+ var element = $(ce), p = [];
+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+ self.containerOffset = element.offset();
+ self.containerPosition = element.position();
+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+ self.parentData = {
+ element: ce, left: co.left, top: co.top, width: width, height: height
+ };
+ }
+ },
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options,
+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+ pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+ if (cp.left < (self._helper ? co.left : 0)) {
+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ self.position.left = o.helper ? co.left : 0;
+ }
+
+ if (cp.top < (self._helper ? co.top : 0)) {
+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ self.position.top = self._helper ? co.top : 0;
+ }
+
+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+ if (woset + self.size.width >= self.parentData.width) {
+ self.size.width = self.parentData.width - woset;
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ }
+
+ if (hoset + self.size.height >= self.parentData.height) {
+ self.size.height = self.parentData.height - hoset;
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options, pr = o.proportionallyResize, cs = self.size;
+
+ self.ghost = self.originalElement.clone();
+ self.ghost
+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .addClass('ui-resizable-ghost')
+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+ self.ghost.appendTo(self.helper);
+
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+ }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+ if (/^(se|s|e)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ }
+ else if (/^(ne)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ }
+ else if (/^(sw)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.left = op.left - ox;
+ }
+ else {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ self.position.left = op.left - ox;
+ }
+ }
+
+});
+
+var num = function(v) {
+ return parseInt(v, 10) || 0;
+};
+
+})(jQuery);
+/*
+ * jQuery UI Dialog 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * ui.core.js
+ * ui.draggable.js
+ * ui.resizable.js
+ */
+(function($) {
+
+var setDataSwitch = {
+ dragStart: "start.draggable",
+ drag: "drag.draggable",
+ dragStop: "stop.draggable",
+ maxHeight: "maxHeight.resizable",
+ minHeight: "minHeight.resizable",
+ maxWidth: "maxWidth.resizable",
+ minWidth: "minWidth.resizable",
+ resizeStart: "start.resizable",
+ resize: "drag.resizable",
+ resizeStop: "stop.resizable"
+};
+
+$.widget("ui.dialog", {
+
+ _init: function() {
+ this.originalTitle = this.element.attr('title');
+
+ var self = this,
+ options = this.options,
+
+ title = options.title || this.originalTitle || '&nbsp;',
+ titleId = $.ui.dialog.getTitleId(this.element),
+
+ uiDialog = (this.uiDialog = $('<div/>'))
+ .appendTo(document.body)
+ .hide()
+ .addClass(
+ 'ui-dialog ' +
+ 'ui-widget ' +
+ 'ui-widget-content ' +
+ 'ui-corner-all ' +
+ options.dialogClass
+ )
+ .css({
+ position: 'absolute',
+ overflow: 'hidden',
+ zIndex: options.zIndex
+ })
+ // setting tabIndex makes the div focusable
+ // setting outline to 0 prevents a border on focus in Mozilla
+ .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
+ (options.closeOnEscape && event.keyCode
+ && event.keyCode == $.ui.keyCode.ESCAPE && self.close(event));
+ })
+ .attr({
+ role: 'dialog',
+ 'aria-labelledby': titleId
+ })
+ .mousedown(function(event) {
+ self.moveToTop(event);
+ }),
+
+ uiDialogContent = this.element
+ .show()
+ .removeAttr('title')
+ .addClass(
+ 'ui-dialog-content ' +
+ 'ui-widget-content')
+ .appendTo(uiDialog),
+
+ uiDialogTitlebar = (this.uiDialogTitlebar = $('<div></div>'))
+ .addClass(
+ 'ui-dialog-titlebar ' +
+ 'ui-widget-header ' +
+ 'ui-corner-all ' +
+ 'ui-helper-clearfix'
+ )
+ .prependTo(uiDialog),
+
+ uiDialogTitlebarClose = $('<a href="#"/>')
+ .addClass(
+ 'ui-dialog-titlebar-close ' +
+ 'ui-corner-all'
+ )
+ .attr('role', 'button')
+ .hover(
+ function() {
+ uiDialogTitlebarClose.addClass('ui-state-hover');
+ },
+ function() {
+ uiDialogTitlebarClose.removeClass('ui-state-hover');
+ }
+ )
+ .focus(function() {
+ uiDialogTitlebarClose.addClass('ui-state-focus');
+ })
+ .blur(function() {
+ uiDialogTitlebarClose.removeClass('ui-state-focus');
+ })
+ .mousedown(function(ev) {
+ ev.stopPropagation();
+ })
+ .click(function(event) {
+ self.close(event);
+ return false;
+ })
+ .appendTo(uiDialogTitlebar),
+
+ uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
+ .addClass(
+ 'ui-icon ' +
+ 'ui-icon-closethick'
+ )
+ .text(options.closeText)
+ .appendTo(uiDialogTitlebarClose),
+
+ uiDialogTitle = $('<span/>')
+ .addClass('ui-dialog-title')
+ .attr('id', titleId)
+ .html(title)
+ .prependTo(uiDialogTitlebar);
+
+ uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
+
+ (options.draggable && $.fn.draggable && this._makeDraggable());
+ (options.resizable && $.fn.resizable && this._makeResizable());
+
+ this._createButtons(options.buttons);
+ this._isOpen = false;
+
+ (options.bgiframe && $.fn.bgiframe && uiDialog.bgiframe());
+ (options.autoOpen && this.open());
+
+ },
+
+ destroy: function() {
+ (this.overlay && this.overlay.destroy());
+ (this.shadow && this._destroyShadow());
+ this.uiDialog.hide();
+ this.element
+ .unbind('.dialog')
+ .removeData('dialog')
+ .removeClass('ui-dialog-content ui-widget-content')
+ .hide().appendTo('body');
+ this.uiDialog.remove();
+
+ (this.originalTitle && this.element.attr('title', this.originalTitle));
+ },
+
+ close: function(event) {
+ if (false === this._trigger('beforeclose', event)) {
+ return;
+ }
+
+ (this.overlay && this.overlay.destroy());
+ (this.shadow && this._destroyShadow());
+ this.uiDialog
+ .hide(this.options.hide)
+ .unbind('keypress.ui-dialog');
+
+ this._trigger('close', event);
+ $.ui.dialog.overlay.resize();
+
+ this._isOpen = false;
+ },
+
+ isOpen: function() {
+ return this._isOpen;
+ },
+
+ // the force parameter allows us to move modal dialogs to their correct
+ // position on open
+ moveToTop: function(force, event) {
+
+ if ((this.options.modal && !force)
+ || (!this.options.stack && !this.options.modal)) {
+ return this._trigger('focus', event);
+ }
+
+ var maxZ = this.options.zIndex, options = this.options;
+ $('.ui-dialog:visible').each(function() {
+ maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10) || options.zIndex);
+ });
+ (this.overlay && this.overlay.$el.css('z-index', ++maxZ));
+ (this.shadow && this.shadow.css('z-index', ++maxZ));
+
+ //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
+ // http://ui.jquery.com/bugs/ticket/3193
+ var saveScroll = { scrollTop: this.element.attr('scrollTop'), scrollLeft: this.element.attr('scrollLeft') };
+ this.uiDialog.css('z-index', ++maxZ);
+ this.element.attr(saveScroll);
+ this._trigger('focus', event);
+ },
+
+ open: function(event) {
+ if (this._isOpen) { return; }
+
+ var options = this.options,
+ uiDialog = this.uiDialog;
+
+ this.overlay = options.modal ? new $.ui.dialog.overlay(this) : null;
+ (uiDialog.next().length && uiDialog.appendTo('body'));
+ this._size();
+ this._position(options.position);
+ uiDialog.show(options.show);
+ this.moveToTop(true, event);
+
+ // prevent tabbing out of modal dialogs
+ (options.modal && uiDialog.bind('keypress.ui-dialog', function(event) {
+ if (event.keyCode != $.ui.keyCode.TAB) {
+ return;
+ }
+
+ var tabbables = $(':tabbable', this),
+ first = tabbables.filter(':first')[0],
+ last = tabbables.filter(':last')[0];
+
+ if (event.target == last && !event.shiftKey) {
+ setTimeout(function() {
+ first.focus();
+ }, 1);
+ } else if (event.target == first && event.shiftKey) {
+ setTimeout(function() {
+ last.focus();
+ }, 1);
+ }
+ }));
+
+ // set focus to the first tabbable element in:
+ // - content area
+ // - button pane
+ // - title bar
+ $([])
+ .add(uiDialog.find('.ui-dialog-content :tabbable:first'))
+ .add(uiDialog.find('.ui-dialog-buttonpane :tabbable:first'))
+ .add(uiDialog.find('.ui-dialog-titlebar :tabbable:first'))
+ .filter(':first')
+ .focus();
+
+ if(options.shadow)
+ this._createShadow();
+
+ this._trigger('open', event);
+ this._isOpen = true;
+ },
+
+ _createButtons: function(buttons) {
+ var self = this,
+ hasButtons = false,
+ uiDialogButtonPane = $('<div></div>')
+ .addClass(
+ 'ui-dialog-buttonpane ' +
+ 'ui-widget-content ' +
+ 'ui-helper-clearfix'
+ );
+
+ // if we already have a button pane, remove it
+ this.uiDialog.find('.ui-dialog-buttonpane').remove();
+
+ (typeof buttons == 'object' && buttons !== null &&
+ $.each(buttons, function() { return !(hasButtons = true); }));
+ if (hasButtons) {
+ $.each(buttons, function(name, fn) {
+ $('<button type="button"></button>')
+ .addClass(
+ 'ui-state-default ' +
+ 'ui-corner-all'
+ )
+ .text(name)
+ .click(function() { fn.apply(self.element[0], arguments); })
+ .hover(
+ function() {
+ $(this).addClass('ui-state-hover');
+ },
+ function() {
+ $(this).removeClass('ui-state-hover');
+ }
+ )
+ .focus(function() {
+ $(this).addClass('ui-state-focus');
+ })
+ .blur(function() {
+ $(this).removeClass('ui-state-focus');
+ })
+ .appendTo(uiDialogButtonPane);
+ });
+ uiDialogButtonPane.appendTo(this.uiDialog);
+ }
+ },
+
+ _makeDraggable: function() {
+ var self = this,
+ options = this.options;
+
+ this.uiDialog.draggable({
+ cancel: '.ui-dialog-content',
+ helper: options.dragHelper,
+ handle: '.ui-dialog-titlebar',
+ containment: 'document',
+ start: function() {
+ (options.dragStart && options.dragStart.apply(self.element[0], arguments));
+ if($.browser.msie && $.browser.version < 7 && self.shadow) self.shadow.hide();
+ },
+ drag: function() {
+ (options.drag && options.drag.apply(self.element[0], arguments));
+ self._refreshShadow(1);
+ },
+ stop: function() {
+ (options.dragStop && options.dragStop.apply(self.element[0], arguments));
+ $.ui.dialog.overlay.resize();
+ if($.browser.msie && $.browser.version < 7 && self.shadow) self.shadow.show();
+ self._refreshShadow();
+ }
+ });
+ },
+
+ _makeResizable: function(handles) {
+ handles = (handles === undefined ? this.options.resizable : handles);
+ var self = this,
+ options = this.options,
+ resizeHandles = typeof handles == 'string'
+ ? handles
+ : 'n,e,s,w,se,sw,ne,nw';
+
+ this.uiDialog.resizable({
+ cancel: '.ui-dialog-content',
+ alsoResize: this.element,
+ helper: options.resizeHelper,
+ maxWidth: options.maxWidth,
+ maxHeight: options.maxHeight,
+ minWidth: options.minWidth,
+ minHeight: options.minHeight,
+ start: function() {
+ (options.resizeStart && options.resizeStart.apply(self.element[0], arguments));
+ if($.browser.msie && $.browser.version < 7 && self.shadow) self.shadow.hide();
+ },
+ resize: function() {
+ (options.resize && options.resize.apply(self.element[0], arguments));
+ self._refreshShadow(1);
+ },
+ handles: resizeHandles,
+ stop: function() {
+ (options.resizeStop && options.resizeStop.apply(self.element[0], arguments));
+ $.ui.dialog.overlay.resize();
+ if($.browser.msie && $.browser.version < 7 && self.shadow) self.shadow.show();
+ self._refreshShadow();
+ }
+ })
+ .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
+ },
+
+ _position: function(pos) {
+ var wnd = $(window), doc = $(document),
+ pTop = doc.scrollTop(), pLeft = doc.scrollLeft(),
+ minTop = pTop;
+
+ if ($.inArray(pos, ['center','top','right','bottom','left']) >= 0) {
+ pos = [
+ pos == 'right' || pos == 'left' ? pos : 'center',
+ pos == 'top' || pos == 'bottom' ? pos : 'middle'
+ ];
+ }
+ if (pos.constructor != Array) {
+ pos = ['center', 'middle'];
+ }
+ if (pos[0].constructor == Number) {
+ pLeft += pos[0];
+ } else {
+ switch (pos[0]) {
+ case 'left':
+ pLeft += 0;
+ break;
+ case 'right':
+ pLeft += wnd.width() - this.uiDialog.outerWidth();
+ break;
+ default:
+ case 'center':
+ pLeft += (wnd.width() - this.uiDialog.outerWidth()) / 2;
+ }
+ }
+ if (pos[1].constructor == Number) {
+ pTop += pos[1];
+ } else {
+ switch (pos[1]) {
+ case 'top':
+ pTop += 0;
+ break;
+ case 'bottom':
+ pTop += wnd.height() - this.uiDialog.outerHeight();
+ break;
+ default:
+ case 'middle':
+ pTop += (wnd.height() - this.uiDialog.outerHeight()) / 2;
+ }
+ }
+
+ // prevent the dialog from being too high (make sure the titlebar
+ // is accessible)
+ pTop = Math.max(pTop, minTop);
+ this.uiDialog.css({top: pTop, left: pLeft});
+ },
+
+ _setData: function(key, value){
+ (setDataSwitch[key] && this.uiDialog.data(setDataSwitch[key], value));
+ switch (key) {
+ case "buttons":
+ this._createButtons(value);
+ break;
+ case "closeText":
+ this.uiDialogTitlebarCloseText.text(value);
+ break;
+ case "draggable":
+ (value
+ ? this._makeDraggable()
+ : this.uiDialog.draggable('destroy'));
+ break;
+ case "height":
+ this.uiDialog.height(value);
+ break;
+ case "position":
+ this._position(value);
+ break;
+ case "resizable":
+ var uiDialog = this.uiDialog,
+ isResizable = this.uiDialog.is(':data(resizable)');
+
+ // currently resizable, becoming non-resizable
+ (isResizable && !value && uiDialog.resizable('destroy'));
+
+ // currently resizable, changing handles
+ (isResizable && typeof value == 'string' &&
+ uiDialog.resizable('option', 'handles', value));
+
+ // currently non-resizable, becoming resizable
+ (isResizable || this._makeResizable(value));
+
+ break;
+ case "title":
+ $(".ui-dialog-title", this.uiDialogTitlebar).html(value || '&nbsp;');
+ break;
+ case "width":
+ this.uiDialog.width(value);
+ break;
+ }
+
+ $.widget.prototype._setData.apply(this, arguments);
+ },
+
+ _size: function() {
+ /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+ * divs will both have width and height set, so we need to reset them
+ */
+ var options = this.options;
+
+ // reset content sizing
+ this.element.css({
+ height: 0,
+ minHeight: 0,
+ width: 'auto'
+ });
+
+ // reset wrapper sizing
+ // determine the height of all the non-content elements
+ var nonContentHeight = this.uiDialog.css({
+ height: 'auto',
+ width: options.width
+ })
+ .height();
+
+ this.element
+ .css({
+ minHeight: Math.max(options.minHeight - nonContentHeight, 0),
+ height: options.height == 'auto'
+ ? 'auto'
+ : options.height - nonContentHeight
+ });
+ },
+
+ _createShadow: function() {
+ this.shadow = $('<div class="ui-widget-shadow"></div>').css('position', 'absolute').appendTo(document.body);
+ this._refreshShadow();
+ return this.shadow;
+ },
+
+ _refreshShadow: function(dragging) {
+ // IE6 is simply to slow to handle the reflow in a good way, so
+ // resizing only happens on stop, and the shadow is hidden during drag/resize
+ if(dragging && $.browser.msie && $.browser.version < 7) return;
+
+ var offset = this.uiDialog.offset();
+ this.shadow.css({
+ left: offset.left,
+ top: offset.top,
+ width: this.uiDialog.outerWidth(),
+ height: this.uiDialog.outerHeight()
+ });
+ },
+
+ _destroyShadow: function() {
+ this.shadow.remove();
+ this.shadow = null;
+ }
+
+});
+
+$.extend($.ui.dialog, {
+ version: "1.6rc6",
+ defaults: {
+ autoOpen: true,
+ bgiframe: false,
+ buttons: {},
+ closeOnEscape: true,
+ closeText: 'close',
+ draggable: true,
+ height: 'auto',
+ minHeight: 150,
+ minWidth: 150,
+ modal: false,
+ position: 'center',
+ resizable: true,
+ shadow: true,
+ stack: true,
+ title: '',
+ width: 300,
+ zIndex: 1000
+ },
+
+ getter: 'isOpen',
+
+ uuid: 0,
+
+ getTitleId: function($el) {
+ return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
+ },
+
+ overlay: function(dialog) {
+ this.$el = $.ui.dialog.overlay.create(dialog);
+ }
+});
+
+$.extend($.ui.dialog.overlay, {
+ instances: [],
+ events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
+ function(event) { return event + '.dialog-overlay'; }).join(' '),
+ create: function(dialog) {
+ if (this.instances.length === 0) {
+ // prevent use of anchors and inputs
+ // we use a setTimeout in case the overlay is created from an
+ // event that we're going to be cancelling (see #2804)
+ setTimeout(function() {
+ $('a, :input').bind($.ui.dialog.overlay.events, function() {
+ // allow use of the element if inside a dialog and
+ // - there are no modal dialogs
+ // - there are modal dialogs, but we are in front of the topmost modal
+ var allow = false;
+ var $dialog = $(this).parents('.ui-dialog');
+ if ($dialog.length) {
+ var $overlays = $('.ui-dialog-overlay');
+ if ($overlays.length) {
+ var maxZ = parseInt($overlays.css('z-index'), 10);
+ $overlays.each(function() {
+ maxZ = Math.max(maxZ, parseInt($(this).css('z-index'), 10));
+ });
+ allow = parseInt($dialog.css('z-index'), 10) > maxZ;
+ } else {
+ allow = true;
+ }
+ }
+ return allow;
+ });
+ }, 1);
+
+ // allow closing by pressing the escape key
+ $(document).bind('keydown.dialog-overlay', function(event) {
+ (dialog.options.closeOnEscape && event.keyCode
+ && event.keyCode == $.ui.keyCode.ESCAPE && dialog.close(event));
+ });
+
+ // handle window resize
+ $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
+ }
+
+ var $el = $('<div></div>').appendTo(document.body)
+ .addClass('ui-widget-overlay').css({
+ width: this.width(),
+ height: this.height()
+ });
+
+ (dialog.options.bgiframe && $.fn.bgiframe && $el.bgiframe());
+
+ this.instances.push($el);
+ return $el;
+ },
+
+ destroy: function($el) {
+ this.instances.splice($.inArray(this.instances, $el), 1);
+
+ if (this.instances.length === 0) {
+ $('a, :input').add([document, window]).unbind('.dialog-overlay');
+ }
+
+ $el.remove();
+ },
+
+ height: function() {
+ // handle IE 6
+ if ($.browser.msie && $.browser.version < 7) {
+ var scrollHeight = Math.max(
+ document.documentElement.scrollHeight,
+ document.body.scrollHeight
+ );
+ var offsetHeight = Math.max(
+ document.documentElement.offsetHeight,
+ document.body.offsetHeight
+ );
+
+ if (scrollHeight < offsetHeight) {
+ return $(window).height() + 'px';
+ } else {
+ return scrollHeight + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).height() + 'px';
+ }
+ },
+
+ width: function() {
+ // handle IE 6
+ if ($.browser.msie && $.browser.version < 7) {
+ var scrollWidth = Math.max(
+ document.documentElement.scrollWidth,
+ document.body.scrollWidth
+ );
+ var offsetWidth = Math.max(
+ document.documentElement.offsetWidth,
+ document.body.offsetWidth
+ );
+
+ if (scrollWidth < offsetWidth) {
+ return $(window).width() + 'px';
+ } else {
+ return scrollWidth + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).width() + 'px';
+ }
+ },
+
+ resize: function() {
+ /* If the dialog is draggable and the user drags it past the
+ * right edge of the window, the document becomes wider so we
+ * need to stretch the overlay. If the user then drags the
+ * dialog back to the left, the document will become narrower,
+ * so we need to shrink the overlay to the appropriate size.
+ * This is handled by shrinking the overlay before setting it
+ * to the full document size.
+ */
+ var $overlays = $([]);
+ $.each($.ui.dialog.overlay.instances, function() {
+ $overlays = $overlays.add(this);
+ });
+
+ $overlays.css({
+ width: 0,
+ height: 0
+ }).css({
+ width: $.ui.dialog.overlay.width(),
+ height: $.ui.dialog.overlay.height()
+ });
+ }
+});
+
+$.extend($.ui.dialog.overlay.prototype, {
+ destroy: function() {
+ $.ui.dialog.overlay.destroy(this.$el);
+ }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Effects 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+;(function($) {
+
+$.effects = $.effects || {}; //Add the 'effects' scope
+
+$.extend($.effects, {
+ version: "1.6rc6",
+
+ // Saves a set of properties in a data storage
+ save: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
+ }
+ },
+
+ // Restores a set of previously saved properties from a data storage
+ restore: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
+ }
+ },
+
+ setMode: function(el, mode) {
+ if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
+ return mode;
+ },
+
+ getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
+ // this should be a little more flexible in the future to handle a string & hash
+ var y, x;
+ switch (origin[0]) {
+ case 'top': y = 0; break;
+ case 'middle': y = 0.5; break;
+ case 'bottom': y = 1; break;
+ default: y = origin[0] / original.height;
+ };
+ switch (origin[1]) {
+ case 'left': x = 0; break;
+ case 'center': x = 0.5; break;
+ case 'right': x = 1; break;
+ default: x = origin[1] / original.width;
+ };
+ return {x: x, y: y};
+ },
+
+ // Wraps the element around a wrapper that copies position properties
+ createWrapper: function(element) {
+
+ //if the element is already wrapped, return it
+ if (element.parent().is('.ui-effects-wrapper'))
+ return element.parent();
+
+ //Cache width,height and float properties of the element, and create a wrapper around it
+ var props = { width: element.outerWidth(true), height: element.outerHeight(true), 'float': element.css('float') };
+ element.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');
+ var wrapper = element.parent();
+
+ //Transfer the positioning of the element to the wrapper
+ if (element.css('position') == 'static') {
+ wrapper.css({ position: 'relative' });
+ element.css({ position: 'relative'} );
+ } else {
+ var top = element.css('top'); if(isNaN(parseInt(top,10))) top = 'auto';
+ var left = element.css('left'); if(isNaN(parseInt(left,10))) left = 'auto';
+ wrapper.css({ position: element.css('position'), top: top, left: left, zIndex: element.css('z-index') }).show();
+ element.css({position: 'relative', top: 0, left: 0 });
+ }
+
+ wrapper.css(props);
+ return wrapper;
+ },
+
+ removeWrapper: function(element) {
+ if (element.parent().is('.ui-effects-wrapper'))
+ return element.parent().replaceWith(element);
+ return element;
+ },
+
+ setTransition: function(element, list, factor, value) {
+ value = value || {};
+ $.each(list, function(i, x){
+ unit = element.cssUnit(x);
+ if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
+ });
+ return value;
+ },
+
+ //Base function to animate from one class to another in a seamless transition
+ animateClass: function(value, duration, easing, callback) {
+
+ var cb = (typeof easing == "function" ? easing : (callback ? callback : null));
+ var ea = (typeof easing == "string" ? easing : null);
+
+ return this.each(function() {
+
+ var offset = {}; var that = $(this); var oldStyleAttr = that.attr("style") || '';
+ if(typeof oldStyleAttr == 'object') oldStyleAttr = oldStyleAttr["cssText"]; /* Stupidly in IE, style is a object.. */
+ if(value.toggle) { that.hasClass(value.toggle) ? value.remove = value.toggle : value.add = value.toggle; }
+
+ //Let's get a style offset
+ var oldStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
+ if(value.add) that.addClass(value.add); if(value.remove) that.removeClass(value.remove);
+ var newStyle = $.extend({}, (document.defaultView ? document.defaultView.getComputedStyle(this,null) : this.currentStyle));
+ if(value.add) that.removeClass(value.add); if(value.remove) that.addClass(value.remove);
+
+ // The main function to form the object for animation
+ for(var n in newStyle) {
+ if( typeof newStyle[n] != "function" && newStyle[n] /* No functions and null properties */
+ && n.indexOf("Moz") == -1 && n.indexOf("length") == -1 /* No mozilla spezific render properties. */
+ && newStyle[n] != oldStyle[n] /* Only values that have changed are used for the animation */
+ && (n.match(/color/i) || (!n.match(/color/i) && !isNaN(parseInt(newStyle[n],10)))) /* Only things that can be parsed to integers or colors */
+ && (oldStyle.position != "static" || (oldStyle.position == "static" && !n.match(/left|top|bottom|right/))) /* No need for positions when dealing with static positions */
+ ) offset[n] = newStyle[n];
+ }
+
+ that.animate(offset, duration, ea, function() { // Animate the newly constructed offset object
+ // Change style attribute back to original. For stupid IE, we need to clear the damn object.
+ if(typeof $(this).attr("style") == 'object') { $(this).attr("style")["cssText"] = ""; $(this).attr("style")["cssText"] = oldStyleAttr; } else $(this).attr("style", oldStyleAttr);
+ if(value.add) $(this).addClass(value.add); if(value.remove) $(this).removeClass(value.remove);
+ if(cb) cb.apply(this, arguments);
+ });
+
+ });
+ }
+});
+
+
+function _normalizeArguments(a, m) {
+
+ var o = a[1] && a[1].constructor == Object ? a[1] : {}; if(m) o.mode = m;
+ var speed = a[1] && a[1].constructor != Object ? a[1] : o.duration; //either comes from options.duration or the second argument
+ speed = $.fx.off ? 0 : typeof speed === "number" ? speed : $.fx.speeds[speed] || $.fx.speeds._default;
+ var callback = o.callback || ( $.isFunction(a[2]) && a[2] ) || ( $.isFunction(a[3]) && a[3] );
+
+ return [a[0], o, speed, callback];
+
+}
+
+//Extend the methods of jQuery
+$.fn.extend({
+
+ //Save old methods
+ _show: $.fn.show,
+ _hide: $.fn.hide,
+ __toggle: $.fn.toggle,
+ _addClass: $.fn.addClass,
+ _removeClass: $.fn.removeClass,
+ _toggleClass: $.fn.toggleClass,
+
+ // New effect methods
+ effect: function(fx, options, speed, callback) {
+ return $.effects[fx] ? $.effects[fx].call(this, {method: fx, options: options || {}, duration: speed, callback: callback }) : null;
+ },
+
+ show: function() {
+ if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
+ return this._show.apply(this, arguments);
+ else {
+ return this.effect.apply(this, _normalizeArguments(arguments, 'show'));
+ }
+ },
+
+ hide: function() {
+ if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])))
+ return this._hide.apply(this, arguments);
+ else {
+ return this.effect.apply(this, _normalizeArguments(arguments, 'hide'));
+ }
+ },
+
+ toggle: function(){
+ if(!arguments[0] || (arguments[0].constructor == Number || (/(slow|normal|fast)/).test(arguments[0])) || (arguments[0].constructor == Function))
+ return this.__toggle.apply(this, arguments);
+ else {
+ return this.effect.apply(this, _normalizeArguments(arguments, 'toggle'));
+ }
+ },
+
+ addClass: function(classNames, speed, easing, callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
+ },
+ removeClass: function(classNames,speed,easing,callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
+ },
+ toggleClass: function(classNames,speed,easing,callback) {
+ return ( (typeof speed !== "boolean") && speed ) ? $.effects.animateClass.apply(this, [{ toggle: classNames },speed,easing,callback]) : this._toggleClass(classNames, speed);
+ },
+ morph: function(remove,add,speed,easing,callback) {
+ return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
+ },
+ switchClass: function() {
+ return this.morph.apply(this, arguments);
+ },
+
+ // helper functions
+ cssUnit: function(key) {
+ var style = this.css(key), val = [];
+ $.each( ['em','px','%','pt'], function(i, unit){
+ if(style.indexOf(unit) > 0)
+ val = [parseFloat(style), unit];
+ });
+ return val;
+ }
+});
+
+/*
+ * jQuery Color Animations
+ * Copyright 2007 John Resig
+ * Released under the MIT and GPL licenses.
+ */
+
+// We override the animation for all of these color styles
+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function(i,attr){
+ $.fx.step[attr] = function(fx) {
+ if ( fx.state == 0 ) {
+ fx.start = getColor( fx.elem, attr );
+ fx.end = getRGB( fx.end );
+ }
+
+ fx.elem.style[attr] = "rgb(" + [
+ Math.max(Math.min( parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0],10), 255), 0),
+ Math.max(Math.min( parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1],10), 255), 0),
+ Math.max(Math.min( parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2],10), 255), 0)
+ ].join(",") + ")";
+ };
+});
+
+// Color Conversion functions from highlightFade
+// By Blair Mitchelmore
+// http://jquery.offput.ca/highlightFade/
+
+// Parse strings looking for color tuples [255,255,255]
+function getRGB(color) {
+ var result;
+
+ // Check if we're already dealing with an array of colors
+ if ( color && color.constructor == Array && color.length == 3 )
+ return color;
+
+ // Look for rgb(num,num,num)
+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
+ return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
+
+ // Look for rgb(num%,num%,num%)
+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
+ return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+
+ // Look for #a0b1c2
+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
+ return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+
+ // Look for #fff
+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
+ return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+
+ // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
+ return colors['transparent'];
+
+ // Otherwise, we're most likely dealing with a named color
+ return colors[$.trim(color).toLowerCase()];
+}
+
+function getColor(elem, attr) {
+ var color;
+
+ do {
+ color = $.curCSS(elem, attr);
+
+ // Keep going until we find an element that has color, or we hit the body
+ if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
+ break;
+
+ attr = "backgroundColor";
+ } while ( elem = elem.parentNode );
+
+ return getRGB(color);
+};
+
+// Some named colors to work with
+// From Interface by Stefan Petre
+// http://interface.eyecon.ro/
+
+var colors = {
+ aqua:[0,255,255],
+ azure:[240,255,255],
+ beige:[245,245,220],
+ black:[0,0,0],
+ blue:[0,0,255],
+ brown:[165,42,42],
+ cyan:[0,255,255],
+ darkblue:[0,0,139],
+ darkcyan:[0,139,139],
+ darkgrey:[169,169,169],
+ darkgreen:[0,100,0],
+ darkkhaki:[189,183,107],
+ darkmagenta:[139,0,139],
+ darkolivegreen:[85,107,47],
+ darkorange:[255,140,0],
+ darkorchid:[153,50,204],
+ darkred:[139,0,0],
+ darksalmon:[233,150,122],
+ darkviolet:[148,0,211],
+ fuchsia:[255,0,255],
+ gold:[255,215,0],
+ green:[0,128,0],
+ indigo:[75,0,130],
+ khaki:[240,230,140],
+ lightblue:[173,216,230],
+ lightcyan:[224,255,255],
+ lightgreen:[144,238,144],
+ lightgrey:[211,211,211],
+ lightpink:[255,182,193],
+ lightyellow:[255,255,224],
+ lime:[0,255,0],
+ magenta:[255,0,255],
+ maroon:[128,0,0],
+ navy:[0,0,128],
+ olive:[128,128,0],
+ orange:[255,165,0],
+ pink:[255,192,203],
+ purple:[128,0,128],
+ violet:[128,0,128],
+ red:[255,0,0],
+ silver:[192,192,192],
+ white:[255,255,255],
+ yellow:[255,255,0],
+ transparent: [255,255,255]
+};
+
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+$.easing.jswing = $.easing.swing;
+
+$.extend($.easing,
+{
+ def: 'easeOutQuad',
+ swing: function (x, t, b, c, d) {
+ //alert($.easing.default);
+ return $.easing[$.easing.def](x, t, b, c, d);
+ },
+ easeInQuad: function (x, t, b, c, d) {
+ return c*(t/=d)*t + b;
+ },
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c *(t/=d)*(t-2) + b;
+ },
+ easeInOutQuad: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t + b;
+ return -c/2 * ((--t)*(t-2) - 1) + b;
+ },
+ easeInCubic: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t + b;
+ },
+ easeOutCubic: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t + 1) + b;
+ },
+ easeInOutCubic: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
+ return c/2*((t-=2)*t*t + 2) + b;
+ },
+ easeInQuart: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t + b;
+ },
+ easeOutQuart: function (x, t, b, c, d) {
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
+ },
+ easeInOutQuart: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
+ },
+ easeInQuint: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t*t + b;
+ },
+ easeOutQuint: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
+ },
+ easeInOutQuint: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
+ },
+ easeInSine: function (x, t, b, c, d) {
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+ },
+ easeOutSine: function (x, t, b, c, d) {
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
+ },
+ easeInOutSine: function (x, t, b, c, d) {
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+ },
+ easeInExpo: function (x, t, b, c, d) {
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+ },
+ easeOutExpo: function (x, t, b, c, d) {
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+ },
+ easeInOutExpo: function (x, t, b, c, d) {
+ if (t==0) return b;
+ if (t==d) return b+c;
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+ },
+ easeInCirc: function (x, t, b, c, d) {
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+ },
+ easeOutCirc: function (x, t, b, c, d) {
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+ },
+ easeInOutCirc: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+ },
+ easeInElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ },
+ easeOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+ },
+ easeInOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+ },
+ easeInBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*(t/=d)*t*((s+1)*t - s) + b;
+ },
+ easeOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+ },
+ easeInOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+ },
+ easeInBounce: function (x, t, b, c, d) {
+ return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+ },
+ easeOutBounce: function (x, t, b, c, d) {
+ if ((t/=d) < (1/2.75)) {
+ return c*(7.5625*t*t) + b;
+ } else if (t < (2/2.75)) {
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+ } else if (t < (2.5/2.75)) {
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+ } else {
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+ }
+ },
+ easeInOutBounce: function (x, t, b, c, d) {
+ if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+ return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+ }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+})(jQuery);
+/*
+ * jQuery UI Effects Blind 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.blind = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'vertical') ? 'height' : 'width';
+ var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
+ if(mode == 'show') wrapper.css(ref, 0); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = mode == 'show' ? distance : 0;
+
+ // Animate
+ wrapper.animate(animation, o.duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Bounce 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.bounce = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'up'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 5; // Default # of times
+ var speed = o.duration || 250; // Default speed per bounce
+ if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+ if (mode == 'hide') distance = distance / (times * 2);
+ if (mode != 'hide') times--;
+
+ // Animate
+ if (mode == 'show') { // Show Bounce
+ var animation = {opacity: 1};
+ animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation, speed / 2, o.options.easing);
+ distance = distance / 2;
+ times--;
+ };
+ for (var i = 0; i < times; i++) { // Bounces
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
+ distance = (mode == 'hide') ? distance * 2 : distance / 2;
+ };
+ if (mode == 'hide') { // Last Bounce
+ var animation = {opacity: 0};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ el.animate(animation, speed / 2, o.options.easing, function(){
+ el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ } else {
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ };
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Clip 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.clip = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left','height','width'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var animate = el[0].tagName == 'IMG' ? wrapper : el;
+ var ref = {
+ size: (direction == 'vertical') ? 'height' : 'width',
+ position: (direction == 'vertical') ? 'top' : 'left'
+ };
+ var distance = (direction == 'vertical') ? animate.height() : animate.width();
+ if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref.size] = mode == 'show' ? distance : 0;
+ animation[ref.position] = mode == 'show' ? 0 : distance / 2;
+
+ // Animate
+ animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Drop 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.drop = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left','opacity'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+
+ // Animation
+ var animation = {opacity: mode == 'show' ? 1 : 0};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Explode 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.explode = function(o) {
+
+ return this.queue(function() {
+
+ var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+ var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+
+ o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
+ var el = $(this).show().css('visibility', 'hidden');
+ var offset = el.offset();
+
+ //Substract the margins - not fixing the problem yet.
+ offset.top -= parseInt(el.css("marginTop")) || 0;
+ offset.left -= parseInt(el.css("marginLeft")) || 0;
+
+ var width = el.outerWidth(true);
+ var height = el.outerHeight(true);
+
+ for(var i=0;i<rows;i++) { // =
+ for(var j=0;j<cells;j++) { // ||
+ el
+ .clone()
+ .appendTo('body')
+ .wrap('<div></div>')
+ .css({
+ position: 'absolute',
+ visibility: 'visible',
+ left: -j*(width/cells),
+ top: -i*(height/rows)
+ })
+ .parent()
+ .addClass('ui-effects-explode')
+ .css({
+ position: 'absolute',
+ overflow: 'hidden',
+ width: width/cells,
+ height: height/rows,
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
+ opacity: o.options.mode == 'show' ? 0 : 1
+ }).animate({
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
+ opacity: o.options.mode == 'show' ? 1 : 0
+ }, o.duration || 500);
+ }
+ }
+
+ // Set a timeout, to call the callback approx. when the other animations have finished
+ setTimeout(function() {
+
+ o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
+ if(o.callback) o.callback.apply(el[0]); // Callback
+ el.dequeue();
+
+ $('div.ui-effects-explode').remove();
+
+ }, o.duration || 500);
+
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fold 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.fold = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var size = o.options.size || 15; // Default fold size
+ var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
+ var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var widthFirst = ((mode == 'show') != horizFirst);
+ var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
+ var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
+ var percent = /([0-9]+)%/.exec(size);
+ if(percent) size = parseInt(percent[1]) / 100 * distance[mode == 'hide' ? 0 : 1];
+ if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
+
+ // Animation
+ var animation1 = {}, animation2 = {};
+ animation1[ref[0]] = mode == 'show' ? distance[0] : size;
+ animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
+
+ // Animate
+ wrapper.animate(animation1, duration, o.options.easing)
+ .animate(animation2, duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Highlight 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.highlight = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['backgroundImage','backgroundColor','opacity'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+ var color = o.options.color || "#ffff99"; // Default highlight color
+ var oldColor = el.css("backgroundColor");
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ el.css({backgroundImage: 'none', backgroundColor: color}); // Shift
+
+ // Animation
+ var animation = {backgroundColor: oldColor };
+ if (mode == "hide") animation['opacity'] = 0;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == "hide") el.hide();
+ $.effects.restore(el, props);
+ if (mode == "show" && $.browser.msie) this.style.removeAttribute('filter');
+ if(o.callback) o.callback.apply(this, arguments);
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Pulsate 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.pulsate = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+ var times = o.options.times || 5; // Default # of times
+ var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
+
+ // Adjust
+ if (mode == 'hide') times--;
+ if (el.is(':hidden')) { // Show fadeIn
+ el.css('opacity', 0);
+ el.show(); // Show
+ el.animate({opacity: 1}, duration, o.options.easing);
+ times = times-2;
+ }
+
+ // Animate
+ for (var i = 0; i < times; i++) { // Pulsate
+ el.animate({opacity: 0}, duration, o.options.easing).animate({opacity: 1}, duration, o.options.easing);
+ };
+ if (mode == 'hide') { // Last Pulse
+ el.animate({opacity: 0}, duration, o.options.easing, function(){
+ el.hide(); // Hide
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ } else {
+ el.animate({opacity: 0}, duration, o.options.easing).animate({opacity: 1}, duration, o.options.easing, function(){
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ };
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Scale 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.puff = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var options = $.extend(true, {}, o.options);
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var percent = parseInt(o.options.percent) || 150; // Set default puff percent
+ options.fade = true; // It's not a puff if it doesn't fade! :)
+ var original = {height: el.height(), width: el.width()}; // Save original
+
+ // Adjust
+ var factor = percent / 100;
+ el.from = (mode == 'hide') ? original : {height: original.height * factor, width: original.width * factor};
+
+ // Animation
+ options.from = el.from;
+ options.percent = (mode == 'hide') ? percent : 100;
+ options.mode = mode;
+
+ // Animate
+ el.effect('scale', options, o.duration, o.callback);
+ el.dequeue();
+ });
+
+};
+
+$.effects.scale = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var options = $.extend(true, {}, o.options);
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var percent = parseInt(o.options.percent) || (parseInt(o.options.percent) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
+ var direction = o.options.direction || 'both'; // Set default axis
+ var origin = o.options.origin; // The origin of the scaling
+ if (mode != 'effect') { // Set default origin and restore for show/hide
+ options.origin = origin || ['middle','center'];
+ options.restore = true;
+ }
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
+
+ // Adjust
+ var factor = { // Set scaling factor
+ y: direction != 'horizontal' ? (percent / 100) : 1,
+ x: direction != 'vertical' ? (percent / 100) : 1
+ };
+ el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
+
+ if (o.options.fade) { // Fade option to support puff
+ if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
+ if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
+ };
+
+ // Animation
+ options.from = el.from; options.to = el.to; options.mode = mode;
+
+ // Animate
+ el.effect('size', options, o.duration, o.callback);
+ el.dequeue();
+ });
+
+};
+
+$.effects.size = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left','width','height','overflow','opacity'];
+ var props1 = ['position','top','left','overflow','opacity']; // Always restore
+ var props2 = ['width','height','overflow']; // Copy for children
+ var cProps = ['fontSize'];
+ var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
+ var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var restore = o.options.restore || false; // Default restore
+ var scale = o.options.scale || 'both'; // Default scale mode
+ var origin = o.options.origin; // The origin of the sizing
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || original; // Default from state
+ el.to = o.options.to || original; // Default to state
+ // Adjust
+ if (origin) { // Calculate baseline shifts
+ var baseline = $.effects.getBaseline(origin, original);
+ el.from.top = (original.height - el.from.height) * baseline.y;
+ el.from.left = (original.width - el.from.width) * baseline.x;
+ el.to.top = (original.height - el.to.height) * baseline.y;
+ el.to.left = (original.width - el.to.width) * baseline.x;
+ };
+ var factor = { // Set scaling factor
+ from: {y: el.from.height / original.height, x: el.from.width / original.width},
+ to: {y: el.to.height / original.height, x: el.to.width / original.width}
+ };
+ if (scale == 'box' || scale == 'both') { // Scale the css box
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(vProps);
+ el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ props = props.concat(hProps);
+ el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
+ el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
+ };
+ };
+ if (scale == 'content' || scale == 'both') { // Scale the content
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(cProps);
+ el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
+ };
+ };
+ $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ el.css('overflow','hidden').css(el.from); // Shift
+
+ // Animate
+ if (scale == 'content' || scale == 'both') { // Scale the children
+ vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
+ hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
+ props2 = props.concat(vProps).concat(hProps); // Concat
+ el.find("*[width]").each(function(){
+ child = $(this);
+ if (restore) $.effects.save(child, props2);
+ var c_original = {height: child.height(), width: child.width()}; // Save original
+ child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
+ child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
+ child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
+ child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
+ };
+ child.css(child.from); // Shift children
+ child.animate(child.to, o.duration, o.options.easing, function(){
+ if (restore) $.effects.restore(child, props2); // Restore children
+ }); // Animate children
+ });
+ };
+
+ // Animate
+ el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Shake 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.shake = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 3; // Default # of times
+ var speed = o.duration || o.options.duration || 140; // Default speed per shake
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+
+ // Animation
+ var animation = {}, animation1 = {}, animation2 = {};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
+ animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
+
+ // Animate
+ el.animate(animation, speed, o.options.easing);
+ for (var i = 1; i < times; i++) { // Shakes
+ el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
+ };
+ el.animate(animation1, speed, o.options.easing).
+ animate(animation, speed / 2, o.options.easing, function(){ // Last shake
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Slide 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.slide = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','left'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
+ if (mode == 'show') el.css(ref, motion == 'pos' ? -distance : distance); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Transfer 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function($) {
+
+$.effects.transfer = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var target = $(o.options.to); // Find Target
+ var position = el.offset();
+ var transfer = $('<div class="ui-effects-transfer"></div>').appendTo(document.body);
+ if(o.options.className) transfer.addClass(o.options.className);
+
+ // Set target css
+ transfer.addClass(o.options.className);
+ transfer.css({
+ top: position.top,
+ left: position.left,
+ height: el.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')),
+ width: el.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth')),
+ position: 'absolute'
+ });
+
+ // Animation
+ position = target.offset();
+ animation = {
+ top: position.top,
+ left: position.left,
+ height: target.outerHeight() - parseInt(transfer.css('borderTopWidth')) - parseInt(transfer.css('borderBottomWidth')),
+ width: target.outerWidth() - parseInt(transfer.css('borderLeftWidth')) - parseInt(transfer.css('borderRightWidth'))
+ };
+
+ // Animate
+ transfer.animate(animation, o.duration, o.options.easing, function() {
+ transfer.remove(); // Remove div
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
diff --git a/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.min.js b/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.min.js
new file mode 100644
index 0000000..2d97bb8
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/scripts/jquery-ui-personalized-1.6rc6.min.js
@@ -0,0 +1,184 @@
+/*
+ * jQuery UI 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */ (function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.6rc6",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},cssCache:{},css:function(j){if(c.ui.cssCache[j]){return c.ui.cssCache[j]}var k=c('<div class="ui-gen"></div>').addClass(j).css({position:"absolute",top:"-5000px",left:"-5000px",display:"block"}).appendTo("body");c.ui.cssCache[j]=!!((!(/auto|default/).test(k.css("cursor"))||(/^[1-9]/).test(k.css("height"))||(/^[1-9]/).test(k.css("width"))||!(/none/).test(k.css("backgroundImage"))||!(/transparent|rgba\(0, 0, 0, 0\)/).test(k.css("backgroundColor"))));try{c("body").get(0).removeChild(k.get(0))}catch(l){}return c.ui.cssCache[j]},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=true;this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/*
+ * jQuery UI Draggable 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * ui.core.js
+ */ (function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.cssNamespace&&this.element.addClass(this.options.cssNamespace+"-draggable"));(this.options.disabled&&this.element.addClass(this.options.cssNamespace+"-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass(this.options.cssNamespace+"-draggable "+this.options.cssNamespace+"-draggable-dragging "+this.options.cssNamespace+"-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is("."+this.options.cssNamespace+"-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass(c.cssNamespace+"-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body&&a.browser.mozilla)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c)}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop()))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft()))}},_clear:function(){this.helper.removeClass(this.options.cssNamespace+"-draggable-dragging");if(this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},_trigger:function(b,c,d){d=d||this._uiHash();a.ui.plugin.call(this,b,[c,d]);if(b=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return a.widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(b){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,offset:this.positionAbs}}}));a.extend(a.ui.draggable,{version:"1.6rc6",eventPrefix:"drag",defaults:{appendTo:"parent",axis:false,cancel:":input,option",connectToSortable:false,containment:false,cssNamespace:"ui",cursor:"default",cursorAt:false,delay:0,distance:1,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false}});a.ui.plugin.add("draggable","connectToSortable",{start:function(b,d){var c=a(this).data("draggable"),e=c.options;c.sortables=[];a(e.connectToSortable).each(function(){a(typeof this=="string"?this+"":this).each(function(){if(a.data(this,"sortable")){var f=a.data(this,"sortable");c.sortables.push({instance:f,shouldRevert:f.options.revert});f._refreshItems();f._trigger("activate",b,c)}})})},stop:function(b,d){var c=a(this).data("draggable");a.each(c.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;c.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(b);this.instance.options.helper=this.instance.options._helper;if(c.options.helper=="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",b,c)}})},drag:function(c,f){var e=a(this).data("draggable"),b=this;var d=function(i){var n=this.offset.click.top,m=this.offset.click.left;var g=this.positionAbs.top,k=this.positionAbs.left;var j=i.height,l=i.width;var p=i.top,h=i.left;return a.ui.isOver(g+n,k+m,p,h,j,l)};a.each(e.sortables,function(g){if(d.call(e,this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(b).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return f.helper[0]};c.target=this.instance.currentItem[0];this.instance._mouseCapture(c,true);this.instance._mouseStart(c,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;e._trigger("toSortable",c);e.dropped=this.instance.element;this.instance.fromOutside=e}if(this.instance.currentItem){this.instance._mouseDrag(c)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._mouseStop(c,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}e._trigger("fromSortable",c);e.dropped=false}}})}});a.ui.plugin.add("draggable","cursor",{start:function(c,d){var b=a("body"),e=a(this).data("draggable").options;if(b.css("cursor")){e._cursor=b.css("cursor")}b.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._cursor){a("body").css("cursor",d._cursor)}}});a.ui.plugin.add("draggable","iframeFix",{start:function(b,c){var d=a(this).data("draggable").options;a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop+f.scrollSpeed}else{if(d.pageY-c.overflowOffset.top<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop-f.scrollSpeed}}}if(!f.axis||f.axis!="y"){if((c.overflowOffset.left+c.scrollParent[0].offsetWidth)-d.pageX<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft+f.scrollSpeed}else{if(d.pageX-c.overflowOffset.left<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft-f.scrollSpeed}}}}else{if(!f.axis||f.axis!="x"){if(d.pageY-a(document).scrollTop()<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-f.scrollSpeed)}else{if(a(window).height()-(d.pageY-a(document).scrollTop())<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+f.scrollSpeed)}}}if(!f.axis||f.axis!="y"){if(d.pageX-a(document).scrollLeft()<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-f.scrollSpeed)}else{if(a(window).width()-(d.pageX-a(document).scrollLeft())<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+f.scrollSpeed)}}}}if(b!==false&&a.ui.ddmanager&&!f.dropBehaviour){a.ui.ddmanager.prepareOffsets(c,d)}}});a.ui.plugin.add("draggable","snap",{start:function(c,d){var b=a(this).data("draggable"),e=b.options;b.snapElements=[];a(e.snap.constructor!=String?(e.snap.items||":data(draggable)"):e.snap).each(function(){var g=a(this);var f=g.offset();if(this!=b.element[0]){b.snapElements.push({item:this,width:g.outerWidth(),height:g.outerHeight(),top:f.top,left:f.left})}})},drag:function(u,p){var g=a(this).data("draggable"),q=g.options;var y=q.snapTolerance;var x=p.absolutePosition.left,w=x+g.helperProportions.width,f=p.absolutePosition.top,e=f+g.helperProportions.height;for(var v=g.snapElements.length-1;v>=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y<x&&x<n+y&&m-y<f&&f<A+y)||(s-y<x&&x<n+y&&m-y<e&&e<A+y)||(s-y<w&&w<n+y&&m-y<f&&f<A+y)||(s-y<w&&w<n+y&&m-y<e&&e<A+y))){if(g.snapElements[v].snapping){(g.options.snap.release&&g.options.snap.release.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=false;continue}if(q.snapMode!="inner"){var c=Math.abs(m-e)<=y;var z=Math.abs(A-f)<=y;var j=Math.abs(s-w)<=y;var k=Math.abs(n-x)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m-g.helperProportions.height,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s-g.helperProportions.width}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n}).left-g.margins.left}}var h=(c||z||j||k);if(q.snapMode!="outer"){var c=Math.abs(m-f)<=y;var z=Math.abs(A-e)<=y;var j=Math.abs(s-x)<=y;var k=Math.abs(n-w)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A-g.helperProportions.height,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n-g.helperProportions.width}).left-g.margins.left}}if(!g.snapElements[v].snapping&&(c||z||j||k||h)){(g.options.snap.snap&&g.options.snap.snap.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=(c||z||j||k||h)}}});a.ui.plugin.add("draggable","stack",{start:function(b,c){var e=a(this).data("draggable").options;var d=a.makeArray(a(e.stack.group)).sort(function(g,f){return(parseInt(a(g).css("zIndex"),10)||e.stack.min)-(parseInt(a(f).css("zIndex"),10)||e.stack.min)});a(d).each(function(f){this.style.zIndex=e.stack.min+f});this[0].style.zIndex=e.stack.min+d.length}});a.ui.plugin.add("draggable","zIndex",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("zIndex")){e._zIndex=b.css("zIndex")}b.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._zIndex){a(c.helper).css("zIndex",d._zIndex)}}})})(jQuery);;/*
+ * jQuery UI Resizable 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * ui.core.js
+ */ (function(b){b.widget("ui.resizable",b.extend({},b.ui.mouse,{_init:function(){var d=this,h=this.options;this.element.addClass("ui-resizable");b.extend(this,{_aspectRatio:!!(h.aspectRatio),aspectRatio:h.aspectRatio,originalElement:this.element,proportionallyResize:h.proportionallyResize?[h.proportionallyResize]:[],_helper:h.helper||h.ghost||h.animate?h.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&b.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(b('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent();this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});if(b.browser.safari&&h.preventDefault){this.originalElement.css("resize","none")}this.proportionallyResize.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=h.handles||(!b(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var j=this.handles.split(",");this.handles={};for(var e=0;e<j.length;e++){var g=b.trim(j[e]),c="ui-resizable-"+g;var f=b('<div class="ui-resizable-handle '+c+'"></div>');if(/sw|se|ne|nw/.test(g)){f.css({zIndex:++h.zIndex})}if("se"==g){f.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[g]=".ui-resizable-"+g;this.element.append(f)}}this._renderAxis=function(o){o=o||this.element;for(var l in this.handles){if(this.handles[l].constructor==String){this.handles[l]=b(this.handles[l],this.element).show()}if(h.transparent){this.handles[l].css({opacity:0})}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var m=b(this.handles[l],this.element),n=0;n=/sw|ne|nw|se|n|s/.test(l)?m.outerHeight():m.outerWidth();var k=["padding",/ne|nw|n/.test(l)?"Top":/se|sw|s/.test(l)?"Bottom":/^e$/.test(l)?"Right":"Left"].join("");if(!h.transparent){o.css(k,n)}this._proportionallyResize()}if(!b(this.handles[l]).length){continue}}};this._renderAxis(this.element);this._handles=b(".ui-resizable-handle",this.element);if(h.disableSelection){this._handles.disableSelection()}this._handles.mouseover(function(){if(!d.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}d.axis=i&&i[1]?i[1]:"se"}});if(h.autoHide){this._handles.hide();b(this.element).addClass("ui-resizable-autohide").hover(function(){b(this).removeClass("ui-resizable-autohide");d._handles.show()},function(){if(!d.resizing){b(this).addClass("ui-resizable-autohide");d._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var c=function(d){b(d).removeClass("ui-resizable ui-resizable-disabled").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){c(this.element);this.wrapper.parent().append(this.originalElement.css({position:this.wrapper.css("position"),width:this.wrapper.outerWidth(),height:this.wrapper.outerHeight(),top:this.wrapper.css("top"),left:this.wrapper.css("left")})).end().remove()}c(this.originalElement)},_mouseCapture:function(d){var e=false;for(var c in this.handles){if(b(this.handles[c])[0]==d.target){e=true}}return this.options.disabled||!!e},_mouseStart:function(e){var h=this.options,d=this.element.position(),c=this.element;this.resizing=true;this.documentScroll={top:b(document).scrollTop(),left:b(document).scrollLeft()};if(c.is(".ui-draggable")||(/absolute/).test(c.css("position"))){c.css({position:"absolute",top:d.top,left:d.left})}if(b.browser.opera&&(/relative/).test(c.css("position"))){c.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var i=a(this.helper.css("left")),f=a(this.helper.css("top"));if(h.containment){i+=b(h.containment).scrollLeft()||0;f+=b(h.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:i,top:f};this.size=this._helper?{width:c.outerWidth(),height:c.outerHeight()}:{width:c.width(),height:c.height()};this.originalSize=this._helper?{width:c.outerWidth(),height:c.outerHeight()}:{width:c.width(),height:c.height()};this.originalPosition={left:i,top:f};this.sizeDiff={width:c.outerWidth()-c.width(),height:c.outerHeight()-c.height()};this.originalMousePosition={left:e.pageX,top:e.pageY};this.aspectRatio=(typeof h.aspectRatio=="number")?h.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);if(h.preserveCursor){var g=b(".ui-resizable-"+this.axis).css("cursor");b("body").css("cursor",g=="auto"?this.axis+"-resize":g)}this._propagate("start",e);return true},_mouseDrag:function(c){var f=this.helper,e=this.options,k={},n=this,h=this.originalMousePosition,l=this.axis;var p=(c.pageX-h.left)||0,m=(c.pageY-h.top)||0;var g=this._change[l];if(!g){return false}var j=g.apply(this,[c,p,m]),i=b.browser.msie&&b.browser.version<7,d=this.sizeDiff;if(this._aspectRatio||c.shiftKey){j=this._updateRatio(j,c)}j=this._respectSize(j,c);this._propagate("resize",c);f.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this.proportionallyResize.length){this._proportionallyResize()}this._updateCache(j);this._trigger("resize",c,this.ui());return false},_mouseStop:function(f){this.resizing=false;var g=this.options,k=this;if(this._helper){var e=this.proportionallyResize,c=e.length&&(/textarea/i).test(e[0].nodeName),d=c&&b.ui.hasScroll(e[0],"left")?0:k.sizeDiff.height,i=c?0:k.sizeDiff.width;var l={width:(k.size.width-i),height:(k.size.height-d)},h=(parseInt(k.element.css("left"),10)+(k.position.left-k.originalPosition.left))||null,j=(parseInt(k.element.css("top"),10)+(k.position.top-k.originalPosition.top))||null;if(!g.animate){this.element.css(b.extend(l,{top:j,left:h}))}if(this._helper&&!g.animate){this._proportionallyResize()}}if(g.preserveCursor){b("body").css("cursor","auto")}this._propagate("stop",f);if(this._helper){this.helper.remove()}return false},_updateCache:function(c){var d=this.options;this.offset=this.helper.offset();if(c.left){this.position.left=c.left}if(c.top){this.position.top=c.top}if(c.height){this.size.height=c.height}if(c.width){this.size.width=c.width}},_updateRatio:function(f,e){var g=this.options,h=this.position,d=this.size,c=this.axis;if(f.height){f.width=(d.height*this.aspectRatio)}else{if(f.width){f.height=(d.width/this.aspectRatio)}}if(c=="sw"){f.left=h.left+(d.width-f.width);f.top=null}if(c=="nw"){f.top=h.top+(d.height-f.height);f.left=h.left+(d.width-f.width)}return f},_respectSize:function(j,e){var r=function(o){return !isNaN(parseInt(o,10))};var h=this.helper,g=this.options,p=this._aspectRatio||e.shiftKey,n=this.axis,s=r(j.width)&&g.maxWidth&&(g.maxWidth<j.width),k=r(j.height)&&g.maxHeight&&(g.maxHeight<j.height),f=r(j.width)&&g.minWidth&&(g.minWidth>j.width),q=r(j.height)&&g.minHeight&&(g.minHeight>j.height);if(f){j.width=g.minWidth}if(q){j.height=g.minHeight}if(s){j.width=g.maxWidth}if(k){j.height=g.maxHeight}var d=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height;var i=/sw|nw|w/.test(n),c=/nw|ne|n/.test(n);if(f&&i){j.left=d-g.minWidth}if(s&&i){j.left=d-g.maxWidth}if(q&&c){j.top=m-g.minHeight}if(k&&c){j.top=m-g.maxHeight}var l=!j.width&&!j.height;if(l&&!j.left&&j.top){j.top=null}else{if(l&&!j.top&&j.left){j.left=null}}return j},_proportionallyResize:function(){var h=this.options;if(!this.proportionallyResize.length){return}var e=this.helper||this.element;for(var d=0;d<this.proportionallyResize.length;d++){var f=this.proportionallyResize[d];if(!this.borderDif){var c=[f.css("borderTopWidth"),f.css("borderRightWidth"),f.css("borderBottomWidth"),f.css("borderLeftWidth")],g=[f.css("paddingTop"),f.css("paddingRight"),f.css("paddingBottom"),f.css("paddingLeft")];this.borderDif=b.map(c,function(j,l){var k=parseInt(j,10)||0,m=parseInt(g[l],10)||0;return k+m})}if(b.browser.msie&&!(!(b(e).is(":hidden")||b(e).parents(":hidden").length))){continue}f.css({height:(e.height()-this.borderDif[0]-this.borderDif[2])||0,width:(e.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var d=this.element,g=this.options;this.elementOffset=d.offset();if(this._helper){this.helper=this.helper||b('<div style="overflow:hidden;"></div>');var c=b.browser.msie&&b.browser.version<7,e=(c?1:0),f=(c?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++g.zIndex});this.helper.appendTo("body");if(g.disableSelection){this.helper.disableSelection()}}else{this.helper=this.element}},_change:{e:function(e,d,c){return{width:this.originalSize.width+d}},w:function(f,d,c){var h=this.options,e=this.originalSize,g=this.originalPosition;return{left:g.left+d,width:e.width-d}},n:function(f,d,c){var h=this.options,e=this.originalSize,g=this.originalPosition;return{top:g.top+c,height:e.height-c}},s:function(e,d,c){return{height:this.originalSize.height+c}},se:function(e,d,c){return b.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,d,c]))},sw:function(e,d,c){return b.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,d,c]))},ne:function(e,d,c){return b.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,d,c]))},nw:function(e,d,c){return b.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,d,c]))}},_propagate:function(d,c){b.ui.plugin.call(this,d,[c,this.ui()]);(d!="resize"&&this._trigger(d,c,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));b.extend(b.ui.resizable,{version:"1.6rc6",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,disableSelection:true,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,preserveCursor:true,preventDefault:true,proportionallyResize:false,transparent:false,zIndex:1000}});b.ui.plugin.add("resizable","alsoResize",{start:function(d,e){var c=b(this).data("resizable"),f=c.options;_store=function(g){b(g).each(function(){b(this).data("resizable-alsoresize",{width:parseInt(b(this).width(),10),height:parseInt(b(this).height(),10),left:parseInt(b(this).css("left"),10),top:parseInt(b(this).css("top"),10)})})};if(typeof(f.alsoResize)=="object"&&!f.alsoResize.parentNode){if(f.alsoResize.length){f.alsoResize=f.alsoResize[0];_store(f.alsoResize)}else{b.each(f.alsoResize,function(g,h){_store(g)})}}else{_store(f.alsoResize)}},resize:function(e,g){var d=b(this).data("resizable"),h=d.options,f=d.originalSize,j=d.originalPosition;var i={height:(d.size.height-f.height)||0,width:(d.size.width-f.width)||0,top:(d.position.top-j.top)||0,left:(d.position.left-j.left)||0},c=function(k,l){b(k).each(function(){var o=b(this),p=b(this).data("resizable-alsoresize"),n={},m=l&&l.length?l:["width","height","top","left"];b.each(m||["width","height","top","left"],function(q,s){var r=(p[s]||0)+(i[s]||0);if(r&&r>=0){n[s]=r||null}});if(/relative/.test(o.css("position"))&&b.browser.opera){d._revertToRelativePosition=true;o.css({position:"absolute",top:"auto",left:"auto"})}o.css(n)})};if(typeof(h.alsoResize)=="object"&&!h.alsoResize.nodeType){b.each(h.alsoResize,function(k,l){c(k,l)})}else{c(h.alsoResize)}},stop:function(d,e){var c=b(this).data("resizable");if(c._revertToRelativePosition&&b.browser.opera){c._revertToRelativePosition=false;el.css({position:"relative"})}b(this).removeData("resizable-alsoresize-start")}});b.ui.plugin.add("resizable","animate",{stop:function(g,l){var m=b(this).data("resizable"),h=m.options;var f=h.proportionallyResize,c=f&&(/textarea/i).test(f.get(0).nodeName),d=c&&b.ui.hasScroll(f.get(0),"left")?0:m.sizeDiff.height,j=c?0:m.sizeDiff.width;var e={width:(m.size.width-j),height:(m.size.height-d)},i=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,k=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;m.element.animate(b.extend(e,k&&i?{top:k,left:i}:{}),{duration:h.animateDuration,easing:h.animateEasing,step:function(){var n={width:parseInt(m.element.css("width"),10),height:parseInt(m.element.css("height"),10),top:parseInt(m.element.css("top"),10),left:parseInt(m.element.css("left"),10)};if(f){f.css({width:n.width,height:n.height})}m._updateCache(n);m._propagate("resize",g)}})}});b.ui.plugin.add("resizable","containment",{start:function(d,n){var r=b(this).data("resizable"),h=r.options,j=r.element;var e=h.containment,i=(e instanceof b)?e.get(0):(/parent/.test(e))?j.parent().get(0):e;if(!i){return}r.containerElement=b(i);if(/document/.test(e)||e==document){r.containerOffset={left:0,top:0};r.containerPosition={left:0,top:0};r.parentData={element:b(document),left:0,top:0,width:b(document).width(),height:b(document).height()||document.body.parentNode.scrollHeight}}else{var l=b(i),g=[];b(["Top","Right","Left","Bottom"]).each(function(p,o){g[p]=a(l.css("padding"+o))});r.containerOffset=l.offset();r.containerPosition=l.position();r.containerSize={height:(l.innerHeight()-g[3]),width:(l.innerWidth()-g[1])};var m=r.containerOffset,c=r.containerSize.height,k=r.containerSize.width,f=(b.ui.hasScroll(i,"left")?i.scrollWidth:k),q=(b.ui.hasScroll(i)?i.scrollHeight:c);r.parentData={element:i,left:m.left,top:m.top,width:f,height:q}}},resize:function(e,l){var p=b(this).data("resizable"),g=p.options,d=p.containerSize,k=p.containerOffset,i=p.size,j=p.position,m=g._aspectRatio||e.shiftKey,c={top:0,left:0},f=p.containerElement;if(f[0]!=document&&(/static/).test(f.css("position"))){c=k}if(j.left<(p._helper?k.left:0)){p.size.width=p.size.width+(p._helper?(p.position.left-k.left):(p.position.left-c.left));if(m){p.size.height=p.size.width/g.aspectRatio}p.position.left=g.helper?k.left:0}if(j.top<(p._helper?k.top:0)){p.size.height=p.size.height+(p._helper?(p.position.top-k.top):p.position.top);if(m){p.size.width=p.size.height*g.aspectRatio}p.position.top=p._helper?k.top:0}var h=Math.abs((p._helper?p.offset.left-c.left:(p.offset.left-c.left))+p.sizeDiff.width),n=Math.abs((p._helper?p.offset.top-c.top:(p.offset.top-k.top))+p.sizeDiff.height);if(h+p.size.width>=p.parentData.width){p.size.width=p.parentData.width-h;if(m){p.size.height=p.size.width/g.aspectRatio}}if(n+p.size.height>=p.parentData.height){p.size.height=p.parentData.height-n;if(m){p.size.width=p.size.height*g.aspectRatio}}},stop:function(d,l){var n=b(this).data("resizable"),e=n.options,j=n.position,k=n.containerOffset,c=n.containerPosition,f=n.containerElement;var g=b(n.helper),p=g.offset(),m=g.outerWidth()-n.sizeDiff.width,i=g.outerHeight()-n.sizeDiff.height;if(n._helper&&!e.animate&&(/relative/).test(f.css("position"))){b(this).css({left:p.left-c.left-k.left,width:m,height:i})}if(n._helper&&!e.animate&&(/static/).test(f.css("position"))){b(this).css({left:p.left-c.left-k.left,width:m,height:i})}}});b.ui.plugin.add("resizable","ghost",{start:function(e,f){var c=b(this).data("resizable"),g=c.options,h=g.proportionallyResize,d=c.size;c.ghost=c.originalElement.clone();c.ghost.css({opacity:0.25,display:"block",position:"relative",height:d.height,width:d.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof g.ghost=="string"?g.ghost:"");c.ghost.appendTo(c.helper)},resize:function(d,e){var c=b(this).data("resizable"),f=c.options;if(c.ghost){c.ghost.css({position:"relative",height:c.size.height,width:c.size.width})}},stop:function(d,e){var c=b(this).data("resizable"),f=c.options;if(c.ghost&&c.helper){c.helper.get(0).removeChild(c.ghost.get(0))}}});b.ui.plugin.add("resizable","grid",{resize:function(c,k){var m=b(this).data("resizable"),f=m.options,i=m.size,g=m.originalSize,h=m.originalPosition,l=m.axis,j=f._aspectRatio||c.shiftKey;f.grid=typeof f.grid=="number"?[f.grid,f.grid]:f.grid;var e=Math.round((i.width-g.width)/(f.grid[0]||1))*(f.grid[0]||1),d=Math.round((i.height-g.height)/(f.grid[1]||1))*(f.grid[1]||1);if(/^(se|s|e)$/.test(l)){m.size.width=g.width+e;m.size.height=g.height+d}else{if(/^(ne)$/.test(l)){m.size.width=g.width+e;m.size.height=g.height+d;m.position.top=h.top-d}else{if(/^(sw)$/.test(l)){m.size.width=g.width+e;m.size.height=g.height+d;m.position.left=h.left-e}else{m.size.width=g.width+e;m.size.height=g.height+d;m.position.top=h.top-d;m.position.left=h.left-e}}}}});var a=function(c){return parseInt(c,10)||0}})(jQuery);;/*
+ * jQuery UI Dialog 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * ui.core.js
+ * ui.draggable.js
+ * ui.resizable.js
+ */ (function(b){var a={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"};b.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");var k=this,l=this.options,i=l.title||this.originalTitle||"&nbsp;",d=b.ui.dialog.getTitleId(this.element),j=(this.uiDialog=b("<div/>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+l.dialogClass).css({position:"absolute",overflow:"hidden",zIndex:l.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(m){(l.closeOnEscape&&m.keyCode&&m.keyCode==b.ui.keyCode.ESCAPE&&k.close(m))}).attr({role:"dialog","aria-labelledby":d}).mousedown(function(m){k.moveToTop(m)}),f=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(j),e=(this.uiDialogTitlebar=b("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(j),h=b('<a href="#"/>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).mousedown(function(m){m.stopPropagation()}).click(function(m){k.close(m);return false}).appendTo(e),g=(this.uiDialogTitlebarCloseText=b("<span/>")).addClass("ui-icon ui-icon-closethick").text(l.closeText).appendTo(h),c=b("<span/>").addClass("ui-dialog-title").attr("id",d).html(i).prependTo(e);e.find("*").add(e).disableSelection();(l.draggable&&b.fn.draggable&&this._makeDraggable());(l.resizable&&b.fn.resizable&&this._makeResizable());this._createButtons(l.buttons);this._isOpen=false;(l.bgiframe&&b.fn.bgiframe&&j.bgiframe());(l.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());(this.shadow&&this._destroyShadow());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(c){if(false===this._trigger("beforeclose",c)){return}(this.overlay&&this.overlay.destroy());(this.shadow&&this._destroyShadow());this.uiDialog.hide(this.options.hide).unbind("keypress.ui-dialog");this._trigger("close",c);b.ui.dialog.overlay.resize();this._isOpen=false},isOpen:function(){return this._isOpen},moveToTop:function(g,f){if((this.options.modal&&!g)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",f)}var e=this.options.zIndex,d=this.options;b(".ui-dialog:visible").each(function(){e=Math.max(e,parseInt(b(this).css("z-index"),10)||d.zIndex)});(this.overlay&&this.overlay.$el.css("z-index",++e));(this.shadow&&this.shadow.css("z-index",++e));var c={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++e);this.element.attr(c);this._trigger("focus",f)},open:function(e){if(this._isOpen){return}var d=this.options,c=this.uiDialog;this.overlay=d.modal?new b.ui.dialog.overlay(this):null;(c.next().length&&c.appendTo("body"));this._size();this._position(d.position);c.show(d.show);this.moveToTop(true,e);(d.modal&&c.bind("keypress.ui-dialog",function(h){if(h.keyCode!=b.ui.keyCode.TAB){return}var g=b(":tabbable",this),i=g.filter(":first")[0],f=g.filter(":last")[0];if(h.target==f&&!h.shiftKey){setTimeout(function(){i.focus()},1)}else{if(h.target==i&&h.shiftKey){setTimeout(function(){f.focus()},1)}}}));b([]).add(c.find(".ui-dialog-content :tabbable:first")).add(c.find(".ui-dialog-buttonpane :tabbable:first")).add(c.find(".ui-dialog-titlebar :tabbable:first")).filter(":first").focus();if(d.shadow){this._createShadow()}this._trigger("open",e);this._isOpen=true},_createButtons:function(f){var e=this,c=false,d=b("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");this.uiDialog.find(".ui-dialog-buttonpane").remove();(typeof f=="object"&&f!==null&&b.each(f,function(){return !(c=true)}));if(c){b.each(f,function(g,h){b('<button type="button"></button>').addClass("ui-state-default ui-corner-all").text(g).click(function(){h.apply(e.element[0],arguments)}).hover(function(){b(this).addClass("ui-state-hover")},function(){b(this).removeClass("ui-state-hover")}).focus(function(){b(this).addClass("ui-state-focus")}).blur(function(){b(this).removeClass("ui-state-focus")}).appendTo(d)});d.appendTo(this.uiDialog)}},_makeDraggable:function(){var c=this,d=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content",helper:d.dragHelper,handle:".ui-dialog-titlebar",containment:"document",start:function(){(d.dragStart&&d.dragStart.apply(c.element[0],arguments));if(b.browser.msie&&b.browser.version<7&&c.shadow){c.shadow.hide()}},drag:function(){(d.drag&&d.drag.apply(c.element[0],arguments));c._refreshShadow(1)},stop:function(){(d.dragStop&&d.dragStop.apply(c.element[0],arguments));b.ui.dialog.overlay.resize();if(b.browser.msie&&b.browser.version<7&&c.shadow){c.shadow.show()}c._refreshShadow()}})},_makeResizable:function(f){f=(f===undefined?this.options.resizable:f);var c=this,e=this.options,d=typeof f=="string"?f:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",alsoResize:this.element,helper:e.resizeHelper,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:e.minHeight,start:function(){(e.resizeStart&&e.resizeStart.apply(c.element[0],arguments));if(b.browser.msie&&b.browser.version<7&&c.shadow){c.shadow.hide()}},resize:function(){(e.resize&&e.resize.apply(c.element[0],arguments));c._refreshShadow(1)},handles:d,stop:function(){(e.resizeStop&&e.resizeStop.apply(c.element[0],arguments));b.ui.dialog.overlay.resize();if(b.browser.msie&&b.browser.version<7&&c.shadow){c.shadow.show()}c._refreshShadow()}}).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_position:function(h){var d=b(window),e=b(document),f=e.scrollTop(),c=e.scrollLeft(),g=f;if(b.inArray(h,["center","top","right","bottom","left"])>=0){h=[h=="right"||h=="left"?h:"center",h=="top"||h=="bottom"?h:"middle"]}if(h.constructor!=Array){h=["center","middle"]}if(h[0].constructor==Number){c+=h[0]}else{switch(h[0]){case"left":c+=0;break;case"right":c+=d.width()-this.uiDialog.outerWidth();break;default:case"center":c+=(d.width()-this.uiDialog.outerWidth())/2}}if(h[1].constructor==Number){f+=h[1]}else{switch(h[1]){case"top":f+=0;break;case"bottom":f+=d.height()-this.uiDialog.outerHeight();break;default:case"middle":f+=(d.height()-this.uiDialog.outerHeight())/2}}f=Math.max(f,g);this.uiDialog.css({top:f,left:c})},_setData:function(d,e){(a[d]&&this.uiDialog.data(a[d],e));switch(d){case"buttons":this._createButtons(e);break;case"closeText":this.uiDialogTitlebarCloseText.text(e);break;case"draggable":(e?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(e);break;case"position":this._position(e);break;case"resizable":var c=this.uiDialog,f=this.uiDialog.is(":data(resizable)");(f&&!e&&c.resizable("destroy"));(f&&typeof e=="string"&&c.resizable("option","handles",e));(f||this._makeResizable(e));break;case"title":b(".ui-dialog-title",this.uiDialogTitlebar).html(e||"&nbsp;");break;case"width":this.uiDialog.width(e);break}b.widget.prototype._setData.apply(this,arguments)},_size:function(){var d=this.options;this.element.css({height:0,minHeight:0,width:"auto"});var c=this.uiDialog.css({height:"auto",width:d.width}).height();this.element.css({minHeight:Math.max(d.minHeight-c,0),height:d.height=="auto"?"auto":d.height-c})},_createShadow:function(){this.shadow=b('<div class="ui-widget-shadow"></div>').css("position","absolute").appendTo(document.body);this._refreshShadow();return this.shadow},_refreshShadow:function(c){if(c&&b.browser.msie&&b.browser.version<7){return}var d=this.uiDialog.offset();this.shadow.css({left:d.left,top:d.top,width:this.uiDialog.outerWidth(),height:this.uiDialog.outerHeight()})},_destroyShadow:function(){this.shadow.remove();this.shadow=null}});b.extend(b.ui.dialog,{version:"1.6rc6",defaults:{autoOpen:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",draggable:true,height:"auto",minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,shadow:true,stack:true,title:"",width:300,zIndex:1000},getter:"isOpen",uuid:0,getTitleId:function(c){return"ui-dialog-title-"+(c.attr("id")||++this.uuid)},overlay:function(c){this.$el=b.ui.dialog.overlay.create(c)}});b.extend(b.ui.dialog.overlay,{instances:[],events:b.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(c){return c+".dialog-overlay"}).join(" "),create:function(d){if(this.instances.length===0){setTimeout(function(){b("a, :input").bind(b.ui.dialog.overlay.events,function(){var f=false;var h=b(this).parents(".ui-dialog");if(h.length){var e=b(".ui-dialog-overlay");if(e.length){var g=parseInt(e.css("z-index"),10);e.each(function(){g=Math.max(g,parseInt(b(this).css("z-index"),10))});f=parseInt(h.css("z-index"),10)>g}else{f=true}}return f})},1);b(document).bind("keydown.dialog-overlay",function(e){(d.options.closeOnEscape&&e.keyCode&&e.keyCode==b.ui.keyCode.ESCAPE&&d.close(e))});b(window).bind("resize.dialog-overlay",b.ui.dialog.overlay.resize)}var c=b("<div></div>").appendTo(document.body).addClass("ui-widget-overlay").css({width:this.width(),height:this.height()});(d.options.bgiframe&&b.fn.bgiframe&&c.bgiframe());this.instances.push(c);return c},destroy:function(c){this.instances.splice(b.inArray(this.instances,c),1);if(this.instances.length===0){b("a, :input").add([document,window]).unbind(".dialog-overlay")}c.remove()},height:function(){if(b.browser.msie&&b.browser.version<7){var d=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(d<c){return b(window).height()+"px"}else{return d+"px"}}else{return b(document).height()+"px"}},width:function(){if(b.browser.msie&&b.browser.version<7){var c=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var d=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(c<d){return b(window).width()+"px"}else{return c+"px"}}else{return b(document).width()+"px"}},resize:function(){var c=b([]);b.each(b.ui.dialog.overlay.instances,function(){c=c.add(this)});c.css({width:0,height:0}).css({width:b.ui.dialog.overlay.width(),height:b.ui.dialog.overlay.height()})}});b.extend(b.ui.dialog.overlay.prototype,{destroy:function(){b.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);;/*
+ * jQuery UI Effects 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */ (function(d){d.effects=d.effects||{};d.extend(d.effects,{version:"1.6rc6",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}});function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:i.duration;h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(arguments[0].constructor==Function)){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);;/*
+ * jQuery UI Effects Blind 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.blind=function(b){return this.queue(function(){var d=a(this),c=["position","top","left"];var h=a.effects.setMode(d,b.options.mode||"hide");var g=b.options.direction||"vertical";a.effects.save(d,c);d.show();var j=a.effects.createWrapper(d).css({overflow:"hidden"});var e=(g=="vertical")?"height":"width";var i=(g=="vertical")?j.height():j.width();if(h=="show"){j.css(e,0)}var f={};f[e]=h=="show"?i:0;j.animate(f,b.duration,b.options.easing,function(){if(h=="hide"){d.hide()}a.effects.restore(d,c);a.effects.removeWrapper(d);if(b.callback){b.callback.apply(d[0],arguments)}d.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Effects Bounce 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.bounce=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"up";var c=b.options.distance||20;var d=b.options.times||5;var g=b.duration||250;if(/show|hide/.test(k)){l.push("opacity")}a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var c=b.options.distance||(f=="top"?e.outerHeight({margin:true})/3:e.outerWidth({margin:true})/3);if(k=="show"){e.css("opacity",0).css(f,p=="pos"?-c:c)}if(k=="hide"){c=c/(d*2)}if(k!="hide"){d--}if(k=="show"){var h={opacity:1};h[f]=(p=="pos"?"+=":"-=")+c;e.animate(h,g/2,b.options.easing);c=c/2;d--}for(var j=0;j<d;j++){var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing);c=(k=="hide")?c*2:c/2}if(k=="hide"){var h={opacity:0};h[f]=(p=="pos"?"-=":"+=")+c;e.animate(h,g/2,b.options.easing,function(){e.hide();a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}else{var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Clip 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.clip=function(b){return this.queue(function(){var f=a(this),j=["position","top","left","height","width"];var i=a.effects.setMode(f,b.options.mode||"hide");var k=b.options.direction||"vertical";a.effects.save(f,j);f.show();var c=a.effects.createWrapper(f).css({overflow:"hidden"});var e=f[0].tagName=="IMG"?c:f;var g={size:(k=="vertical")?"height":"width",position:(k=="vertical")?"top":"left"};var d=(k=="vertical")?e.height():e.width();if(i=="show"){e.css(g.size,0);e.css(g.position,d/2)}var h={};h[g.size]=i=="show"?d:0;h[g.position]=i=="show"?0:d/2;e.animate(h,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){f.hide()}a.effects.restore(f,j);a.effects.removeWrapper(f);if(b.callback){b.callback.apply(f[0],arguments)}f.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Drop 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.drop=function(b){return this.queue(function(){var e=a(this),d=["position","top","left","opacity"];var i=a.effects.setMode(e,b.options.mode||"hide");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e);var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true})/2:e.outerWidth({margin:true})/2);if(i=="show"){e.css("opacity",0).css(f,c=="pos"?-j:j)}var g={opacity:i=="show"?1:0};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Explode 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.explode=function(b){return this.queue(function(){var k=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;var e=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?(a(this).is(":visible")?"hide":"show"):b.options.mode;var h=a(this).show().css("visibility","hidden");var l=h.offset();l.top-=parseInt(h.css("marginTop"))||0;l.left-=parseInt(h.css("marginLeft"))||0;var g=h.outerWidth(true);var c=h.outerHeight(true);for(var f=0;f<k;f++){for(var d=0;d<e;d++){h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/*
+ * jQuery UI Effects Fold 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1])/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Effects Highlight 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Pulsate 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c<f;c++){d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing)}if(g=="hide"){d.animate({opacity:0},e,b.options.easing,function(){d.hide();if(b.callback){b.callback.apply(this,arguments)}})}else{d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing,function(){if(b.callback){b.callback.apply(this,arguments)}})}d.queue("fx",function(){d.dequeue()});d.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Scale 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.puff=function(b){return this.queue(function(){var f=a(this);var c=a.extend(true,{},b.options);var h=a.effects.setMode(f,b.options.mode||"hide");var g=parseInt(b.options.percent)||150;c.fade=true;var e={height:f.height(),width:f.width()};var d=g/100;f.from=(h=="hide")?e:{height:e.height*d,width:e.width*d};c.from=f.from;c.percent=(h=="hide")?g:100;c.mode=h;f.effect("scale",c,b.duration,b.callback);f.dequeue()})};a.effects.scale=function(b){return this.queue(function(){var g=a(this);var d=a.extend(true,{},b.options);var j=a.effects.setMode(g,b.options.mode||"effect");var h=parseInt(b.options.percent)||(parseInt(b.options.percent)==0?0:(j=="hide"?0:100));var i=b.options.direction||"both";var c=b.options.origin;if(j!="effect"){d.origin=c||["middle","center"];d.restore=true}var f={height:g.height(),width:g.width()};g.from=b.options.from||(j=="show"?{height:0,width:0}:f);var e={y:i!="horizontal"?(h/100):1,x:i!="vertical"?(h/100):1};g.to={height:f.height*e.y,width:f.width*e.x};if(b.options.fade){if(j=="show"){g.from.opacity=0;g.to.opacity=1}if(j=="hide"){g.from.opacity=1;g.to.opacity=0}}d.from=g.from;d.to=g.to;d.mode=j;g.effect("size",d,b.duration,b.callback);g.dequeue()})};a.effects.size=function(b){return this.queue(function(){var c=a(this),n=["position","top","left","width","height","overflow","opacity"];var m=["position","top","left","overflow","opacity"];var j=["width","height","overflow"];var p=["fontSize"];var k=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var g=a.effects.setMode(c,b.options.mode||"effect");var i=b.options.restore||false;var e=b.options.scale||"both";var o=b.options.origin;var d={height:c.height(),width:c.width()};c.from=b.options.from||d;c.to=b.options.to||d;if(o){var h=a.effects.getBaseline(o,d);c.from.top=(d.height-c.from.height)*h.y;c.from.left=(d.width-c.from.width)*h.x;c.to.top=(d.height-c.to.height)*h.y;c.to.left=(d.width-c.to.width)*h.x}var l={from:{y:c.from.height/d.height,x:c.from.width/d.width},to:{y:c.to.height/d.height,x:c.to.width/d.width}};if(e=="box"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(k);c.from=a.effects.setTransition(c,k,l.from.y,c.from);c.to=a.effects.setTransition(c,k,l.to.y,c.to)}if(l.from.x!=l.to.x){n=n.concat(f);c.from=a.effects.setTransition(c,f,l.from.x,c.from);c.to=a.effects.setTransition(c,f,l.to.x,c.to)}}if(e=="content"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(p);c.from=a.effects.setTransition(c,p,l.from.y,c.from);c.to=a.effects.setTransition(c,p,l.to.y,c.to)}}a.effects.save(c,i?n:m);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(e=="content"||e=="both"){k=k.concat(["marginTop","marginBottom"]).concat(p);f=f.concat(["marginLeft","marginRight"]);j=n.concat(k).concat(f);c.find("*[width]").each(function(){child=a(this);if(i){a.effects.save(child,j)}var q={height:child.height(),width:child.width()};child.from={height:q.height*l.from.y,width:q.width*l.from.x};child.to={height:q.height*l.to.y,width:q.width*l.to.x};if(l.from.y!=l.to.y){child.from=a.effects.setTransition(child,k,l.from.y,child.from);child.to=a.effects.setTransition(child,k,l.to.y,child.to)}if(l.from.x!=l.to.x){child.from=a.effects.setTransition(child,f,l.from.x,child.from);child.to=a.effects.setTransition(child,f,l.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){if(i){a.effects.restore(child,j)}})})}c.animate(c.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(g=="hide"){c.hide()}a.effects.restore(c,i?n:m);a.effects.removeWrapper(c);if(b.callback){b.callback.apply(this,arguments)}c.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Shake 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.shake=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"left";var c=b.options.distance||20;var d=b.options.times||3;var g=b.duration||b.options.duration||140;a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var h={},o={},m={};h[f]=(p=="pos"?"-=":"+=")+c;o[f]=(p=="pos"?"+=":"-=")+c*2;m[f]=(p=="pos"?"-=":"+=")+c*2;e.animate(h,g,b.options.easing);for(var j=1;j<d;j++){e.animate(o,g,b.options.easing).animate(m,g,b.options.easing)}e.animate(o,g,b.options.easing).animate(h,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}});e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Slide 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.slide=function(b){return this.queue(function(){var e=a(this),d=["position","top","left"];var i=a.effects.setMode(e,b.options.mode||"show");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e).css({overflow:"hidden"});var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true}):e.outerWidth({margin:true}));if(i=="show"){e.css(f,c=="pos"?-j:j)}var g={};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Transfer 1.6rc6
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ * effects.core.js
+ */ (function(a){a.effects.transfer=function(b){return this.queue(function(){var e=a(this);var g=a.effects.setMode(e,b.options.mode||"effect");var f=a(b.options.to);var c=e.offset();var d=a('<div class="ui-effects-transfer"></div>').appendTo(document.body);if(b.options.className){d.addClass(b.options.className)}d.addClass(b.options.className);d.css({top:c.top,left:c.left,height:e.outerHeight()-parseInt(d.css("borderTopWidth"))-parseInt(d.css("borderBottomWidth")),width:e.outerWidth()-parseInt(d.css("borderLeftWidth"))-parseInt(d.css("borderRightWidth")),position:"absolute"});c=f.offset();animation={top:c.top,left:c.left,height:f.outerHeight()-parseInt(d.css("borderTopWidth"))-parseInt(d.css("borderBottomWidth")),width:f.outerWidth()-parseInt(d.css("borderLeftWidth"))-parseInt(d.css("borderRightWidth"))};d.animate(animation,b.duration,b.options.easing,function(){d.remove();if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);; \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/scripts/jquery.cookie.js b/projecttemplates/WebFormsRelyingParty/scripts/jquery.cookie.js
new file mode 100644
index 0000000..121f723
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/scripts/jquery.cookie.js
@@ -0,0 +1,96 @@
+/**
+* Cookie plugin
+*
+* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+* Dual licensed under the MIT and GPL licenses:
+* http://www.opensource.org/licenses/mit-license.php
+* http://www.gnu.org/licenses/gpl.html
+*
+*/
+
+/**
+* Create a cookie with the given name and value and other optional parameters.
+*
+* @example $.cookie('the_cookie', 'the_value');
+* @desc Set the value of a cookie.
+* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
+* @desc Create a cookie with all available options.
+* @example $.cookie('the_cookie', 'the_value');
+* @desc Create a session cookie.
+* @example $.cookie('the_cookie', null);
+* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
+* used when the cookie was set.
+*
+* @param String name The name of the cookie.
+* @param String value The value of the cookie.
+* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+* If set to null or omitted, the cookie will be a session cookie and will not be retained
+* when the the browser exits.
+* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+* require a secure protocol (like HTTPS).
+* @type undefined
+*
+* @name $.cookie
+* @cat Plugins/Cookie
+* @author Klaus Hartl/klaus.hartl@stilbuero.de
+*/
+
+/**
+* Get the value of a cookie with the given name.
+*
+* @example $.cookie('the_cookie');
+* @desc Get the value of a cookie.
+*
+* @param String name The name of the cookie.
+* @return The value of the cookie.
+* @type String
+*
+* @name $.cookie
+* @cat Plugins/Cookie
+* @author Klaus Hartl/klaus.hartl@stilbuero.de
+*/
+jQuery.cookie = function(name, value, options) {
+ if (typeof value != 'undefined') { // name and value given, set cookie
+ options = options || {};
+ if (value === null) {
+ value = '';
+ options.expires = -1;
+ }
+ var expires = '';
+ if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+ var date;
+ if (typeof options.expires == 'number') {
+ date = new Date();
+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+ } else {
+ date = options.expires;
+ }
+ expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+ }
+ // CAUTION: Needed to parenthesize options.path and options.domain
+ // in the following expressions, otherwise they evaluate to undefined
+ // in the packed version for some reason...
+ var path = options.path ? '; path=' + (options.path) : '';
+ var domain = options.domain ? '; domain=' + (options.domain) : '';
+ var secure = options.secure ? '; secure' : '';
+ document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+ } else { // only name given, get cookie
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+}; \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/styles/Standard.css b/projecttemplates/WebFormsRelyingParty/styles/Standard.css
new file mode 100644
index 0000000..f0b1d8e
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/styles/Standard.css
@@ -0,0 +1,67 @@
+body
+{
+ font-family: Cambria, Arial, Times New Roman;
+ font-size: 12pt;
+}
+
+h1 a
+{
+ text-decoration: none;
+ color: Black;
+}
+
+div.OpenIdButtons
+{
+ margin-bottom: 10px;
+}
+
+div.OpenIdButtons span.OpenIdButton
+{
+ margin-left: 2px;
+ margin-right: 2px;
+ display: table;
+ float: left;
+ width: 92px;
+ height: 64px;
+ border: solid 1px lightgray;
+ text-align: center;
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+div.OpenIdButtons span.OpenIdButton span
+{
+ margin: 0;
+ padding: 0;
+ top: 50%;
+ display: table-cell;
+ vertical-align: middle;
+}
+
+div.OpenIdButtons span.OpenIdButton object
+{
+ height: 0px;
+}
+
+div.OpenIdButtons span.OpenIdButton div
+{
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+}
+
+div.OpenIdBox
+{
+ margin-top: 10px;
+ clear: left;
+}
+
+ul.AuthTokens li.OpenID
+{
+ list-style-image: url(../images/openid_login.gif);
+}
+
+ul.AuthTokens li.InfoCard
+{
+ list-style-image: url(../images/infocard_23x16.png);
+}
diff --git a/projecttemplates/WebFormsRelyingParty/styles/loginpopup.css b/projecttemplates/WebFormsRelyingParty/styles/loginpopup.css
new file mode 100644
index 0000000..89e1b38
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/styles/loginpopup.css
@@ -0,0 +1,23 @@
+body
+{
+ font-family: Verdana;
+ font-size: 10pt;
+ background-color: White;
+ margin: 10px;
+}
+/*
+body > div.wrapper
+{
+ width: 355px;
+ height: 235px;
+}
+*/
+Div#NotMyComputerDiv
+{
+ display: none;
+}
+
+.helpDoc
+{
+ font-size: 80%;
+} \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_55_999999_40x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_55_999999_40x100.png
new file mode 100644
index 0000000..6b6de7d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_55_999999_40x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_75_aaaaaa_40x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_75_aaaaaa_40x100.png
new file mode 100644
index 0000000..5b5dab2
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_flat_75_aaaaaa_40x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_45_0078ae_1x400.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_45_0078ae_1x400.png
new file mode 100644
index 0000000..3dac650
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_45_0078ae_1x400.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_55_f8da4e_1x400.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_55_f8da4e_1x400.png
new file mode 100644
index 0000000..b383704
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_55_f8da4e_1x400.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_75_79c9ec_1x400.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_75_79c9ec_1x400.png
new file mode 100644
index 0000000..d384e42
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_glass_75_79c9ec_1x400.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_45_e14f1c_500x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
new file mode 100644
index 0000000..b9851ba
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_50_6eac2c_500x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_50_6eac2c_500x100.png
new file mode 100644
index 0000000..76dac56
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_50_6eac2c_500x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_75_2191c0_500x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_75_2191c0_500x100.png
new file mode 100644
index 0000000..eeacf69
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_gloss-wave_75_2191c0_500x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
new file mode 100644
index 0000000..38c3833
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_0078ae_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_0078ae_256x240.png
new file mode 100644
index 0000000..58f96f8
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_0078ae_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_056b93_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_056b93_256x240.png
new file mode 100644
index 0000000..8e6103d
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_056b93_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_d8e7f3_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_d8e7f3_256x240.png
new file mode 100644
index 0000000..2c8aac4
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_d8e7f3_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_e0fdff_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_e0fdff_256x240.png
new file mode 100644
index 0000000..d985a26
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_e0fdff_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f5e175_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f5e175_256x240.png
new file mode 100644
index 0000000..7862520
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f5e175_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f7a50d_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f7a50d_256x240.png
new file mode 100644
index 0000000..c5297f8
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_f7a50d_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_fcd113_256x240.png b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_fcd113_256x240.png
new file mode 100644
index 0000000..68dcff5
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/images/ui-icons_fcd113_256x240.png
Binary files differ
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.accordion.css b/projecttemplates/WebFormsRelyingParty/theme/ui.accordion.css
new file mode 100644
index 0000000..c84ad4e
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.accordion.css
@@ -0,0 +1,9 @@
+/* Accordion
+----------------------------------*/
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion li {display: inline;}
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
+.ui-accordion .ui-accordion-content-active { display: block; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.all.css b/projecttemplates/WebFormsRelyingParty/theme/ui.all.css
new file mode 100644
index 0000000..543e4c3
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.all.css
@@ -0,0 +1,2 @@
+@import "ui.base.css";
+@import "ui.theme.css";
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.base.css b/projecttemplates/WebFormsRelyingParty/theme/ui.base.css
new file mode 100644
index 0000000..dadf378
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.base.css
@@ -0,0 +1,9 @@
+@import url("ui.core.css");
+
+@import url("ui.accordion.css");
+@import url("ui.datepicker.css");
+@import url("ui.dialog.css");
+@import url("ui.progressbar.css");
+@import url("ui.resizable.css");
+@import url("ui.slider.css");
+@import url("ui.tabs.css");
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.core.css b/projecttemplates/WebFormsRelyingParty/theme/ui.core.css
new file mode 100644
index 0000000..d832ad7
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.core.css
@@ -0,0 +1,37 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.datepicker.css b/projecttemplates/WebFormsRelyingParty/theme/ui.datepicker.css
new file mode 100644
index 0000000..92986c9
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.datepicker.css
@@ -0,0 +1,62 @@
+/* Datepicker
+----------------------------------*/
+.ui-datepicker { width: 17em; padding: .2em .2em 0; }
+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
+.ui-datepicker .ui-datepicker-prev { left:2px; }
+.ui-datepicker .ui-datepicker-next { right:2px; }
+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
+.ui-datepicker .ui-datepicker-next-hover { right:1px; }
+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
+.ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
+.ui-datepicker td { border: 0; padding: 1px; }
+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi { width:auto; }
+.ui-datepicker-multi .ui-datepicker-group { float:left; }
+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
+.ui-datepicker-row-break { clear:left; width:100%; }
+
+/* RTL support */
+.ui-datepicker-rtl { direction: rtl; }
+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+} \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.dialog.css b/projecttemplates/WebFormsRelyingParty/theme/ui.dialog.css
new file mode 100644
index 0000000..f10f409
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.dialog.css
@@ -0,0 +1,13 @@
+/* Dialog
+----------------------------------*/
+.ui-dialog { position: relative; padding: .2em; width: 300px; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.progressbar.css b/projecttemplates/WebFormsRelyingParty/theme/ui.progressbar.css
new file mode 100644
index 0000000..bc0939e
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.progressbar.css
@@ -0,0 +1,4 @@
+/* Progressbar
+----------------------------------*/
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.resizable.css b/projecttemplates/WebFormsRelyingParty/theme/ui.resizable.css
new file mode 100644
index 0000000..44efeb2
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.resizable.css
@@ -0,0 +1,13 @@
+/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;} \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.slider.css b/projecttemplates/WebFormsRelyingParty/theme/ui.slider.css
new file mode 100644
index 0000000..0792a48
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.slider.css
@@ -0,0 +1,17 @@
+/* Slider
+----------------------------------*/
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: 1%; display: block; border: 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.tabs.css b/projecttemplates/WebFormsRelyingParty/theme/ui.tabs.css
new file mode 100644
index 0000000..70ed3ef
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.tabs.css
@@ -0,0 +1,9 @@
+/* Tabs
+----------------------------------*/
+.ui-tabs {padding: .2em;}
+.ui-tabs .ui-tabs-nav { padding: .2em .2em 0 .2em; position: relative; }
+.ui-tabs .ui-tabs-nav li { float: left; border-bottom: 0 !important; margin: 0 .2em -1px 0; padding: 0; list-style: none; }
+.ui-tabs .ui-tabs-nav li a { display:block; text-decoration: none; padding: .5em 1em; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: .1em; border-bottom: 0; }
+.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border: 0; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/theme/ui.theme.css b/projecttemplates/WebFormsRelyingParty/theme/ui.theme.css
new file mode 100644
index 0000000..84f7fed
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/theme/ui.theme.css
@@ -0,0 +1,243 @@
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://ui.jquery.com/themeroller/?tr=&ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=2191c0&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=75&borderColorHeader=4297d7&fcHeader=eaf5f7&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=0078ae&bgColorDefault=0078ae&bgTextureDefault=02_glass.png&bgImgOpacityDefault=45&borderColorDefault=77d5f7&fcDefault=ffffff&iconColorDefault=e0fdff&bgColorHover=79c9ec&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=448dae&fcHover=026890&iconColorHover=056b93&bgColorActive=6eac2c&bgTextureActive=12_gloss_wave.png&bgImgOpacityActive=50&borderColorActive=acdd4a&fcActive=ffffff&iconColorActive=f5e175&bgColorHighlight=f8da4e&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcd113&fcHighlight=915608&iconColorHighlight=f7a50d&bgColorError=e14f1c&bgTextureError=12_gloss_wave.png&bgImgOpacityError=45&borderColorError=cd0a0a&fcError=ffffff&iconColorError=fcd113&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=999999&bgTextureShadow=01_flat.png&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
+.ui-widget-header { border: 1px solid #4297d7; background: #2191c0 url(images/ui-bg_gloss-wave_75_2191c0_500x100.png) 50% 50% repeat-x; color: #eaf5f7; font-weight: bold; }
+.ui-widget-header a { color: #eaf5f7; }
+.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #77d5f7; background: #0078ae url(images/ui-bg_glass_45_0078ae_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+.ui-state-default a { color: #ffffff; text-decoration: none; outline: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #448dae; background: #79c9ec url(images/ui-bg_glass_75_79c9ec_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #026890; outline: none; }
+.ui-state-hover a { color: #026890; text-decoration: none; outline: none; }
+.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #acdd4a; background: #6eac2c url(images/ui-bg_gloss-wave_50_6eac2c_500x100.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+.ui-state-active a { color: #ffffff; outline: none; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcd113; background: #f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x; color: #915608; }
+.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x; color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #ffffff; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_0078ae_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_0078ae_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_e0fdff_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_056b93_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_f5e175_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_f7a50d_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fcd113_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; }
+.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; }
+.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; }
+.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; }
+.ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; }
+.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; }
+.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: 5px 0 0 5px; padding: 0px; background: #999999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x; opacity: .45;filter:Alpha(Opacity=45); -moz-border-radius: 5px; -webkit-border-radius: 5px; } \ No newline at end of file
diff --git a/projecttemplates/WebFormsRelyingParty/xrds.aspx b/projecttemplates/WebFormsRelyingParty/xrds.aspx
new file mode 100644
index 0000000..cb36eee
--- /dev/null
+++ b/projecttemplates/WebFormsRelyingParty/xrds.aspx
@@ -0,0 +1,20 @@
+<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?>
+<%--
+This page is a required for relying party discovery per OpenID 2.0.
+It allows Providers to call back to the relying party site to confirm the
+identity that it is claiming in the realm and return_to URLs.
+This page should be pointed to by the 'realm' home page, which is default.aspx.
+--%>
+<xrds:XRDS
+ xmlns:xrds="xri://$xrds"
+ xmlns:openid="http://openid.net/xmlns/1.0"
+ xmlns="xri://$xrd*($v*2.0)">
+ <XRD>
+ <Service priority="1">
+ <Type>http://specs.openid.net/auth/2.0/return_to</Type>
+ <%-- Every page with an OpenID login should be listed here. --%>
+ <URI priority="1"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/LoginFrame.aspx"))%></URI>
+ <URI priority="2"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/Members/AccountInfo.aspx"))%></URI>
+ </Service>
+ </XRD>
+</xrds:XRDS>
diff --git a/samples/OAuthConsumer/App_Code/InMemoryTokenManager.cs b/samples/OAuthConsumer/App_Code/InMemoryTokenManager.cs
index fede300..2ecd045 100644
--- a/samples/OAuthConsumer/App_Code/InMemoryTokenManager.cs
+++ b/samples/OAuthConsumer/App_Code/InMemoryTokenManager.cs
@@ -28,14 +28,6 @@ public class InMemoryTokenManager : IConsumerTokenManager {
#region ITokenManager Members
- public string GetConsumerSecret(string consumerKey) {
- if (consumerKey == this.ConsumerKey) {
- return this.ConsumerSecret;
- } else {
- throw new ArgumentException("Unrecognized consumer key.", "consumerKey");
- }
- }
-
public string GetTokenSecret(string token) {
return this.tokensAndSecrets[token];
}
diff --git a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
index 710508d..8c93d2f 100644
--- a/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
+++ b/samples/OAuthServiceProvider/App_Code/DatabaseTokenManager.cs
@@ -40,6 +40,10 @@ public class DatabaseTokenManager : IServiceProviderTokenManager {
}
}
+ public void UpdateToken(IServiceProviderRequestToken token) {
+ // Nothing to do here, since we're using Linq To SQL.
+ }
+
#endregion
#region ITokenManager Members
diff --git a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
index f936c60..1e981a3 100644
--- a/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
+++ b/samples/OAuthServiceProvider/Members/Authorize.aspx.cs
@@ -63,7 +63,9 @@ public partial class Authorize : System.Web.UI.Page {
string verifier = ServiceProvider.CreateVerificationCode(VerificationCodeFormat.AlphaNumericNoLookAlikes, 10);
verificationCodeLabel.Text = verifier;
ITokenContainingMessage requestTokenMessage = pending;
- Global.TokenManager.GetRequestToken(requestTokenMessage.Token).VerificationCode = verifier;
+ var requestToken = Global.TokenManager.GetRequestToken(requestTokenMessage.Token);
+ requestToken.VerificationCode = verifier;
+ Global.TokenManager.UpdateToken(requestToken);
}
}
}
diff --git a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
index 1bb2367..2f303bb 100644
--- a/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
+++ b/samples/OpenIdOfflineProvider/OpenIdOfflineProvider.csproj
@@ -57,10 +57,11 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\..\src\official-build-key.pfx</AssemblyOriginatorKeyFile>
<DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\..\src\official-build-key.pub</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs b/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs
new file mode 100644
index 0000000..de4505d
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryConsumerDescription.cs
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryConsumerDescription.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryConsumerDescription : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ public string Key { get; set; }
+
+ public string Secret { get; set; }
+
+ public System.Security.Cryptography.X509Certificates.X509Certificate2 Certificate { get; set; }
+
+ public Uri Callback { get; set; }
+
+ public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat { get; set; }
+
+ public int VerificationCodeLength { get; set; }
+
+ #endregion
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs
new file mode 100644
index 0000000..7e26b45
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderAccessToken.cs
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryServiceProviderAccessToken.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryServiceProviderAccessToken : IServiceProviderAccessToken {
+ #region IServiceProviderAccessToken Members
+
+ public string Token { get; set; }
+
+ public DateTime? ExpirationDate { get; set; }
+
+ public string Username { get; set; }
+
+ public string[] Roles { get; set; }
+
+ #endregion
+
+ public string Secret { get; set; }
+
+ public string Scope { get; set; }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs
new file mode 100644
index 0000000..9c02427
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryServiceProviderRequestToken.cs
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryServiceProviderRequestToken.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class InMemoryServiceProviderRequestToken : IServiceProviderRequestToken {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InMemoryServiceProviderRequestToken"/> class.
+ /// </summary>
+ public InMemoryServiceProviderRequestToken() {
+ this.CreatedOn = DateTime.Now;
+ }
+
+ #region IServiceProviderRequestToken Members
+
+ public string Token { get; set; }
+
+ public string ConsumerKey { get; set; }
+
+ public DateTime CreatedOn { get; set; }
+
+ public Uri Callback { get; set; }
+
+ public string VerificationCode { get; set; }
+
+ public Version ConsumerVersion { get; set; }
+
+ #endregion
+
+ public string Secret { get; set; }
+
+ public string Scope { get; set; }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
new file mode 100644
index 0000000..b04f736
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/InMemoryTokenManager.cs
@@ -0,0 +1,117 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryTokenManager.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OpenId.Extensions.OAuth;
+
+ /// <summary>
+ /// A simple in-memory token manager. JUST FOR PURPOSES OF KEEPING THE SAMPLE SIMPLE.
+ /// </summary>
+ /// <remarks>
+ /// This is merely a sample app. A real web app SHOULD NEVER store a memory-only
+ /// token manager in application. It should be an IServiceProviderTokenManager
+ /// implementation that is bound to a database.
+ /// </remarks>
+ public class InMemoryTokenManager : IServiceProviderTokenManager, IOpenIdOAuthTokenManager, ICombinedOpenIdProviderTokenManager {
+ private Dictionary<string, InMemoryServiceProviderRequestToken> requestTokens = new Dictionary<string, InMemoryServiceProviderRequestToken>();
+ private Dictionary<string, InMemoryServiceProviderAccessToken> accessTokens = new Dictionary<string, InMemoryServiceProviderAccessToken>();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InMemoryTokenManager"/> class.
+ /// </summary>
+ internal InMemoryTokenManager() {
+ }
+
+ #region IServiceProviderTokenManager Members
+
+ public IConsumerDescription GetConsumer(string consumerKey) {
+ return new InMemoryConsumerDescription {
+ Key = consumerKey,
+ Secret = "some crazy secret",
+ };
+ }
+
+ public IServiceProviderRequestToken GetRequestToken(string token) {
+ return this.requestTokens[token];
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ throw new NotImplementedException();
+ }
+
+ public void UpdateToken(IServiceProviderRequestToken token) {
+ // Nothing to do here, since there's not database in this sample.
+ }
+
+ #endregion
+
+ #region ITokenManager Members
+
+ public string GetTokenSecret(string token) {
+ if (this.requestTokens.ContainsKey(token)) {
+ return this.requestTokens[token].Secret;
+ } else {
+ return this.accessTokens[token].Secret;
+ }
+ }
+
+ public void StoreNewRequestToken(DotNetOpenAuth.OAuth.Messages.UnauthorizedTokenRequest request, DotNetOpenAuth.OAuth.Messages.ITokenSecretContainingMessage response) {
+ throw new NotImplementedException();
+ }
+
+ public bool IsRequestTokenAuthorized(string requestToken) {
+ // In OpenID+OAuth scenarios, request tokens are always authorized.
+ return true;
+ }
+
+ public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
+ this.requestTokens.Remove(requestToken);
+ this.accessTokens[accessToken] = new InMemoryServiceProviderAccessToken {
+ Token = accessToken,
+ Secret = accessTokenSecret,
+ };
+ }
+
+ public TokenType GetTokenType(string token) {
+ if (this.requestTokens.ContainsKey(token)) {
+ return TokenType.RequestToken;
+ } else if (this.accessTokens.ContainsKey(token)) {
+ return TokenType.AccessToken;
+ } else {
+ return TokenType.InvalidToken;
+ }
+ }
+
+ #endregion
+
+ #region IOpenIdOAuthTokenManager Members
+
+ public void StoreOpenIdAuthorizedRequestToken(string consumerKey, AuthorizationApprovedResponse authorization) {
+ this.requestTokens[authorization.RequestToken] = new InMemoryServiceProviderRequestToken {
+ Token = authorization.RequestToken,
+ Scope = authorization.Scope,
+ ConsumerVersion = authorization.Version,
+ };
+ }
+
+ #endregion
+
+ #region ICombinedOpenIdProviderTokenManager Members
+
+ public string GetConsumerKey(DotNetOpenAuth.OpenId.Realm realm) {
+ // We just use the realm as the consumer key, like Google does.
+ return realm;
+ }
+
+ #endregion
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs b/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs
new file mode 100644
index 0000000..cc4beff
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/OAuthHybrid.cs
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthHybrid.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ internal class OAuthHybrid {
+ /// <summary>
+ /// Initializes static members of the <see cref="OAuthHybrid"/> class.
+ /// </summary>
+ static OAuthHybrid() {
+ ServiceProvider = new ServiceProvider(GetServiceDescription(), TokenManager);
+ }
+
+ internal static IServiceProviderTokenManager TokenManager {
+ get {
+ // This is merely a sample app. A real web app SHOULD NEVER store a memory-only
+ // token manager in application. It should be an IServiceProviderTokenManager
+ // implementation that is bound to a database.
+ var tokenManager = (IServiceProviderTokenManager)HttpContext.Current.Application["TokenManager"];
+ if (tokenManager == null) {
+ HttpContext.Current.Application["TokenManager"] = tokenManager = new InMemoryTokenManager();
+ }
+
+ return tokenManager;
+ }
+ }
+
+ internal static ServiceProvider ServiceProvider { get; private set; }
+
+ internal static ServiceProviderDescription GetServiceDescription() {
+ return new ServiceProviderDescription {
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ };
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
index ceea842..ffb0f2f 100644
--- a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
+++ b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
@@ -83,12 +83,20 @@
<Content Include="user_xrds.aspx" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="access_token.ashx.cs">
+ <DependentUpon>access_token.ashx</DependentUpon>
+ </Compile>
+ <Compile Include="Code\InMemoryConsumerDescription.cs" />
+ <Compile Include="Code\InMemoryServiceProviderAccessToken.cs" />
<Compile Include="Code\CustomStore.cs" />
<Compile Include="Code\CustomStoreDataSet.Designer.cs">
<DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
+ <Compile Include="Code\InMemoryServiceProviderRequestToken.cs" />
+ <Compile Include="Code\InMemoryTokenManager.cs" />
+ <Compile Include="Code\OAuthHybrid.cs" />
<Compile Include="Code\ReadOnlyXmlMembershipProvider.cs" />
<Compile Include="Code\TracePageAppender.cs" />
<Compile Include="Code\Util.cs" />
@@ -157,6 +165,7 @@
<Content Include="TracePage.aspx" />
</ItemGroup>
<ItemGroup>
+ <Content Include="access_token.ashx" />
<None Include="Code\CustomStoreDataSet.xsc">
<DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
</None>
@@ -190,7 +199,7 @@
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
- <AutoAssignPort>True</AutoAssignPort>
+ <AutoAssignPort>False</AutoAssignPort>
<DevelopmentServerPort>4860</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>
diff --git a/samples/OpenIdProviderWebForms/access_token.ashx b/samples/OpenIdProviderWebForms/access_token.ashx
new file mode 100644
index 0000000..dcb088e
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/access_token.ashx
@@ -0,0 +1 @@
+<%@ WebHandler Language="C#" CodeBehind="access_token.ashx.cs" Class="OpenIdProviderWebForms.access_token" %>
diff --git a/samples/OpenIdProviderWebForms/access_token.ashx.cs b/samples/OpenIdProviderWebForms/access_token.ashx.cs
new file mode 100644
index 0000000..b895da9
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/access_token.ashx.cs
@@ -0,0 +1,23 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Services;
+ using DotNetOpenAuth.OAuth;
+ using OpenIdProviderWebForms.Code;
+
+ [WebService(Namespace = "http://tempuri.org/")]
+ [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
+ public class access_token : IHttpHandler {
+ public bool IsReusable {
+ get { return true; }
+ }
+
+ public void ProcessRequest(HttpContext context) {
+ var request = OAuthHybrid.ServiceProvider.ReadAccessTokenRequest();
+ var response = OAuthHybrid.ServiceProvider.PrepareAccessTokenMessage(request);
+ OAuthHybrid.ServiceProvider.Channel.Send(response);
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/decide.aspx b/samples/OpenIdProviderWebForms/decide.aspx
index 4a6e2d8..d63364e 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx
+++ b/samples/OpenIdProviderWebForms/decide.aspx
@@ -17,6 +17,10 @@
<td><asp:Label runat="server" ID='realmLabel' /> </td>
</tr>
</table>
+ <asp:Panel runat="server" ID="OAuthPanel" Visible="false">
+ <p>In addition the relying party has asked for permission to access your private data. </p>
+ <asp:CheckBox runat="server" Text="Allow the relying party to access my private data" ID="oauthPermission" />
+ </asp:Panel>
<p>Allow this to proceed? </p>
<uc1:ProfileFields ID="profileFields" runat="server" Visible="false" />
<asp:Button ID="yes_button" OnClick="Yes_Click" Text=" yes " runat="Server" />
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs
index 3a14cf7..6146bd2 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.cs
@@ -6,6 +6,7 @@ namespace OpenIdProviderWebForms {
using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.Provider;
+ using OpenIdProviderWebForms.Code;
/// <summary>
/// Page for giving the user the option to continue or cancel out of authentication with a consumer.
@@ -21,6 +22,11 @@ namespace OpenIdProviderWebForms {
this.realmLabel.Text = ProviderEndpoint.PendingRequest.Realm.ToString();
+ var oauthRequest = OAuthHybrid.ServiceProvider.ReadAuthorizationRequest(ProviderEndpoint.PendingRequest);
+ if (oauthRequest != null) {
+ this.OAuthPanel.Visible = true;
+ }
+
if (ProviderEndpoint.PendingAuthenticationRequest != null) {
if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) {
ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier = Code.Util.BuildIdentityUrl();
@@ -51,6 +57,24 @@ namespace OpenIdProviderWebForms {
}
protected void Yes_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ if (this.OAuthPanel.Visible) {
+ string consumerKey = null;
+ string grantedScope = null;
+ if (this.oauthPermission.Checked) {
+ // This SIMPLE sample merely uses the realm as the consumerKey,
+ // but in a real app this will probably involve a database lookup to translate
+ // the realm to a known consumerKey.
+ consumerKey = ProviderEndpoint.PendingRequest.Realm;
+ grantedScope = string.Empty; // we don't scope individual access rights on this sample
+ }
+
+ OAuthHybrid.ServiceProvider.AttachAuthorizationResponse(ProviderEndpoint.PendingRequest, consumerKey, grantedScope);
+ }
+
var sregRequest = ProviderEndpoint.PendingRequest.GetExtension<ClaimsRequest>();
ClaimsResponse sregResponse = null;
if (sregRequest != null) {
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
index 05386cd..3aa6271 100644
--- a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
+++ b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
@@ -50,6 +50,24 @@ namespace OpenIdProviderWebForms {
protected global::System.Web.UI.WebControls.Label realmLabel;
/// <summary>
+ /// OAuthPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel OAuthPanel;
+
+ /// <summary>
+ /// oauthPermission control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBox oauthPermission;
+
+ /// <summary>
/// profileFields control.
/// </summary>
/// <remarks>
diff --git a/samples/OpenIdRelyingPartyMvc/Content/css/openidlogin.css b/samples/OpenIdRelyingPartyMvc/Content/css/openidlogin.css
index 20338c4..5f401d0 100644
--- a/samples/OpenIdRelyingPartyMvc/Content/css/openidlogin.css
+++ b/samples/OpenIdRelyingPartyMvc/Content/css/openidlogin.css
@@ -52,7 +52,7 @@
#openidlogin .provider
{
- cursor: hand;
+ cursor: pointer;
}
#openidlogin .buttons .provider
diff --git a/samples/OpenIdRelyingPartyWebForms/Global.asax.cs b/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
index ac74853..6583289 100644
--- a/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
+++ b/samples/OpenIdRelyingPartyWebForms/Global.asax.cs
@@ -42,6 +42,20 @@
}
}
+ internal static InMemoryTokenManager OwnSampleOPHybridTokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)HttpContext.Current.Application["OwnSampleOPHybridTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = new Uri(HttpContext.Current.Request.Url, HttpContext.Current.Request.ApplicationPath).AbsoluteUri;
+ string consumerSecret = "some crazy secret";
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ HttpContext.Current.Application["OwnSampleOPHybridTokenManager"] = tokenManager;
+ }
+
+ return tokenManager;
+ }
+ }
+
public static string ToString(NameValueCollection collection) {
using (StringWriter sw = new StringWriter()) {
foreach (string key in collection.Keys) {
diff --git a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
index d3bf92c..6f5df5c 100644
--- a/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
+++ b/samples/OpenIdRelyingPartyWebForms/OpenIdRelyingPartyWebForms.csproj
@@ -101,6 +101,13 @@
<Compile Include="Code\InMemoryTokenManager.cs" />
<Compile Include="Code\State.cs" />
<Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="loginPlusOAuthSampleOP.aspx.cs">
+ <DependentUpon>loginPlusOAuthSampleOP.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="loginPlusOAuthSampleOP.aspx.designer.cs">
+ <DependentUpon>loginPlusOAuthSampleOP.aspx</DependentUpon>
+ </Compile>
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
@@ -169,6 +176,7 @@
<Content Include="xrds.aspx" />
</ItemGroup>
<ItemGroup>
+ <Content Include="loginPlusOAuthSampleOP.aspx" />
<Content Include="images\attention.png" />
<Content Include="images\dotnetopenid_tiny.gif" />
<Content Include="images\openid_login.gif" />
diff --git a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
index 232cf3f..d70bc30 100644
--- a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx
@@ -25,14 +25,14 @@ td
<asp:Content runat="server" ContentPlaceHolderID="Main">
<script type="text/javascript">
- function onauthenticated(sender) {
+ function onauthenticated(sender, e) {
var emailBox = document.getElementById('<%= emailAddressBox.ClientID %>');
emailBox.disabled = false;
emailBox.title = null; // remove tooltip describing why the box was disabled.
// the sreg response may not always be included.
- if (sender.sreg) {
+ if (e && e.sreg) {
// and the email field may not always be included in the sreg response.
- if (sender.sreg.email) { emailBox.value = sender.sreg.email; }
+ if (e.sreg.email) { emailBox.value = e.sreg.email; }
}
}
</script>
@@ -48,7 +48,7 @@ td
<openid:OpenIdAjaxTextBox ID="OpenIdAjaxTextBox1" runat="server" CssClass="openidtextbox"
OnLoggingIn="OpenIdAjaxTextBox1_LoggingIn"
OnLoggedIn="OpenIdAjaxTextBox1_LoggedIn"
- OnClientAssertionReceived="onauthenticated(sender)"
+ OnClientAssertionReceived="onauthenticated(sender, e)"
OnUnconfirmedPositiveAssertion="OpenIdAjaxTextBox1_UnconfirmedPositiveAssertion" />
<asp:RequiredFieldValidator ID="openidRequiredValidator" runat="server"
ControlToValidate="OpenIdAjaxTextBox1" ValidationGroup="openidVG"
@@ -74,7 +74,7 @@ td
</td>
</tr>
<tr>
- <td />
+ <td></td>
<td>
<asp:Button runat="server" Text="Submit" ID="submitButton" OnClick="submitButton_Click" />
</td>
diff --git a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx.cs b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx.cs
index ffaf6f0..78d08f3 100644
--- a/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx.cs
+++ b/samples/OpenIdRelyingPartyWebForms/ajaxlogin.aspx.cs
@@ -13,7 +13,7 @@
protected void OpenIdAjaxTextBox1_LoggingIn(object sender, OpenIdEventArgs e) {
e.Request.AddExtension(new ClaimsRequest {
- Email = DemandLevel.Request,
+ Email = DemandLevel.Require,
});
}
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx b/samples/OpenIdRelyingPartyWebForms/login.aspx
index 281725c..bca0676 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx
@@ -7,8 +7,7 @@
<rp:OpenIdLogin ID="OpenIdLogin1" runat="server" CssClass="openid_login" RequestCountry="Request"
RequestEmail="Require" RequestGender="Require" RequestPostalCode="Require" RequestTimeZone="Require"
RememberMeVisible="True" PolicyUrl="~/PrivacyPolicy.aspx" TabIndex="1"
- OnLoggedIn="OpenIdLogin1_LoggedIn" OnLoggingIn="OpenIdLogin1_LoggingIn"
- OnSetupRequired="OpenIdLogin1_SetupRequired" />
+ OnLoggedIn="OpenIdLogin1_LoggedIn" OnLoggingIn="OpenIdLogin1_LoggingIn" />
<fieldset title="Knobs">
<asp:CheckBox ID="requireSslCheckBox" runat="server"
Text="RequireSsl (high security) mode"
@@ -22,9 +21,6 @@
</asp:CheckBoxList>
<p>Try the PPID identifier functionality against the OpenIDProviderMvc sample.</p>
</fieldset>
- <br />
- <asp:Label ID="setupRequiredLabel" runat="server" EnableViewState="False" Text="You must log into your Provider first to use Immediate mode."
- Visible="False" />
<p>
<rp:OpenIdButton runat="server" ImageUrl="~/images/yahoo.png" Text="Login with Yahoo!" ID="yahooLoginButton"
Identifier="https://me.yahoo.com/" />
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx.cs b/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
index 1de942a..6721e9b 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx.cs
@@ -35,10 +35,6 @@ namespace OpenIdRelyingPartyWebForms {
State.PapePolicies = e.Response.GetExtension<PolicyResponse>();
}
- protected void OpenIdLogin1_SetupRequired(object sender, OpenIdEventArgs e) {
- this.setupRequiredLabel.Visible = true;
- }
-
private void prepareRequest(IAuthenticationRequest request) {
// Collect the PAPE policies requested by the user.
List<string> policies = new List<string>();
diff --git a/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
index 944f5ff..4a2521c 100644
--- a/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
+++ b/samples/OpenIdRelyingPartyWebForms/login.aspx.designer.cs
@@ -41,15 +41,6 @@ namespace OpenIdRelyingPartyWebForms {
protected global::System.Web.UI.WebControls.CheckBoxList papePolicies;
/// <summary>
- /// setupRequiredLabel control.
- /// </summary>
- /// <remarks>
- /// Auto-generated field.
- /// To modify move field declaration from designer file to code-behind file.
- /// </remarks>
- protected global::System.Web.UI.WebControls.Label setupRequiredLabel;
-
- /// <summary>
/// yahooLoginButton control.
/// </summary>
/// <remarks>
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx
new file mode 100644
index 0000000..863f335
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx
@@ -0,0 +1,34 @@
+<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="loginPlusOAuthSampleOP.aspx.cs"
+ Inherits="OpenIdRelyingPartyWebForms.loginPlusOAuthSampleOP" ValidateRequest="false"
+ MasterPageFile="~/Site.Master" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.RelyingParty"
+ TagPrefix="rp" %>
+<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
+ <h2>Login Page </h2>
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex='0'>
+ <asp:View ID="View1" runat="server">
+ <asp:Label runat="server" Text="OpenIdProviderWebForms sample's OP Identifier or Claimed Identifier: " />
+ <rp:OpenIdTextBox runat="server" ID="identifierBox" Text="http://localhost:4860/"
+ OnLoggingIn="identifierBox_LoggingIn" OnLoggedIn="identifierBox_LoggedIn" OnCanceled="identifierBox_Failed"
+ OnFailed="identifierBox_Failed" />
+ <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="required"
+ ControlToValidate="identifierBox" />
+ <br />
+ <asp:Button ID="beginButton" runat="server" Text="Login + OAuth request" OnClick="beginButton_Click" />
+ </asp:View>
+ <asp:View ID="AuthorizationGiven" runat="server">
+ Authentication succeeded, and OAuth access was granted.
+ <p>The actual login step is aborted since this sample focuses on the process only
+ up to this point.</p>
+ </asp:View>
+ <asp:View ID="AuthorizationDenied" runat="server">
+ Authentication succeeded, but OAuth access was denied.
+ <p>The actual login step is aborted since this sample focuses on the process only
+ up to this point.</p>
+ </asp:View>
+ <asp:View ID="AuthenticationFailed" runat="server">
+ Authentication failed or was canceled.
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs
new file mode 100644
index 0000000..c7d3168
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.cs
@@ -0,0 +1,62 @@
+namespace OpenIdRelyingPartyWebForms {
+ using System;
+ using System.Web.Security;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ public partial class loginPlusOAuthSampleOP : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+
+ protected void beginButton_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ this.identifierBox.LogOn();
+ }
+
+ protected void identifierBox_LoggingIn(object sender, OpenIdEventArgs e) {
+ ServiceProviderDescription serviceDescription = new ServiceProviderDescription {
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ };
+
+ WebConsumer consumer = new WebConsumer(serviceDescription, Global.OwnSampleOPHybridTokenManager);
+ consumer.AttachAuthorizationRequest(e.Request, "http://tempuri.org/IDataApi/GetName");
+ }
+
+ protected void identifierBox_LoggedIn(object sender, OpenIdEventArgs e) {
+ State.FetchResponse = e.Response.GetExtension<FetchResponse>();
+
+ ServiceProviderDescription serviceDescription = new ServiceProviderDescription {
+ AccessTokenEndpoint = new MessageReceivingEndpoint(new Uri(e.Response.Provider.Uri, "/access_token.ashx"), HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ };
+ WebConsumer consumer = new WebConsumer(serviceDescription, Global.OwnSampleOPHybridTokenManager);
+
+ AuthorizedTokenResponse accessToken = consumer.ProcessUserAuthorization(e.Response);
+ if (accessToken != null) {
+ this.MultiView1.SetActiveView(this.AuthorizationGiven);
+
+ // At this point, the access token would be somehow associated with the user
+ // account at the RP.
+ ////Database.Associate(e.Response.ClaimedIdentifier, accessToken.AccessToken);
+ } else {
+ this.MultiView1.SetActiveView(this.AuthorizationDenied);
+ }
+
+ // Avoid the redirect
+ e.Cancel = true;
+ }
+
+ protected void identifierBox_Failed(object sender, OpenIdEventArgs e) {
+ this.MultiView1.SetActiveView(this.AuthenticationFailed);
+ }
+ }
+}
diff --git a/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs
new file mode 100644
index 0000000..9bf29b9
--- /dev/null
+++ b/samples/OpenIdRelyingPartyWebForms/loginPlusOAuthSampleOP.aspx.designer.cs
@@ -0,0 +1,88 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4918
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdRelyingPartyWebForms {
+
+
+ public partial class loginPlusOAuthSampleOP {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// identifierBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.RelyingParty.OpenIdTextBox identifierBox;
+
+ /// <summary>
+ /// RequiredFieldValidator1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1;
+
+ /// <summary>
+ /// beginButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button beginButton;
+
+ /// <summary>
+ /// AuthorizationGiven control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationGiven;
+
+ /// <summary>
+ /// AuthorizationDenied control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationDenied;
+
+ /// <summary>
+ /// AuthenticationFailed control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthenticationFailed;
+ }
+}
diff --git a/samples/OpenIdRelyingPartyWebForms/logout.aspx b/samples/OpenIdRelyingPartyWebForms/logout.aspx
index 71c0433..156f800 100644
--- a/samples/OpenIdRelyingPartyWebForms/logout.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/logout.aspx
@@ -7,6 +7,7 @@
State.FriendlyLoginName = null;
State.ProfileFields = null;
System.Web.Security.FormsAuthentication.SignOut();
+ DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.LogOff();
Response.Redirect("~/");
}
</script>
diff --git a/samples/OpenIdRelyingPartyWebForms/xrds.aspx b/samples/OpenIdRelyingPartyWebForms/xrds.aspx
index 52e27f7..92983fd 100644
--- a/samples/OpenIdRelyingPartyWebForms/xrds.aspx
+++ b/samples/OpenIdRelyingPartyWebForms/xrds.aspx
@@ -17,7 +17,9 @@ is default.aspx.
<URI priority="1"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/login.aspx"))%></URI>
<URI priority="2"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginProgrammatic.aspx"))%></URI>
<URI priority="3"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/ajaxlogin.aspx"))%></URI>
- <URI priority="3"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/NoIdentityOpenId.aspx"))%></URI>
+ <URI priority="4"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/NoIdentityOpenId.aspx"))%></URI>
+ <URI priority="5"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginPlusOAuth.aspx"))%></URI>
+ <URI priority="6"><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/loginPlusOAuthSampleOP.aspx"))%></URI>
</Service>
<Service>
<Type>http://specs.openid.net/extensions/ui/icon</Type>
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs
new file mode 100644
index 0000000..3ad5eb0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeAssemblyReference.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Xml;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.BuildEngine;
+
+namespace DotNetOpenAuth.BuildTasks {
+ /// <summary>
+ /// Replaces Reference items HintPaths in a set of projects.
+ /// </summary>
+ public class ChangeAssemblyReference : Task {
+ /// <summary>
+ /// The projects to alter.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Projects { get; set; }
+ /// <summary>
+ /// The project reference to remove.
+ /// </summary>
+ [Required]
+ public string OldReference { get; set; }
+ /// <summary>
+ /// The assembly reference to add.
+ /// </summary>
+ [Required]
+ public string NewReference { get; set; }
+
+ const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+ public override bool Execute() {
+ foreach (var project in Projects) {
+ Project doc = new Project();
+ doc.Load(project.ItemSpec);
+
+ var reference = doc.GetEvaluatedItemsByName("Reference").OfType<BuildItem>().
+ Where(item => string.Equals(item.GetMetadata("HintPath"), OldReference, StringComparison.OrdinalIgnoreCase)).Single();
+ reference.SetMetadata("HintPath", NewReference);
+
+ doc.Save(project.ItemSpec);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
new file mode 100644
index 0000000..973d8d6
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ChangeProjectReferenceToAssemblyReference.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using System.IO;
+using System.Xml;
+
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.BuildEngine;
+
+namespace DotNetOpenAuth.BuildTasks {
+ /// <summary>
+ /// Replaces ProjectReference items in a set of projects with Reference items.
+ /// </summary>
+ public class ChangeProjectReferenceToAssemblyReference : Task {
+ /// <summary>
+ /// The projects to alter.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Projects { get; set; }
+ /// <summary>
+ /// The project reference to remove.
+ /// </summary>
+ [Required]
+ public string ProjectReference { get; set; }
+ /// <summary>
+ /// The assembly reference to add.
+ /// </summary>
+ [Required]
+ public string Reference { get; set; }
+
+ const string msbuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+ public override bool Execute() {
+ foreach (var project in Projects) {
+ Log.LogMessage(MessageImportance.Normal, "Changing P2P references to assembly references in \"{0}\".", project.ItemSpec);
+
+ Project doc = new Project();
+ doc.Load(project.ItemSpec);
+
+ var projectReference = doc.EvaluatedItems.OfType<BuildItem>().Where(
+ item => item.Name == "ProjectReference" && item.Include == ProjectReference).Single();
+ doc.RemoveItem(projectReference);
+
+ var newReference = doc.AddNewItem("Reference", Path.GetFileNameWithoutExtension(Reference));
+ newReference.SetMetadata("HintPath", Reference);
+
+ doc.Save(project.ItemSpec);
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs
new file mode 100644
index 0000000..9cfd35d
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CheckAdminRights.cs
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------
+// <copyright file="CheckAdminRights.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System.Security.Principal;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ public class CheckAdminRights : Task {
+ /// <summary>
+ /// Gets or sets a value indicating whether this process has elevated permissions.
+ /// </summary>
+ [Output]
+ public bool IsElevated { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ WindowsIdentity id = WindowsIdentity.GetCurrent();
+ WindowsPrincipal p = new WindowsPrincipal(id);
+ this.IsElevated = p.IsInRole(WindowsBuiltInRole.Administrator);
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs
new file mode 100644
index 0000000..691df20
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CompareFiles.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+using System.IO;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class CompareFiles : Task {
+ /// <summary>
+ /// One set of items to compare.
+ /// </summary>
+ [Required]
+ public ITaskItem[] OriginalItems { get; set; }
+
+ /// <summary>
+ /// The other set of items to compare.
+ /// </summary>
+ [Required]
+ public ITaskItem[] NewItems { get; set; }
+
+ /// <summary>
+ /// Gets whether the items lists contain items that are identical going down the list.
+ /// </summary>
+ [Output]
+ public bool AreSame { get; private set; }
+
+ /// <summary>
+ /// Same as <see cref="AreSame"/>, but opposite.
+ /// </summary>
+ [Output]
+ public bool AreChanged { get { return !AreSame; } }
+
+ public override bool Execute() {
+ AreSame = AreFilesIdentical();
+ return true;
+ }
+
+ private bool AreFilesIdentical() {
+ if (OriginalItems.Length != NewItems.Length) {
+ return false;
+ }
+
+ for (int i = 0; i < OriginalItems.Length; i++) {
+ if (!IsContentOfFilesTheSame(OriginalItems[i].ItemSpec, NewItems[i].ItemSpec)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private bool IsContentOfFilesTheSame(string file1, string file2) {
+ // If exactly one file is missing, that's different.
+ if (File.Exists(file1) ^ File.Exists(file2)) return false;
+ // If both are missing, that's the same.
+ if (!File.Exists(file1)) return true;
+ // If both are present, we need to do a content comparison.
+ using (FileStream fileStream1 = File.OpenRead(file1)) {
+ using (FileStream fileStream2 = File.OpenRead(file2)) {
+ if (fileStream1.Length != fileStream2.Length) return false;
+ byte[] buffer1 = new byte[4096];
+ byte[] buffer2 = new byte[buffer1.Length];
+ int bytesRead;
+ do {
+ bytesRead = fileStream1.Read(buffer1, 0, buffer1.Length);
+ if (fileStream2.Read(buffer2, 0, buffer2.Length) != bytesRead) {
+ // We should never get here since we compared file lengths, but
+ // this is a sanity check.
+ return false;
+ }
+ for (int i = 0; i < bytesRead; i++) {
+ if (buffer1[i] != buffer2[i]) {
+ return false;
+ }
+ }
+ } while (bytesRead == buffer1.Length);
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
new file mode 100644
index 0000000..3b81978
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------
+// <copyright file="CopyWithTokenSubstitution.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Copies files and performs a search and replace for given tokens in their contents during the process.
+ /// </summary>
+ public class CopyWithTokenSubstitution : Task {
+ /// <summary>
+ /// Gets or sets a value indicating whether the task should
+ /// skip the copying of files that are unchanged between the source and destination.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> to skip copying files where the destination files are newer than the source files; otherwise, <c>false</c> to copy all files.
+ /// </value>
+ public bool SkipUnchangedFiles { get; set; }
+
+ /// <summary>
+ /// Gets or sets the files to copy.
+ /// </summary>
+ /// <value>The files to copy.</value>
+ [Required]
+ public ITaskItem[] SourceFiles { get; set; }
+
+ /// <summary>
+ /// Gets or sets a list of files to copy the source files to.
+ /// </summary>
+ /// <value>The list of files to copy the source files to.</value>
+ [Required]
+ public ITaskItem[] DestinationFiles { get; set; }
+
+ /// <summary>
+ /// Gets or sets the destination files actually copied to.
+ /// </summary>
+ /// <remarks>
+ /// In the case of error partway through, or files not copied due to already being up to date,
+ /// this can be a subset of the <see cref="DestinationFiles"/> array.
+ /// </remarks>
+ [Output]
+ public ITaskItem[] CopiedFiles { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns><c>true</c> if the operation was successful.</returns>
+ public override bool Execute() {
+ if (this.SourceFiles.Length != this.DestinationFiles.Length) {
+ Log.LogError("{0} inputs and {1} outputs given.", this.SourceFiles.Length, this.DestinationFiles.Length);
+ return false;
+ }
+
+ var copiedFiles = new List<ITaskItem>(this.DestinationFiles.Length);
+
+ for (int i = 0; i < this.SourceFiles.Length; i++) {
+ string sourcePath = this.SourceFiles[i].ItemSpec;
+ string destPath = this.DestinationFiles[i].ItemSpec;
+
+ if (this.SkipUnchangedFiles && File.GetLastWriteTimeUtc(sourcePath) < File.GetLastWriteTimeUtc(destPath)) {
+ Log.LogMessage(MessageImportance.Low, "Skipping \"{0}\" -> \"{1}\" because the destination is up to date.", sourcePath, destPath);
+ continue;
+ }
+
+ Log.LogMessage(MessageImportance.Normal, "Transforming \"{0}\" -> \"{1}\"", sourcePath, destPath);
+
+ string[] beforeTokens = this.SourceFiles[i].GetMetadata("BeforeTokens").Split(';');
+ string[] afterTokens = this.SourceFiles[i].GetMetadata("AfterTokens").Split(';');
+ if (beforeTokens.Length != afterTokens.Length) {
+ Log.LogError("Unequal number of before and after tokens. Before: \"{0}\". After \"{1}\".", beforeTokens, afterTokens);
+ return false;
+ }
+
+ using (StreamReader sr = File.OpenText(sourcePath)) {
+ if (!Directory.Exists(Path.GetDirectoryName(destPath))) {
+ Directory.CreateDirectory(Path.GetDirectoryName(destPath));
+ }
+ using (StreamWriter sw = File.CreateText(destPath)) {
+ StringBuilder line = new StringBuilder();
+ while (!sr.EndOfStream) {
+ line.Length = 0;
+ line.Append(sr.ReadLine());
+ for (int j = 0; j < beforeTokens.Length; j++) {
+ line.Replace(beforeTokens[j], afterTokens[j]);
+ }
+
+ sw.WriteLine(line);
+ }
+ }
+ }
+
+ copiedFiles.Add(this.DestinationFiles[i]);
+ }
+
+ this.CopiedFiles = copiedFiles.ToArray();
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs
new file mode 100644
index 0000000..4980898
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CreateWebApplication.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="CreateWebApplication.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Web.Administration;
+
+ /// <summary>
+ /// Creates or updates web applications within an existing web site in IIS.
+ /// </summary>
+ public class CreateWebApplication : Task {
+ /// <summary>
+ /// Gets or sets the name of the application pool that should host the web application.
+ /// </summary>
+ /// <value>The name of an existing application pool.</value>
+ public string ApplicationPoolName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the web site under which to create the web application.
+ /// </summary>
+ /// <value>The name of the existing web site.</value>
+ [Required]
+ public string WebSiteName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the virtual paths within the web site that will access these applications.
+ /// </summary>
+ /// <value>The virtual path, which must start with '/'.</value>
+ [Required]
+ public ITaskItem[] VirtualPaths { get; set; }
+
+ /// <summary>
+ /// Gets or sets the full file system paths to the web applications.
+ /// </summary>
+ /// <value>The physical path.</value>
+ [Required]
+ public ITaskItem[] PhysicalPaths { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ var serverManager = new ServerManager();
+
+ if (this.PhysicalPaths.Length != this.VirtualPaths.Length) {
+ Log.LogError(TaskStrings.MismatchingArrayLengths, "PhysicalPath", "VirtualPath");
+ return false;
+ }
+
+ if (this.VirtualPaths.Length == 0) {
+ // Nothing to do.
+ return true;
+ }
+
+ // Find the root web site that this web application will be created under.
+ var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase));
+ if (site == null) {
+ Log.LogError(TaskStrings.NoMatchingWebSiteFound, this.WebSiteName);
+ return false;
+ }
+
+ Log.LogMessage(MessageImportance.Normal, "Creating web applications under web site: {0}", site.Name);
+
+ for (int i = 0; i < this.PhysicalPaths.Length; i++) {
+ string physicalPath = this.PhysicalPaths[i].ItemSpec;
+ string virtualPath = this.VirtualPaths[i].ItemSpec;
+
+ Log.LogMessage(MessageImportance.Normal, "\t{0} -> {1}", virtualPath, physicalPath);
+
+ var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, virtualPath, StringComparison.OrdinalIgnoreCase));
+ if (app == null) {
+ app = site.Applications.Add(virtualPath, physicalPath);
+ } else {
+ // Ensure physical path is set correctly.
+ var appRoot = app.VirtualDirectories.First(vd => vd.Path == "/");
+ appRoot.PhysicalPath = physicalPath;
+ }
+
+ if (!string.IsNullOrEmpty(this.ApplicationPoolName)) {
+ app.ApplicationPoolName = this.ApplicationPoolName;
+ }
+ }
+
+ serverManager.CommitChanges();
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln
new file mode 100644
index 0000000..6eae4e0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/CustomMsBuildTasks.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AC231A51-EF60-437C-A33F-AF8ADEB8EB74}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs
new file mode 100644
index 0000000..930a8c4
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DeleteWebApplication.cs
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------
+// <copyright file="DeleteWebApplication.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Web.Administration;
+
+ /// <summary>
+ /// Deletes a web application from IIS.
+ /// </summary>
+ public class DeleteWebApplication : Task {
+ /// <summary>
+ /// Gets or sets the name of the web site under which to create the web application.
+ /// </summary>
+ /// <value>The name of the existing web site.</value>
+ [Required]
+ public string WebSiteName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the virtual paths within the web site that will access these applications.
+ /// </summary>
+ /// <value>The virtual path, which must start with '/'.</value>
+ [Required]
+ public ITaskItem[] VirtualPaths { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ var serverManager = new ServerManager();
+
+ // Find the root web site that this web application will be created under.
+ var site = serverManager.Sites.FirstOrDefault(s => string.Equals(s.Name, this.WebSiteName, StringComparison.OrdinalIgnoreCase));
+ if (site == null) {
+ Log.LogMessage(MessageImportance.Low, TaskStrings.NoMatchingWebSiteFound, this.WebSiteName);
+ return true;
+ }
+
+ if (this.VirtualPaths.Length == 0) {
+ // Nothing to do.
+ return true;
+ }
+
+ foreach (ITaskItem path in this.VirtualPaths) {
+ var app = site.Applications.FirstOrDefault(a => string.Equals(a.Path, path.ItemSpec, StringComparison.OrdinalIgnoreCase));
+ if (app != null) {
+ site.Applications.Remove(app);
+ Log.LogMessage(MessageImportance.Normal, TaskStrings.DeletedWebApplication, app.Path);
+ } else {
+ Log.LogMessage(MessageImportance.Low, TaskStrings.WebApplicationNotFoundSoNotDeleted, path.ItemSpec);
+ }
+ }
+
+ serverManager.CommitChanges();
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
new file mode 100644
index 0000000..3b22fff
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DotNetOpenAuth.BuildTasks</RootNamespace>
+ <AssemblyName>DotNetOpenAuth.BuildTasks</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>..\..\lib\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>..\..\lib\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.Build.Engine" />
+ <Reference Include="Microsoft.Build.Framework" />
+ <Reference Include="Microsoft.Build.Utilities.v3.5">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>$(SystemRoot)\System32\inetsrv\Microsoft.Web.Administration.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ChangeProjectReferenceToAssemblyReference.cs" />
+ <Compile Include="CompareFiles.cs" />
+ <Compile Include="ChangeAssemblyReference.cs" />
+ <Compile Include="CopyWithTokenSubstitution.cs" />
+ <Compile Include="CreateWebApplication.cs" />
+ <Compile Include="DeleteWebApplication.cs" />
+ <Compile Include="ECMAScriptPacker.cs" />
+ <Compile Include="FilterItems.cs" />
+ <Compile Include="GetBuildVersion.cs" />
+ <Compile Include="CheckAdminRights.cs" />
+ <Compile Include="JsPack.cs" />
+ <Compile Include="ParseMaster.cs" />
+ <Compile Include="ReSignDelaySignedAssemblies.cs" />
+ <Compile Include="SetEnvironmentVariable.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SignatureVerification.cs" />
+ <Compile Include="SnToolTask.cs" />
+ <Compile Include="TaskStrings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>TaskStrings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Trim.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="TaskStrings.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>TaskStrings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.BuildTasks/ECMAScriptPacker.cs b/src/DotNetOpenAuth.BuildTasks/ECMAScriptPacker.cs
new file mode 100644
index 0000000..d63d5b4
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ECMAScriptPacker.cs
@@ -0,0 +1,486 @@
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Web;
+using System.IO;
+
+/*
+ packer, version 2.0 (beta) (2005/02/01)
+ Copyright 2004-2005, Dean Edwards
+ Web: http://dean.edwards.name/
+
+ This software is licensed under the CC-GNU LGPL
+ Web: http://creativecommons.org/licenses/LGPL/2.1/
+
+ Ported to C# by Jesse Hansen, twindagger2k@msn.com
+ modified slightly by Andrew Arnott
+*/
+
+// http://dean.edwards.name/packer/
+
+namespace Dean.Edwards
+{
+ /// <summary>
+ /// Packs a javascript file into a smaller area, removing unnecessary characters from the output.
+ /// </summary>
+ internal class ECMAScriptPacker
+ {
+ /// <summary>
+ /// The encoding level to use. See http://dean.edwards.name/packer/usage/ for more info.
+ /// </summary>
+ public enum PackerEncoding { None = 0, Numeric = 10, Mid = 36, Normal = 62, HighAscii = 95 };
+
+ private PackerEncoding encoding = PackerEncoding.Normal;
+ private bool fastDecode = true;
+ private bool specialChars = false;
+ private bool enabled = true;
+
+ string IGNORE = "$1";
+
+ /// <summary>
+ /// The encoding level for this instance
+ /// </summary>
+ public PackerEncoding Encoding
+ {
+ get { return encoding; }
+ set { encoding = value; }
+ }
+
+ /// <summary>
+ /// Adds a subroutine to the output to speed up decoding
+ /// </summary>
+ public bool FastDecode
+ {
+ get { return fastDecode; }
+ set { fastDecode = value; }
+ }
+
+ /// <summary>
+ /// Replaces special characters
+ /// </summary>
+ public bool SpecialChars
+ {
+ get { return specialChars; }
+ set { specialChars = value; }
+ }
+
+ /// <summary>
+ /// Packer enabled
+ /// </summary>
+ public bool Enabled
+ {
+ get { return enabled; }
+ set { enabled = value; }
+ }
+
+ public ECMAScriptPacker()
+ {
+ Encoding = PackerEncoding.Normal;
+ FastDecode = true;
+ SpecialChars = false;
+ }
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="encoding">The encoding level for this instance</param>
+ /// <param name="fastDecode">Adds a subroutine to the output to speed up decoding</param>
+ /// <param name="specialChars">Replaces special characters</param>
+ public ECMAScriptPacker(PackerEncoding encoding, bool fastDecode, bool specialChars)
+ {
+ Encoding = encoding;
+ FastDecode = fastDecode;
+ SpecialChars = specialChars;
+ }
+
+ /// <summary>
+ /// Packs the script
+ /// </summary>
+ /// <param name="script">the script to pack</param>
+ /// <returns>the packed script</returns>
+ public string Pack(string script)
+ {
+ if (enabled)
+ {
+ script += "\n";
+ script = basicCompression(script);
+ if (SpecialChars)
+ script = encodeSpecialChars(script);
+ if (Encoding != PackerEncoding.None)
+ script = encodeKeywords(script);
+ }
+ return script;
+ }
+
+ //zero encoding - just removal of whitespace and comments
+ private string basicCompression(string script)
+ {
+ ParseMaster parser = new ParseMaster();
+ // make safe
+ parser.EscapeChar = '\\';
+ // protect strings
+ parser.Add("'[^'\\n\\r]*'", IGNORE);
+ parser.Add("\"[^\"\\n\\r]*\"", IGNORE);
+ // remove comments
+ parser.Add("\\/\\/[^\\n\\r]*[\\n\\r]");
+ parser.Add("\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/");
+ // protect regular expressions
+ parser.Add("\\s+(\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?)", "$2");
+ parser.Add("[^\\w\\$\\/'\"*)\\?:]\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?", IGNORE);
+ // remove: ;;; doSomething();
+ if (specialChars)
+ parser.Add(";;[^\\n\\r]+[\\n\\r]");
+ // remove redundant semi-colons
+ parser.Add(";+\\s*([};])", "$2");
+ // remove white-space
+ parser.Add("(\\b|\\$)\\s+(\\b|\\$)", "$2 $3");
+ parser.Add("([+\\-])\\s+([+\\-])", "$2 $3");
+ parser.Add("\\s+");
+ // done
+ return parser.Exec(script);
+ }
+
+ WordList encodingLookup;
+ private string encodeSpecialChars(string script)
+ {
+ ParseMaster parser = new ParseMaster();
+ // replace: $name -> n, $$name -> na
+ parser.Add("((\\$+)([a-zA-Z\\$_]+))(\\d*)",
+ new ParseMaster.MatchGroupEvaluator(encodeLocalVars));
+
+ // replace: _name -> _0, double-underscore (__name) is ignored
+ Regex regex = new Regex("\\b_[A-Za-z\\d]\\w*");
+
+ // build the word list
+ encodingLookup = analyze(script, regex, new EncodeMethod(encodePrivate));
+
+ parser.Add("\\b_[A-Za-z\\d]\\w*", new ParseMaster.MatchGroupEvaluator(encodeWithLookup));
+
+ script = parser.Exec(script);
+ return script;
+ }
+
+ private string encodeKeywords(string script)
+ {
+ // escape high-ascii values already in the script (i.e. in strings)
+ if (Encoding == PackerEncoding.HighAscii) script = escape95(script);
+ // create the parser
+ ParseMaster parser = new ParseMaster();
+ EncodeMethod encode = getEncoder(Encoding);
+
+ // for high-ascii, don't encode single character low-ascii
+ Regex regex = new Regex(
+ (Encoding == PackerEncoding.HighAscii) ? "\\w\\w+" : "\\w+"
+ );
+ // build the word list
+ encodingLookup = analyze(script, regex, encode);
+
+ // encode
+ parser.Add((Encoding == PackerEncoding.HighAscii) ? "\\w\\w+" : "\\w+",
+ new ParseMaster.MatchGroupEvaluator(encodeWithLookup));
+
+ // if encoded, wrap the script in a decoding function
+ return (script == string.Empty) ? "" : bootStrap(parser.Exec(script), encodingLookup);
+ }
+
+ private string bootStrap(string packed, WordList keywords)
+ {
+ // packed: the packed script
+ packed = "'" + escape(packed) + "'";
+
+ // ascii: base for encoding
+ int ascii = Math.Min(keywords.Sorted.Count, (int) Encoding);
+ if (ascii == 0)
+ ascii = 1;
+
+ // count: number of words contained in the script
+ int count = keywords.Sorted.Count;
+
+ // keywords: list of words contained in the script
+ foreach (object key in keywords.Protected.Keys)
+ {
+ keywords.Sorted[(int) key] = "";
+ }
+ // convert from a string to an array
+ StringBuilder sbKeywords = new StringBuilder("'");
+ foreach (string word in keywords.Sorted)
+ sbKeywords.Append(word + "|");
+ sbKeywords.Remove(sbKeywords.Length-1, 1);
+ string keywordsout = sbKeywords.ToString() + "'.split('|')";
+
+ string encode;
+ string inline = "c";
+
+ switch (Encoding)
+ {
+ case PackerEncoding.Mid:
+ encode = "function(c){return c.toString(36)}";
+ inline += ".toString(a)";
+ break;
+ case PackerEncoding.Normal:
+ encode = "function(c){return(c<a?\"\":e(parseInt(c/a)))+" +
+ "((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))}";
+ inline += ".toString(a)";
+ break;
+ case PackerEncoding.HighAscii:
+ encode = "function(c){return(c<a?\"\":e(c/a))+" +
+ "String.fromCharCode(c%a+161)}";
+ inline += ".toString(a)";
+ break;
+ default:
+ encode = "function(c){return c}";
+ break;
+ }
+
+ // decode: code snippet to speed up decoding
+ string decode = "";
+ if (fastDecode)
+ {
+ decode = "if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\\\w+'};c=1;}";
+ if (Encoding == PackerEncoding.HighAscii)
+ decode = decode.Replace("\\\\w", "[\\xa1-\\xff]");
+ else if (Encoding == PackerEncoding.Numeric)
+ decode = decode.Replace("e(c)", inline);
+ if (count == 0)
+ decode = decode.Replace("c=1", "c=0");
+ }
+
+ // boot function
+ string unpack = "function(p,a,c,k,e,d){while(c--)if(k[c])p=p.replace(new RegExp('\\\\b'+e(c)+'\\\\b','g'),k[c]);return p;}";
+ Regex r;
+ if (fastDecode)
+ {
+ //insert the decoder
+ r = new Regex("\\{");
+ unpack = r.Replace(unpack, "{" + decode + ";", 1);
+ }
+
+ if (Encoding == PackerEncoding.HighAscii)
+ {
+ // get rid of the word-boundries for regexp matches
+ r = new Regex("'\\\\\\\\b'\\s*\\+|\\+\\s*'\\\\\\\\b'");
+ unpack = r.Replace(unpack, "");
+ }
+ if (Encoding == PackerEncoding.HighAscii || ascii > (int) PackerEncoding.Normal || fastDecode)
+ {
+ // insert the encode function
+ r = new Regex("\\{");
+ unpack = r.Replace(unpack, "{e=" + encode + ";", 1);
+ }
+ else
+ {
+ r = new Regex("e\\(c\\)");
+ unpack = r.Replace(unpack, inline);
+ }
+ // no need to pack the boot function since i've already done it
+ string _params = "" + packed + "," + ascii + "," + count + "," + keywordsout;
+ if (fastDecode)
+ {
+ //insert placeholders for the decoder
+ _params += ",0,{}";
+ }
+ // the whole thing
+ return "eval(" + unpack + "(" + _params + "))\n";
+ }
+
+ private string escape(string input)
+ {
+ Regex r = new Regex("([\\\\'])");
+ return r.Replace(input, "\\$1");
+ }
+
+ private EncodeMethod getEncoder(PackerEncoding encoding)
+ {
+ switch (encoding)
+ {
+ case PackerEncoding.Mid:
+ return new EncodeMethod(encode36);
+ case PackerEncoding.Normal:
+ return new EncodeMethod(encode62);
+ case PackerEncoding.HighAscii:
+ return new EncodeMethod(encode95);
+ default:
+ return new EncodeMethod(encode10);
+ }
+ }
+
+ private string encode10(int code)
+ {
+ return code.ToString();
+ }
+
+ //lookups seemed like the easiest way to do this since
+ // I don't know of an equivalent to .toString(36)
+ private static string lookup36 = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+ private string encode36(int code)
+ {
+ string encoded = "";
+ int i = 0;
+ do
+ {
+ int digit = (code / (int) Math.Pow(36, i)) % 36;
+ encoded = lookup36[digit] + encoded;
+ code -= digit * (int) Math.Pow(36, i++);
+ } while (code > 0);
+ return encoded;
+ }
+
+ private static string lookup62 = lookup36 + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ private string encode62(int code)
+ {
+ string encoded = "";
+ int i = 0;
+ do
+ {
+ int digit = (code / (int) Math.Pow(62, i)) % 62;
+ encoded = lookup62[digit] + encoded;
+ code -= digit * (int) Math.Pow(62, i++);
+ } while (code > 0);
+ return encoded;
+ }
+
+ private static string lookup95 = "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
+
+ private string encode95(int code)
+ {
+ string encoded = "";
+ int i = 0;
+ do
+ {
+ int digit = (code / (int) Math.Pow(95, i)) % 95;
+ encoded = lookup95[digit] + encoded;
+ code -= digit * (int) Math.Pow(95, i++);
+ } while (code > 0);
+ return encoded;
+ }
+
+ private string escape95(string input)
+ {
+ Regex r = new Regex("[\xa1-\xff]");
+ return r.Replace(input, new MatchEvaluator(escape95Eval));
+ }
+
+ private string escape95Eval(Match match)
+ {
+ return "\\x" + ((int) match.Value[0]).ToString("x"); //return hexadecimal value
+ }
+
+ private string encodeLocalVars(Match match, int offset)
+ {
+ int length = match.Groups[offset + 2].Length;
+ int start = length - Math.Max(length - match.Groups[offset + 3].Length, 0);
+ return match.Groups[offset + 1].Value.Substring(start, length) +
+ match.Groups[offset + 4].Value;
+ }
+
+ private string encodeWithLookup(Match match, int offset)
+ {
+ return (string) encodingLookup.Encoded[match.Groups[offset].Value];
+ }
+
+ private delegate string EncodeMethod(int code);
+
+ private string encodePrivate(int code)
+ {
+ return "_" + code;
+ }
+
+ private WordList analyze(string input, Regex regex, EncodeMethod encodeMethod)
+ {
+ // analyse
+ // retreive all words in the script
+ MatchCollection all = regex.Matches(input);
+ WordList rtrn;
+ rtrn.Sorted = new StringCollection(); // list of words sorted by frequency
+ rtrn.Protected = new HybridDictionary(); // dictionary of word->encoding
+ rtrn.Encoded = new HybridDictionary(); // instances of "protected" words
+ if (all.Count > 0)
+ {
+ StringCollection unsorted = new StringCollection(); // same list, not sorted
+ HybridDictionary Protected = new HybridDictionary(); // "protected" words (dictionary of word->"word")
+ HybridDictionary values = new HybridDictionary(); // dictionary of charCode->encoding (eg. 256->ff)
+ HybridDictionary count = new HybridDictionary(); // word->count
+ int i = all.Count, j = 0;
+ string word;
+ // count the occurrences - used for sorting later
+ do
+ {
+ word = "$" + all[--i].Value;
+ if (count[word] == null)
+ {
+ count[word] = 0;
+ unsorted.Add(word);
+ // make a dictionary of all of the protected words in this script
+ // these are words that might be mistaken for encoding
+ Protected["$" + (values[j] = encodeMethod(j))] = j++;
+ }
+ // increment the word counter
+ count[word] = (int) count[word] + 1;
+ } while (i > 0);
+ /* prepare to sort the word list, first we must protect
+ words that are also used as codes. we assign them a code
+ equivalent to the word itself.
+ e.g. if "do" falls within our encoding range
+ then we store keywords["do"] = "do";
+ this avoids problems when decoding */
+ i = unsorted.Count;
+ string[] sortedarr = new string[unsorted.Count];
+ do
+ {
+ word = unsorted[--i];
+ if (Protected[word] != null)
+ {
+ sortedarr[(int) Protected[word]] = word.Substring(1);
+ rtrn.Protected[(int) Protected[word]] = true;
+ count[word] = 0;
+ }
+ } while (i > 0);
+ string[] unsortedarr = new string[unsorted.Count];
+ unsorted.CopyTo(unsortedarr, 0);
+ // sort the words by frequency
+ Array.Sort(unsortedarr, (IComparer) new CountComparer(count));
+ j = 0;
+ /*because there are "protected" words in the list
+ we must add the sorted words around them */
+ do
+ {
+ if (sortedarr[i] == null)
+ sortedarr[i] = unsortedarr[j++].Substring(1);
+ rtrn.Encoded[sortedarr[i]] = values[i];
+ } while (++i < unsortedarr.Length);
+ rtrn.Sorted.AddRange(sortedarr);
+ }
+ return rtrn;
+ }
+
+ private struct WordList
+ {
+ public StringCollection Sorted;
+ public HybridDictionary Encoded;
+ public HybridDictionary Protected;
+ }
+
+ private class CountComparer : IComparer
+ {
+ HybridDictionary count;
+
+ public CountComparer(HybridDictionary count)
+ {
+ this.count = count;
+ }
+
+ #region IComparer Members
+
+ public int Compare(object x, object y)
+ {
+ return (int) count[y] - (int) count[x];
+ }
+
+ #endregion
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/FilterItems.cs b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs
new file mode 100644
index 0000000..97631c6
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/FilterItems.cs
@@ -0,0 +1,24 @@
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.Build.Utilities;
+ using Microsoft.Build.Framework;
+
+ public class FilterItems : Task {
+ [Required]
+ public ITaskItem[] InputItems { get; set; }
+
+ [Required]
+ public ITaskItem[] StartsWithAny { get; set; }
+
+ [Output]
+ public ITaskItem[] FilteredItems { get; set; }
+
+ public override bool Execute() {
+ FilteredItems = InputItems.Where(item => StartsWithAny.Any(filter => item.ItemSpec.StartsWith(filter.ItemSpec, StringComparison.OrdinalIgnoreCase))).ToArray();
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs
new file mode 100644
index 0000000..e40eb78
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/GetBuildVersion.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+using System.IO;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class GetBuildVersion : Task {
+
+ /// <summary>
+ /// Gets the version string to use in the compiled assemblies.
+ /// </summary>
+ [Output]
+ public string Version { get; private set; }
+
+ /// <summary>
+ /// The file that contains the version base (Major.Minor.Build) to use.
+ /// </summary>
+ [Required]
+ public string VersionFile { get; set; }
+
+ public override bool Execute() {
+ try {
+ Version typedVersion = ReadVersionFromFile();
+ typedVersion = new Version(typedVersion.Major, typedVersion.Minor, typedVersion.Build, CalculateJDate(DateTime.Now));
+ Version = typedVersion.ToString();
+ } catch (ArgumentOutOfRangeException ex) {
+ Log.LogErrorFromException(ex);
+ return false;
+ }
+
+ return true;
+ }
+
+ private Version ReadVersionFromFile() {
+ string[] lines = File.ReadAllLines(VersionFile);
+ string versionLine = lines[0];
+ return new Version(versionLine);
+ }
+
+ private int CalculateJDate(DateTime date) {
+ int yearLastDigit = date.Year % 10;
+ DateTime firstOfYear = new DateTime(date.Year, 1, 1);
+ int dayOfYear = (date - firstOfYear).Days + 1;
+ int jdate = yearLastDigit * 1000 + dayOfYear;
+ return jdate;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/JsPack.cs b/src/DotNetOpenAuth.BuildTasks/JsPack.cs
new file mode 100644
index 0000000..fa8c7f0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/JsPack.cs
@@ -0,0 +1,75 @@
+//-----------------------------------------------------------------------
+// <copyright file="JsPack.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Compresses .js files.
+ /// </summary>
+ public class JsPack : Task {
+ /// <summary>
+ /// The Javascript packer to use.
+ /// </summary>
+ private Dean.Edwards.ECMAScriptPacker packer = new Dean.Edwards.ECMAScriptPacker();
+
+ /// <summary>
+ /// Gets or sets the set of javascript files to compress.
+ /// </summary>
+ /// <value>The inputs.</value>
+ [Required]
+ public ITaskItem[] Inputs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the paths where the packed javascript files should be saved.
+ /// </summary>
+ /// <value>The outputs.</value>
+ [Required]
+ public ITaskItem[] Outputs { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the packing was successful.</returns>
+ public override bool Execute() {
+ if (this.Inputs.Length != this.Outputs.Length) {
+ Log.LogError("{0} inputs and {1} outputs given.", this.Inputs.Length, this.Outputs.Length);
+ return false;
+ }
+
+ for (int i = 0; i < this.Inputs.Length; i++) {
+ if (!File.Exists(this.Outputs[i].ItemSpec) || File.GetLastWriteTime(this.Outputs[i].ItemSpec) < File.GetLastWriteTime(this.Inputs[i].ItemSpec)) {
+ Log.LogMessage(MessageImportance.Normal, TaskStrings.PackingJsFile, this.Inputs[i].ItemSpec, this.Outputs[i].ItemSpec);
+ string input = File.ReadAllText(this.Inputs[i].ItemSpec);
+ string output = this.packer.Pack(input);
+ if (!Directory.Exists(Path.GetDirectoryName(this.Outputs[i].ItemSpec))) {
+ Directory.CreateDirectory(Path.GetDirectoryName(this.Outputs[i].ItemSpec));
+ }
+
+ // Minification removes all comments, including copyright notices
+ // that must remain. So if there's metadata on this item with
+ // a copyright notice on it, stick it on the front of the file.
+ string copyright = this.Inputs[i].GetMetadata("Copyright");
+ if (!string.IsNullOrEmpty(copyright)) {
+ output = "/*" + copyright + "*/" + output;
+ }
+
+ File.WriteAllText(this.Outputs[i].ItemSpec, output, Encoding.UTF8);
+ } else {
+ Log.LogMessage(MessageImportance.Low, TaskStrings.SkipPackingJsFile, this.Inputs[i].ItemSpec);
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/ParseMaster.cs b/src/DotNetOpenAuth.BuildTasks/ParseMaster.cs
new file mode 100644
index 0000000..7edba29
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ParseMaster.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Collections;
+using System.Collections.Specialized;
+
+/*
+ ParseMaster, version 1.0 (pre-release) (2005/02/01) x4
+ Copyright 2005, Dean Edwards
+ Web: http://dean.edwards.name/
+
+ This software is licensed under the CC-GNU LGPL
+ Web: http://creativecommons.org/licenses/LGPL/2.1/
+
+ Ported to C# by Jesse Hansen, twindagger2k@msn.com
+*/
+
+namespace Dean.Edwards
+{
+ /// <summary>
+ /// a multi-pattern parser
+ /// </summary>
+ internal class ParseMaster
+ {
+ // used to determine nesting levels
+ Regex GROUPS = new Regex("\\("),
+ SUB_REPLACE = new Regex("\\$"),
+ INDEXED = new Regex("^\\$\\d+$"),
+ ESCAPE = new Regex("\\\\."),
+ QUOTE = new Regex("'"),
+ DELETED = new Regex("\\x01[^\\x01]*\\x01");
+
+ /// <summary>
+ /// Delegate to call when a regular expression is found.
+ /// Use match.Groups[offset + &lt;group number&gt;].Value to get
+ /// the correct subexpression
+ /// </summary>
+ public delegate string MatchGroupEvaluator(Match match, int offset);
+
+ private string DELETE(Match match, int offset)
+ {
+ return "\x01" + match.Groups[offset].Value + "\x01";
+ }
+
+ private bool ignoreCase = false;
+ private char escapeChar = '\0';
+
+ /// <summary>
+ /// Ignore Case?
+ /// </summary>
+ public bool IgnoreCase
+ {
+ get { return ignoreCase; }
+ set { ignoreCase = value; }
+ }
+
+ /// <summary>
+ /// Escape Character to use
+ /// </summary>
+ public char EscapeChar
+ {
+ get { return escapeChar; }
+ set { escapeChar = value; }
+ }
+
+ /// <summary>
+ /// Add an expression to be deleted
+ /// </summary>
+ /// <param name="expression">Regular Expression String</param>
+ public void Add(string expression)
+ {
+ Add(expression, string.Empty);
+ }
+
+ /// <summary>
+ /// Add an expression to be replaced with the replacement string
+ /// </summary>
+ /// <param name="expression">Regular Expression String</param>
+ /// <param name="replacement">Replacement String. Use $1, $2, etc. for groups</param>
+ public void Add(string expression, string replacement)
+ {
+ if (replacement == string.Empty)
+ add(expression, new MatchGroupEvaluator(DELETE));
+
+ add(expression, replacement);
+ }
+
+ /// <summary>
+ /// Add an expression to be replaced using a callback function
+ /// </summary>
+ /// <param name="expression">Regular expression string</param>
+ /// <param name="replacement">Callback function</param>
+ public void Add(string expression, MatchGroupEvaluator replacement)
+ {
+ add(expression, replacement);
+ }
+
+ /// <summary>
+ /// Executes the parser
+ /// </summary>
+ /// <param name="input">input string</param>
+ /// <returns>parsed string</returns>
+ public string Exec(string input)
+ {
+ return DELETED.Replace(unescape(getPatterns().Replace(escape(input), new MatchEvaluator(replacement))), string.Empty);
+ //long way for debugging
+ /*input = escape(input);
+ Regex patterns = getPatterns();
+ input = patterns.Replace(input, new MatchEvaluator(replacement));
+ input = DELETED.Replace(input, string.Empty);
+ return input;*/
+ }
+
+ ArrayList patterns = new ArrayList();
+ private void add(string expression, object replacement)
+ {
+ Pattern pattern = new Pattern();
+ pattern.expression = expression;
+ pattern.replacement = replacement;
+ //count the number of sub-expressions
+ // - add 1 because each group is itself a sub-expression
+ pattern.length = GROUPS.Matches(internalEscape(expression)).Count + 1;
+
+ //does the pattern deal with sup-expressions?
+ if (replacement is string && SUB_REPLACE.IsMatch((string) replacement))
+ {
+ string sreplacement = (string) replacement;
+ // a simple lookup (e.g. $2)
+ if (INDEXED.IsMatch(sreplacement))
+ {
+ pattern.replacement = int.Parse(sreplacement.Substring(1)) - 1;
+ }
+ }
+
+ patterns.Add(pattern);
+ }
+
+ /// <summary>
+ /// builds the patterns into a single regular expression
+ /// </summary>
+ /// <returns></returns>
+ private Regex getPatterns()
+ {
+ StringBuilder rtrn = new StringBuilder(string.Empty);
+ foreach (object pattern in patterns)
+ {
+ rtrn.Append(((Pattern) pattern).ToString() + "|");
+ }
+ rtrn.Remove(rtrn.Length - 1, 1);
+ return new Regex(rtrn.ToString(), ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None );
+ }
+
+ /// <summary>
+ /// Global replacement function. Called once for each match found
+ /// </summary>
+ /// <param name="match">Match found</param>
+ private string replacement(Match match)
+ {
+ int i = 1, j = 0;
+ Pattern pattern;
+ //loop through the patterns
+ while (!((pattern = (Pattern) patterns[j++]) == null))
+ {
+ //do we have a result?
+ if (match.Groups[i].Value != string.Empty)
+ {
+ object replacement = pattern.replacement;
+ if (replacement is MatchGroupEvaluator)
+ {
+ return ((MatchGroupEvaluator) replacement)(match, i);
+ }
+ else if (replacement is int)
+ {
+ return match.Groups[(int) replacement + i].Value;
+ }
+ else
+ {
+ //string, send to interpreter
+ return replacementString(match, i, (string) replacement, pattern.length);
+ }
+ }
+ else //skip over references to sub-expressions
+ i += pattern.length;
+ }
+ return match.Value; //should never be hit, but you never know
+ }
+
+ /// <summary>
+ /// Replacement function for complicated lookups (e.g. Hello $3 $2)
+ /// </summary>
+ private string replacementString(Match match, int offset, string replacement, int length)
+ {
+ while (length > 0)
+ {
+ replacement = replacement.Replace("$" + length--, match.Groups[offset + length].Value);
+ }
+ return replacement;
+ }
+
+ private StringCollection escaped = new StringCollection();
+
+ //encode escaped characters
+ private string escape(string str)
+ {
+ if (escapeChar == '\0')
+ return str;
+ Regex escaping = new Regex("\\\\(.)");
+ return escaping.Replace(str, new MatchEvaluator(escapeMatch));
+ }
+
+ private string escapeMatch(Match match)
+ {
+ escaped.Add(match.Groups[1].Value);
+ return "\\";
+ }
+
+ //decode escaped characters
+ private int unescapeIndex = 0;
+ private string unescape(string str)
+ {
+ if (escapeChar == '\0')
+ return str;
+ Regex unescaping = new Regex("\\" + escapeChar);
+ return unescaping.Replace(str, new MatchEvaluator(unescapeMatch));
+ }
+
+ private string unescapeMatch(Match match)
+ {
+ return "\\" + escaped[unescapeIndex++];
+ }
+
+ private string internalEscape(string str)
+ {
+ return ESCAPE.Replace(str, "");
+ }
+
+ //subclass for each pattern
+ private class Pattern
+ {
+ public string expression;
+ public object replacement;
+ public int length;
+
+ public override string ToString()
+ {
+ return "(" + expression + ")";
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6fdcc21
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CustomMsBuildTasks")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CustomMsBuildTasks")]
+[assembly: AssemblyCopyright("Copyright © 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("952e3aaa-5dc6-4b71-8c9c-6b485263be19")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
new file mode 100644
index 0000000..a0ba386
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/ReSignDelaySignedAssemblies.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+// <copyright file="ReSignDelaySignedAssemblies.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ public class ReSignDelaySignedAssemblies : SnToolTask {
+ /// <summary>
+ /// Gets or sets the key file to use for signing.
+ /// </summary>
+ public ITaskItem KeyFile { get; set; }
+
+ /// <summary>
+ /// Gets or sets the key container.
+ /// </summary>
+ public ITaskItem KeyContainer { get; set; }
+
+ /// <summary>
+ /// Gets or sets the assemblies to re-sign.
+ /// </summary>
+ public ITaskItem[] Assemblies { get; set; }
+
+ /// <summary>
+ /// Generates the command line commands.
+ /// </summary>
+ protected override string GenerateCommandLineCommands() {
+ ////if (this.Assemblies.Length != 1) {
+ //// throw new NotSupportedException("Exactly 1 assembly for signing is supported.");
+ ////}
+ CommandLineBuilder args = new CommandLineBuilder();
+ args.AppendSwitch("-q");
+
+ if (this.KeyFile != null) {
+ args.AppendSwitch("-R");
+ } else if (this.KeyContainer != null) {
+ args.AppendSwitch("-Rc");
+ } else {
+ throw new InvalidOperationException("Either KeyFile or KeyContainer must be set.");
+ }
+
+ args.AppendFileNameIfNotNull(this.Assemblies[0]);
+ if (this.KeyFile != null) {
+ args.AppendFileNameIfNotNull(this.KeyFile);
+ } else {
+ args.AppendFileNameIfNotNull(this.KeyContainer);
+ }
+
+ return args.ToString();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs
new file mode 100644
index 0000000..2de5976
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SetEnvironmentVariable.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Build.Utilities;
+using Microsoft.Build.Framework;
+
+namespace DotNetOpenAuth.BuildTasks {
+ public class SetEnvironmentVariable : Task {
+ public SetEnvironmentVariable() {
+ Scope = EnvironmentVariableTarget.Process;
+ }
+
+ /// <summary>
+ /// The name of the environment variable to set or clear.
+ /// </summary>
+ [Required]
+ public string Name { get; set; }
+ /// <summary>
+ /// The value of the environment variable, or the empty string to clear it.
+ /// </summary>
+ [Required]
+ public string Value { get; set; }
+ /// <summary>
+ /// The target environment for the variable. Machine, User, or Process.
+ /// </summary>
+ public EnvironmentVariableTarget Scope { get; set; }
+
+ public override bool Execute() {
+ Environment.SetEnvironmentVariable(Name, Value, Scope);
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs
new file mode 100644
index 0000000..2e69926
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SignatureVerification.cs
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------
+// <copyright file="SignatureVerification.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using Microsoft.Build.Utilities;
+
+ public class SignatureVerification : SnToolTask {
+ /// <summary>
+ /// Gets or sets a value indicating whether to register the given assembly and public key token
+ /// for skip verification or clear any pre-existing skip verification entry.
+ /// </summary>
+ public bool SkipVerification { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the assembly.
+ /// </summary>
+ /// <value>The name of the assembly.</value>
+ public string AssemblyName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the public key token.
+ /// </summary>
+ /// <value>The public key token.</value>
+ public string PublicKeyToken { get; set; }
+
+ /// <summary>
+ /// Generates the command line commands.
+ /// </summary>
+ protected override string GenerateCommandLineCommands() {
+ CommandLineBuilder builder = new CommandLineBuilder();
+ builder.AppendSwitch("-q");
+ if (this.SkipVerification) {
+ builder.AppendSwitch("-Vr");
+ } else {
+ builder.AppendSwitch("-Vu");
+ }
+
+ builder.AppendFileNameIfNotNull(this.AssemblyName + "," + this.PublicKeyToken);
+ return builder.ToString();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs
new file mode 100644
index 0000000..29896fe
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/SnToolTask.cs
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------
+// <copyright file="SnToolTask.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.IO;
+ using Microsoft.Build.Utilities;
+
+ public abstract class SnToolTask : ToolTask {
+ /// <summary>
+ /// Gets the name of the tool.
+ /// </summary>
+ /// <value>The name of the tool.</value>
+ protected override string ToolName {
+ get { return "sn.exe"; }
+ }
+
+ /// <summary>
+ /// Generates the full path to tool.
+ /// </summary>
+ protected override string GenerateFullPathToTool() {
+ string[] versions = new[] { "v6.0A", "v6.1", "v7.0a" };
+ string fullPath = null;
+ foreach (string version in versions) {
+ fullPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft SDKs\Windows\" + version + @"\bin\" + this.ToolName);
+ if (File.Exists(fullPath)) {
+ return fullPath;
+ }
+ }
+
+ throw new FileNotFoundException("Unable to find sn.exe tool.", fullPath);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
new file mode 100644
index 0000000..17647fd
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.Designer.cs
@@ -0,0 +1,117 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4927
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class TaskStrings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal TaskStrings() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.BuildTasks.TaskStrings", typeof(TaskStrings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Web application &apos;{0}&apos; deleted..
+ /// </summary>
+ internal static string DeletedWebApplication {
+ get {
+ return ResourceManager.GetString("DeletedWebApplication", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The {0} and {1} properties must be set to arrays of equal length..
+ /// </summary>
+ internal static string MismatchingArrayLengths {
+ get {
+ return ResourceManager.GetString("MismatchingArrayLengths", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to No web site with the name &apos;{0}&apos; found..
+ /// </summary>
+ internal static string NoMatchingWebSiteFound {
+ get {
+ return ResourceManager.GetString("NoMatchingWebSiteFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Packing javascript resource &quot;{0}&quot; into &quot;{1}&quot;..
+ /// </summary>
+ internal static string PackingJsFile {
+ get {
+ return ResourceManager.GetString("PackingJsFile", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Skip packing &quot;{0}&quot; because its packed version is up to date..
+ /// </summary>
+ internal static string SkipPackingJsFile {
+ get {
+ return ResourceManager.GetString("SkipPackingJsFile", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Web application &apos;{0}&apos; was not found, so it was not deleted..
+ /// </summary>
+ internal static string WebApplicationNotFoundSoNotDeleted {
+ get {
+ return ResourceManager.GetString("WebApplicationNotFoundSoNotDeleted", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx
new file mode 100644
index 0000000..50e1592
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/TaskStrings.resx
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="DeletedWebApplication" xml:space="preserve">
+ <value>Web application '{0}' deleted.</value>
+ </data>
+ <data name="MismatchingArrayLengths" xml:space="preserve">
+ <value>The {0} and {1} properties must be set to arrays of equal length.</value>
+ </data>
+ <data name="NoMatchingWebSiteFound" xml:space="preserve">
+ <value>No web site with the name '{0}' found.</value>
+ </data>
+ <data name="PackingJsFile" xml:space="preserve">
+ <value>Packing javascript resource "{0}" into "{1}".</value>
+ </data>
+ <data name="SkipPackingJsFile" xml:space="preserve">
+ <value>Skip packing "{0}" because its packed version is up to date.</value>
+ </data>
+ <data name="WebApplicationNotFoundSoNotDeleted" xml:space="preserve">
+ <value>Web application '{0}' was not found, so it was not deleted.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.BuildTasks/Trim.cs b/src/DotNetOpenAuth.BuildTasks/Trim.cs
new file mode 100644
index 0000000..972b87d
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/Trim.cs
@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------
+// <copyright file="Trim.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Trims item identities or metadata.
+ /// </summary>
+ public class Trim : Task {
+ /// <summary>
+ /// Gets or sets the name of the metadata to trim. Leave empty or null to operate on itemspec.
+ /// </summary>
+ /// <value>The name of the metadata.</value>
+ public string MetadataName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the characters that should be trimmed off if found at the start of items' ItemSpecs.
+ /// </summary>
+ public string StartCharacters { get; set; }
+
+ /// <summary>
+ /// Gets or sets the characters that should be trimmed off if found at the end of items' ItemSpecs.
+ /// </summary>
+ public string EndCharacters { get; set; }
+
+ /// <summary>
+ /// Gets or sets the substring that should be trimmed along with everything that appears after it.
+ /// </summary>
+ public string AllAfter { get; set; }
+
+ /// <summary>
+ /// Gets or sets the items with ItemSpec's to be trimmed.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Inputs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the items with trimmed ItemSpec strings.
+ /// </summary>
+ [Output]
+ public ITaskItem[] Outputs { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ /// <returns>A value indicating whether the task completed successfully.</returns>
+ public override bool Execute() {
+ this.Outputs = new ITaskItem[this.Inputs.Length];
+ for (int i = 0; i < this.Inputs.Length; i++) {
+ this.Outputs[i] = new TaskItem(this.Inputs[i]);
+ string value = string.IsNullOrEmpty(this.MetadataName) ? this.Outputs[i].ItemSpec : this.Outputs[i].GetMetadata(this.MetadataName);
+ if (!string.IsNullOrEmpty(this.StartCharacters)) {
+ value = value.TrimStart(this.StartCharacters.ToCharArray());
+ }
+ if (!string.IsNullOrEmpty(this.EndCharacters)) {
+ value = value.TrimEnd(this.EndCharacters.ToCharArray());
+ }
+ if (!string.IsNullOrEmpty(this.AllAfter)) {
+ int index = value.IndexOf(this.AllAfter);
+ if (index >= 0) {
+ value = value.Substring(0, index);
+ }
+ }
+ if (string.IsNullOrEmpty(this.MetadataName)) {
+ this.Outputs[i].ItemSpec = value;
+ } else {
+ this.Outputs[i].SetMetadata(this.MetadataName, value);
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/App.config b/src/DotNetOpenAuth.Test/App.config
index 359e25f..dafb99d 100644
--- a/src/DotNetOpenAuth.Test/App.config
+++ b/src/DotNetOpenAuth.Test/App.config
@@ -50,4 +50,8 @@
</provider>
</openid>
</dotNetOpenAuth>
+
+ <system.diagnostics>
+ <assert assertuienabled="false"/>
+ </system.diagnostics>
</configuration> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/AssemblyTesting.cs b/src/DotNetOpenAuth.Test/AssemblyTesting.cs
index d0868d2..7659a82 100644
--- a/src/DotNetOpenAuth.Test/AssemblyTesting.cs
+++ b/src/DotNetOpenAuth.Test/AssemblyTesting.cs
@@ -14,10 +14,9 @@ namespace DotNetOpenAuth.Test {
public static void AssemblyInitialize(TestContext tc) {
// Make contract failures become test failures.
Contract.ContractFailed += (sender, e) => {
- if (e.FailureKind == ContractFailureKind.Precondition) {
- // Currently we ignore these so that the regular ErrorUtilities can kick in.
- e.SetHandled();
- } else {
+ // For now, we have tests that verify that preconditions throw exceptions.
+ // So we don't want to fail a test just because a precondition check failed.
+ if (e.FailureKind != ContractFailureKind.Precondition) {
e.SetHandled();
Assert.Fail(e.FailureKind.ToString() + ": " + e.Message);
}
diff --git a/src/DotNetOpenAuth.Test/CoordinatorBase.cs b/src/DotNetOpenAuth.Test/CoordinatorBase.cs
index d1bf27c..df331f3 100644
--- a/src/DotNetOpenAuth.Test/CoordinatorBase.cs
+++ b/src/DotNetOpenAuth.Test/CoordinatorBase.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test {
using System;
+ using System.Diagnostics.Contracts;
using System.Threading;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.RelyingParty;
@@ -17,8 +18,8 @@ namespace DotNetOpenAuth.Test {
private Action<T2> party2Action;
protected CoordinatorBase(Action<T1> party1Action, Action<T2> party2Action) {
- ErrorUtilities.VerifyArgumentNotNull(party1Action, "party1Action");
- ErrorUtilities.VerifyArgumentNotNull(party2Action, "party2Action");
+ Contract.Requires<ArgumentNullException>(party1Action != null);
+ Contract.Requires<ArgumentNullException>(party2Action != null);
this.party1Action = party1Action;
this.party2Action = party2Action;
@@ -38,6 +39,7 @@ namespace DotNetOpenAuth.Test {
// terminate the other thread and inform the test host that the test failed.
Action<Action> safeWrapper = (action) => {
try {
+ TestBase.SetMockHttpContext();
action();
} catch (Exception ex) {
// We may be the second thread in an ThreadAbortException, so check the "flag"
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
index 7212008..27ea955 100644
--- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
+++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj
@@ -21,12 +21,12 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsCustomRewriterAssembly>
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
</CodeContractsCustomRewriterClass>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsRuntimeCheckingLevel>None</CodeContractsRuntimeCheckingLevel>
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
<CodeContractsBuildReferenceAssembly>False</CodeContractsBuildReferenceAssembly>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
@@ -44,6 +44,8 @@
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -52,10 +54,36 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsCustomRewriterAssembly>
+ </CodeContractsCustomRewriterAssembly>
+ <CodeContractsCustomRewriterClass>
+ </CodeContractsCustomRewriterClass>
+ <CodeContractsRuntimeCheckingLevel>None</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsBuildReferenceAssembly>False</CodeContractsBuildReferenceAssembly>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsLibPaths>
+ </CodeContractsLibPaths>
+ <CodeContractsPlatformPath>
+ </CodeContractsPlatformPath>
+ <CodeContractsExtraAnalysisOptions>
+ </CodeContractsExtraAnalysisOptions>
+ <CodeContractsBaseLineFile>
+ </CodeContractsBaseLineFile>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -71,7 +99,7 @@
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
</CodeContractsCustomRewriterClass>
- <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsRuntimeCheckingLevel>None</CodeContractsRuntimeCheckingLevel>
<CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
<CodeContractsBuildReferenceAssembly>False</CodeContractsBuildReferenceAssembly>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
@@ -87,6 +115,10 @@
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
@@ -131,10 +163,12 @@
<Compile Include="Hosting\HostingTests.cs" />
<Compile Include="Hosting\HttpHost.cs" />
<Compile Include="Hosting\TestingWorkerRequest.cs" />
+ <Compile Include="LocalizationTests.cs" />
<Compile Include="Messaging\CollectionAssert.cs" />
<Compile Include="Messaging\EnumerableCacheTests.cs" />
<Compile Include="Messaging\ErrorUtilitiesTests.cs" />
<Compile Include="Messaging\MessageSerializerTests.cs" />
+ <Compile Include="Messaging\MultipartPostPartTests.cs" />
<Compile Include="Messaging\OutgoingWebResponseTests.cs" />
<Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" />
<Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" />
@@ -233,6 +267,7 @@
<Compile Include="OpenId\RelyingParty\AuthenticationRequestTests.cs" />
<Compile Include="OpenId\RelyingParty\FailedAuthenticationResponseTests.cs" />
<Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponseTests.cs" />
+ <Compile Include="OpenId\RelyingParty\OpenIdTextBoxTests.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAnonymousResponseTests.cs" />
<Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseTests.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyTests.cs" />
@@ -296,4 +331,4 @@
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/DotNetOpenAuth.Test/LocalizationTests.cs b/src/DotNetOpenAuth.Test/LocalizationTests.cs
new file mode 100644
index 0000000..50e9a34
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/LocalizationTests.cs
@@ -0,0 +1,28 @@
+//-----------------------------------------------------------------------
+// <copyright file="LocalizationTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test {
+ using System;
+ using System.Globalization;
+ using System.Threading;
+ using DotNetOpenAuth.Messaging;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ /// <summary>
+ /// Tests various localized resources work as expected.
+ /// </summary>
+ [TestClass]
+ public class LocalizationTests {
+ /// <summary>
+ /// Tests that Serbian localized strings are correctly installed.
+ /// </summary>
+ [TestMethod, ExpectedException(typeof(InvalidOperationException), "Ovaj metod zahteva tekući HttpContext. Kao alternativa, koristite preklopljeni metod koji dozvoljava da se prosledi informacija bez HttpContext-a.")]
+ public void Serbian() {
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("sr");
+ ErrorUtilities.VerifyHttpContext();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
index cbaded1..3cc792b 100644
--- a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardExpirationBindingElementTests.cs
@@ -33,7 +33,7 @@ namespace DotNetOpenAuth.Test.Messaging.Bindings {
[TestMethod, ExpectedException(typeof(ExpiredMessageException))]
public void VerifyBadTimestampIsRejected() {
this.Channel = CreateChannel(MessageProtections.Expiration);
- this.ParameterizedReceiveProtectedTest(DateTime.UtcNow - StandardExpirationBindingElement.DefaultMaximumMessageAge - TimeSpan.FromSeconds(1), false);
+ this.ParameterizedReceiveProtectedTest(DateTime.UtcNow - StandardExpirationBindingElement.MaximumMessageAge - TimeSpan.FromSeconds(1), false);
}
}
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardReplayProtectionBindingElementTests.cs b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardReplayProtectionBindingElementTests.cs
index 26ce01c..14651bc 100644
--- a/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardReplayProtectionBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/Bindings/StandardReplayProtectionBindingElementTests.cs
@@ -31,6 +31,7 @@ namespace DotNetOpenAuth.Test.Messaging.Bindings {
this.protocol = Protocol.Default;
this.nonceStore = new NonceMemoryStore(TimeSpan.FromHours(3));
this.nonceElement = new StandardReplayProtectionBindingElement(this.nonceStore);
+ this.nonceElement.Channel = new Mocks.TestChannel();
this.message = new TestReplayProtectedMessage();
this.message.UtcCreationDate = DateTime.UtcNow;
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
index 669abbc..7846411 100644
--- a/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/ChannelTests.cs
@@ -201,6 +201,7 @@ namespace DotNetOpenAuth.Test.Messaging {
[TestMethod, ExpectedException(typeof(InvalidOperationException))]
public void ReadFromRequestNoContext() {
+ HttpContext.Current = null;
TestBadChannel badChannel = new TestBadChannel(false);
badChannel.ReadFromRequest();
}
diff --git a/src/DotNetOpenAuth.Test/Messaging/CollectionAssert.cs b/src/DotNetOpenAuth.Test/Messaging/CollectionAssert.cs
index f9e569a..db136f5 100644
--- a/src/DotNetOpenAuth.Test/Messaging/CollectionAssert.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/CollectionAssert.cs
@@ -5,16 +5,18 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.Messaging {
+ using System;
using System.Collections;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
internal class CollectionAssert<T> {
internal static void AreEquivalent(ICollection<T> expected, ICollection<T> actual) {
- ErrorUtilities.VerifyArgumentNotNull(expected, "expected");
- ErrorUtilities.VerifyArgumentNotNull(actual, "actual");
+ Contract.Requires<ArgumentNullException>(expected != null);
+ Contract.Requires<ArgumentNullException>(actual != null);
ICollection expectedNonGeneric = new List<T>(expected);
ICollection actualNonGeneric = new List<T>(actual);
@@ -22,8 +24,8 @@ namespace DotNetOpenAuth.Test.Messaging {
}
internal static void AreEquivalentByEquality(ICollection<T> expected, ICollection<T> actual) {
- ErrorUtilities.VerifyArgumentNotNull(expected, "expected");
- ErrorUtilities.VerifyArgumentNotNull(actual, "actual");
+ Contract.Requires<ArgumentNullException>(expected != null);
+ Contract.Requires<ArgumentNullException>(actual != null);
Assert.AreEqual(expected.Count, actual.Count);
foreach (T value in expected) {
@@ -32,7 +34,7 @@ namespace DotNetOpenAuth.Test.Messaging {
}
internal static void Contains(IEnumerable<T> sequence, T element) {
- ErrorUtilities.VerifyArgumentNotNull(sequence, "sequence");
+ Contract.Requires<ArgumentNullException>(sequence != null);
if (!sequence.Contains(element)) {
Assert.Fail("Sequence did not include expected element '{0}'.", element);
diff --git a/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs b/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs
new file mode 100644
index 0000000..f87ae59
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs
@@ -0,0 +1,99 @@
+//-----------------------------------------------------------------------
+// <copyright file="MultipartPostPartTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Messaging {
+ using System.CodeDom.Compiler;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Net;
+ using DotNetOpenAuth.Messaging;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class MultipartPostPartTests : TestBase {
+ /// <summary>
+ /// Verifies that the Length property matches the length actually serialized.
+ /// </summary>
+ [TestMethod]
+ public void FormDataSerializeMatchesLength() {
+ var part = MultipartPostPart.CreateFormPart("a", "b");
+ VerifyLength(part);
+ }
+
+ /// <summary>
+ /// Verifies that the length property matches the length actually serialized.
+ /// </summary>
+ [TestMethod]
+ public void FileSerializeMatchesLength() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension(".txt");
+ File.WriteAllText(file, "sometext");
+ var part = MultipartPostPart.CreateFormFilePart("someformname", file, "text/plain");
+ VerifyLength(part);
+ }
+ }
+
+ /// <summary>
+ /// Verifies MultiPartPost sends the right number of bytes.
+ /// </summary>
+ [TestMethod]
+ public void MultiPartPostAscii() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension("txt");
+ File.WriteAllText(file, "sometext");
+ this.VerifyFullPost(new List<MultipartPostPart> {
+ MultipartPostPart.CreateFormPart("a", "b"),
+ MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
+ });
+ }
+ }
+
+ /// <summary>
+ /// Verifies MultiPartPost sends the right number of bytes.
+ /// </summary>
+ [TestMethod]
+ public void MultiPartPostMultiByteCharacters() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension("txt");
+ File.WriteAllText(file, "\x1020\x818");
+ this.VerifyFullPost(new List<MultipartPostPart> {
+ MultipartPostPart.CreateFormPart("a", "\x987"),
+ MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
+ });
+ }
+ }
+
+ private static void VerifyLength(MultipartPostPart part) {
+ Contract.Requires(part != null);
+
+ var expectedLength = part.Length;
+ var ms = new MemoryStream();
+ var sw = new StreamWriter(ms);
+ part.Serialize(sw);
+ sw.Flush();
+ var actualLength = ms.Length;
+ Assert.AreEqual(expectedLength, actualLength);
+ }
+
+ private void VerifyFullPost(List<MultipartPostPart> parts) {
+ var request = (HttpWebRequest)WebRequest.Create("http://localhost");
+ var handler = new Mocks.TestWebRequestHandler();
+ bool posted = false;
+ handler.Callback = req => {
+ foreach (string header in req.Headers) {
+ TestContext.WriteLine("{0}: {1}", header, req.Headers[header]);
+ }
+ TestContext.WriteLine(handler.RequestEntityAsString);
+ Assert.AreEqual(req.ContentLength, handler.RequestEntityStream.Length);
+ posted = true;
+ return null;
+ };
+ request.PostMultipart(handler, parts);
+ Assert.IsTrue(posted, "HTTP POST never sent.");
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs b/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs
new file mode 100644
index 0000000..f87ae59
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs
@@ -0,0 +1,99 @@
+//-----------------------------------------------------------------------
+// <copyright file="MultipartPostPartTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.Messaging {
+ using System.CodeDom.Compiler;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Net;
+ using DotNetOpenAuth.Messaging;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class MultipartPostPartTests : TestBase {
+ /// <summary>
+ /// Verifies that the Length property matches the length actually serialized.
+ /// </summary>
+ [TestMethod]
+ public void FormDataSerializeMatchesLength() {
+ var part = MultipartPostPart.CreateFormPart("a", "b");
+ VerifyLength(part);
+ }
+
+ /// <summary>
+ /// Verifies that the length property matches the length actually serialized.
+ /// </summary>
+ [TestMethod]
+ public void FileSerializeMatchesLength() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension(".txt");
+ File.WriteAllText(file, "sometext");
+ var part = MultipartPostPart.CreateFormFilePart("someformname", file, "text/plain");
+ VerifyLength(part);
+ }
+ }
+
+ /// <summary>
+ /// Verifies MultiPartPost sends the right number of bytes.
+ /// </summary>
+ [TestMethod]
+ public void MultiPartPostAscii() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension("txt");
+ File.WriteAllText(file, "sometext");
+ this.VerifyFullPost(new List<MultipartPostPart> {
+ MultipartPostPart.CreateFormPart("a", "b"),
+ MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
+ });
+ }
+ }
+
+ /// <summary>
+ /// Verifies MultiPartPost sends the right number of bytes.
+ /// </summary>
+ [TestMethod]
+ public void MultiPartPostMultiByteCharacters() {
+ using (TempFileCollection tfc = new TempFileCollection()) {
+ string file = tfc.AddExtension("txt");
+ File.WriteAllText(file, "\x1020\x818");
+ this.VerifyFullPost(new List<MultipartPostPart> {
+ MultipartPostPart.CreateFormPart("a", "\x987"),
+ MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"),
+ });
+ }
+ }
+
+ private static void VerifyLength(MultipartPostPart part) {
+ Contract.Requires(part != null);
+
+ var expectedLength = part.Length;
+ var ms = new MemoryStream();
+ var sw = new StreamWriter(ms);
+ part.Serialize(sw);
+ sw.Flush();
+ var actualLength = ms.Length;
+ Assert.AreEqual(expectedLength, actualLength);
+ }
+
+ private void VerifyFullPost(List<MultipartPostPart> parts) {
+ var request = (HttpWebRequest)WebRequest.Create("http://localhost");
+ var handler = new Mocks.TestWebRequestHandler();
+ bool posted = false;
+ handler.Callback = req => {
+ foreach (string header in req.Headers) {
+ TestContext.WriteLine("{0}: {1}", header, req.Headers[header]);
+ }
+ TestContext.WriteLine(handler.RequestEntityAsString);
+ Assert.AreEqual(req.ContentLength, handler.RequestEntityStream.Length);
+ posted = true;
+ return null;
+ };
+ request.PostMultipart(handler, parts);
+ Assert.IsTrue(posted, "HTTP POST never sent.");
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs b/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs
index a0e7c3f..89d165a 100644
--- a/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/Messaging/ResponseTests.cs
@@ -15,6 +15,7 @@ namespace DotNetOpenAuth.Test.Messaging {
public class ResponseTests : TestBase {
[TestMethod, ExpectedException(typeof(InvalidOperationException))]
public void SendWithoutAspNetContext() {
+ HttpContext.Current = null;
new OutgoingWebResponse().Send();
}
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs
index 3bbe6e3..16386de 100644
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingChannel.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
@@ -84,7 +85,7 @@ namespace DotNetOpenAuth.Test.Mocks {
/// <param name="outgoingMessageFilter">The outgoing message filter. May be null.</param>
internal CoordinatingChannel(Channel wrappedChannel, Action<IProtocolMessage> incomingMessageFilter, Action<IProtocolMessage> outgoingMessageFilter)
: base(GetMessageFactory(wrappedChannel), wrappedChannel.BindingElements.ToArray()) {
- ErrorUtilities.VerifyArgumentNotNull(wrappedChannel, "wrappedChannel");
+ Contract.Requires<ArgumentNullException>(wrappedChannel != null);
this.wrappedChannel = wrappedChannel;
this.incomingMessageFilter = incomingMessageFilter;
@@ -220,7 +221,7 @@ namespace DotNetOpenAuth.Test.Mocks {
/// channel since their message factory is not used.
/// </remarks>
protected virtual T CloneSerializedParts<T>(T message) where T : class, IProtocolMessage {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
IProtocolMessage clonedMessage;
var messageAccessor = this.MessageDescriptions.GetAccessor(message);
@@ -251,7 +252,7 @@ namespace DotNetOpenAuth.Test.Mocks {
}
private static IMessageFactory GetMessageFactory(Channel channel) {
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
Channel_Accessor accessor = Channel_Accessor.AttachShadow(channel);
return accessor.MessageFactory;
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs
index 10b0261..e862ca6 100644
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOAuthChannel.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
+ using System.Diagnostics.Contracts;
using System.Threading;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
@@ -30,7 +31,7 @@ namespace DotNetOpenAuth.Test.Mocks {
internal CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, IConsumerTokenManager tokenManager)
: base(
signingBindingElement,
- new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge),
+ new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
tokenManager) {
}
@@ -44,7 +45,7 @@ namespace DotNetOpenAuth.Test.Mocks {
internal CoordinatingOAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, IServiceProviderTokenManager tokenManager)
: base(
signingBindingElement,
- new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge),
+ new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge),
tokenManager) {
}
@@ -134,7 +135,7 @@ namespace DotNetOpenAuth.Test.Mocks {
}
private T CloneSerializedParts<T>(T message, HttpRequestInfo requestInfo) where T : class, IProtocolMessage {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
IProtocolMessage clonedMessage;
var messageAccessor = this.MessageDescriptions.GetAccessor(message);
diff --git a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs
index 07f9bc9..62ea871 100644
--- a/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/CoordinatingOutgoingWebResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -20,8 +21,8 @@ namespace DotNetOpenAuth.Test.Mocks {
/// <param name="message">The direct response message to send to the remote channel. This message will be cloned.</param>
/// <param name="receivingChannel">The receiving channel.</param>
internal CoordinatingOutgoingWebResponse(IProtocolMessage message, CoordinatingChannel receivingChannel) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- ErrorUtilities.VerifyArgumentNotNull(receivingChannel, "receivingChannel");
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentNullException>(receivingChannel != null);
this.receivingChannel = receivingChannel;
this.OriginalMessage = message;
diff --git a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
index 48547b7..35672d7 100644
--- a/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/InMemoryTokenManager.cs
@@ -106,6 +106,10 @@ namespace DotNetOpenAuth.Test.Mocks {
return this.tokens[token];
}
+ public void UpdateToken(IServiceProviderRequestToken token) {
+ // Nothing to do here, since we're using Linq To SQL.
+ }
+
#endregion
/// <summary>
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
index 66f258d..0213a33 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockHttpRequest.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Net;
@@ -22,7 +23,7 @@ namespace DotNetOpenAuth.Test.Mocks {
private readonly Dictionary<Uri, IncomingWebResponse> registeredMockResponses = new Dictionary<Uri, IncomingWebResponse>();
private MockHttpRequest(IDirectWebRequestHandler mockHandler) {
- ErrorUtilities.VerifyArgumentNotNull(mockHandler, "mockHandler");
+ Contract.Requires<ArgumentNullException>(mockHandler != null);
this.MockWebRequestHandler = mockHandler;
}
@@ -41,7 +42,7 @@ namespace DotNetOpenAuth.Test.Mocks {
}
internal void RegisterMockResponse(IncomingWebResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
if (this.registeredMockResponses.ContainsKey(response.RequestUri)) {
Logger.Http.WarnFormat("Mock HTTP response already registered for {0}.", response.RequestUri);
} else {
@@ -58,9 +59,9 @@ namespace DotNetOpenAuth.Test.Mocks {
}
internal void RegisterMockResponse(Uri requestUri, Uri responseUri, string contentType, WebHeaderCollection headers, string responseBody) {
- ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
- ErrorUtilities.VerifyArgumentNotNull(responseUri, "responseUri");
- ErrorUtilities.VerifyNonZeroLength(contentType, "contentType");
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+ Contract.Requires<ArgumentNullException>(responseUri != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(contentType));
// Set up the redirect if appropriate
if (requestUri != responseUri) {
@@ -83,7 +84,7 @@ namespace DotNetOpenAuth.Test.Mocks {
}
internal void RegisterMockXrdsResponse(ServiceEndpoint endpoint) {
- ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint");
+ Contract.Requires<ArgumentNullException>(endpoint != null);
string identityUri;
if (endpoint.ClaimedIdentifier == endpoint.Protocol.ClaimedIdentifierForOPIdentifier) {
@@ -95,7 +96,7 @@ namespace DotNetOpenAuth.Test.Mocks {
}
internal void RegisterMockXrdsResponse(Uri respondingUri, IEnumerable<ServiceEndpoint> endpoints) {
- ErrorUtilities.VerifyArgumentNotNull(endpoints, "endpoints");
+ Contract.Requires<ArgumentNullException>(endpoints != null);
StringBuilder xrds = new StringBuilder();
xrds.AppendLine(@"<xrds:XRDS xmlns:xrds='xri://$xrds' xmlns:openid='http://openid.net/xmlns/1.0' xmlns='xri://$xrd*($v*2.0)'>
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs
index 669e4d3..346dde9 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockIdentifier.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
@@ -24,10 +25,10 @@ namespace DotNetOpenAuth.Test.Mocks {
private Identifier wrappedIdentifier;
public MockIdentifier(Identifier wrappedIdentifier, MockHttpRequest mockHttpRequest, IEnumerable<ServiceEndpoint> endpoints)
- : base(false) {
- ErrorUtilities.VerifyArgumentNotNull(wrappedIdentifier, "wrappedIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(mockHttpRequest, "mockHttpRequest");
- ErrorUtilities.VerifyArgumentNotNull(endpoints, "endpoints");
+ : base(wrappedIdentifier.OriginalString, false) {
+ Contract.Requires<ArgumentNullException>(wrappedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(mockHttpRequest != null);
+ Contract.Requires<ArgumentNullException>(endpoints != null);
this.wrappedIdentifier = wrappedIdentifier;
this.endpoints = endpoints;
diff --git a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
index ae39ebb..dd17735 100644
--- a/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/MockRealm.cs
@@ -5,7 +5,9 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.Mocks {
+ using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
@@ -19,7 +21,7 @@ namespace DotNetOpenAuth.Test.Mocks {
/// <param name="relyingPartyDescriptions">The relying party descriptions.</param>
internal MockRealm(Realm wrappedRealm, params RelyingPartyEndpointDescription[] relyingPartyDescriptions)
: base(wrappedRealm) {
- ErrorUtilities.VerifyArgumentNotNull(relyingPartyDescriptions, "relyingPartyDescriptions");
+ Contract.Requires<ArgumentNullException>(relyingPartyDescriptions != null);
this.relyingPartyDescriptions = relyingPartyDescriptions;
}
diff --git a/src/DotNetOpenAuth.Test/Mocks/TestMessageFactory.cs b/src/DotNetOpenAuth.Test/Mocks/TestMessageFactory.cs
index ffb117c..7b13175 100644
--- a/src/DotNetOpenAuth.Test/Mocks/TestMessageFactory.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/TestMessageFactory.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.Mocks {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -32,8 +33,6 @@ namespace DotNetOpenAuth.Test.Mocks {
#region IMessageFactory Members
public IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
if (fields.ContainsKey("age")) {
if (this.signedMessages) {
if (this.expiringMessages) {
diff --git a/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs b/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs
index b74c0f0..03dbd6b 100644
--- a/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs
+++ b/src/DotNetOpenAuth.Test/Mocks/TestWebRequestHandler.cs
@@ -56,7 +56,7 @@ namespace DotNetOpenAuth.Test.Mocks {
#region IWebRequestHandler Members
public bool CanSupport(DirectWebRequestOptions options) {
- return options == DirectWebRequestOptions.None;
+ return true;
}
/// <summary>
diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
index 856f164..e0cc92a 100644
--- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/OAuthChannelTests.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
using System.Text;
@@ -34,13 +35,13 @@ namespace DotNetOpenAuth.Test.ChannelElements {
this.webRequestHandler = new TestWebRequestHandler();
this.signingElement = new RsaSha1SigningBindingElement(new InMemoryTokenManager());
- this.nonceStore = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
+ this.nonceStore = new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge);
this.channel = new OAuthChannel(this.signingElement, this.nonceStore, new InMemoryTokenManager(), new TestMessageFactory());
this.accessor = OAuthChannel_Accessor.AttachShadow(this.channel);
this.channel.WebRequestHandler = this.webRequestHandler;
}
- [TestMethod, ExpectedException(typeof(ArgumentException))]
+ [TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void CtorNullSigner() {
new OAuthChannel(null, this.nonceStore, new InMemoryTokenManager(), new TestMessageFactory());
}
@@ -243,7 +244,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
}
private static string CreateAuthorizationHeader(IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
+ Contract.Requires<ArgumentNullException>(fields != null);
StringBuilder authorization = new StringBuilder();
authorization.Append("OAuth ");
diff --git a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs
index 627db8f..01d51a3 100644
--- a/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/ChannelElements/PlaintextSigningBindingElementTest.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
using DotNetOpenAuth.OAuth.Messages;
+ using DotNetOpenAuth.Test.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
@@ -16,6 +17,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
[TestMethod]
public void HttpsSignatureGeneration() {
SigningBindingElementBase target = new PlaintextSigningBindingElement();
+ target.Channel = new TestChannel();
MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest);
ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version);
message.ConsumerSecret = "cs";
@@ -29,6 +31,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
public void HttpsSignatureVerification() {
MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest);
ITamperProtectionChannelBindingElement target = new PlaintextSigningBindingElement();
+ target.Channel = new TestChannel();
ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version);
message.ConsumerSecret = "cs";
message.TokenSecret = "ts";
@@ -40,6 +43,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
[TestMethod]
public void HttpsSignatureVerificationNotApplicable() {
SigningBindingElementBase target = new PlaintextSigningBindingElement();
+ target.Channel = new TestChannel();
MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("https://localtest", HttpDeliveryMethods.GetRequest);
ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version);
message.ConsumerSecret = "cs";
@@ -52,6 +56,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
[TestMethod]
public void HttpSignatureGeneration() {
SigningBindingElementBase target = new PlaintextSigningBindingElement();
+ target.Channel = new TestChannel();
MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("http://localtest", HttpDeliveryMethods.GetRequest);
ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version);
message.ConsumerSecret = "cs";
@@ -66,6 +71,7 @@ namespace DotNetOpenAuth.Test.ChannelElements {
[TestMethod]
public void HttpSignatureVerification() {
SigningBindingElementBase target = new PlaintextSigningBindingElement();
+ target.Channel = new TestChannel();
MessageReceivingEndpoint endpoint = new MessageReceivingEndpoint("http://localtest", HttpDeliveryMethods.GetRequest);
ITamperResistantOAuthMessage message = new UnauthorizedTokenRequest(endpoint, Protocol.Default.Version);
message.ConsumerSecret = "cs";
diff --git a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
index e04edeb..4373402 100644
--- a/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
+++ b/src/DotNetOpenAuth.Test/OAuth/OAuthCoordinator.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test {
using System;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;
@@ -25,8 +26,8 @@ namespace DotNetOpenAuth.Test {
/// <param name="serviceProviderAction">The code path of the Service Provider.</param>
internal OAuthCoordinator(ConsumerDescription consumerDescription, ServiceProviderDescription serviceDescription, Action<WebConsumer> consumerAction, Action<ServiceProvider> serviceProviderAction)
: base(consumerAction, serviceProviderAction) {
- ErrorUtilities.VerifyArgumentNotNull(consumerDescription, "consumerDescription");
- ErrorUtilities.VerifyArgumentNotNull(serviceDescription, "serviceDescription");
+ Contract.Requires<ArgumentNullException>(consumerDescription != null);
+ Contract.Requires<ArgumentNullException>(serviceDescription != null);
this.consumerDescription = consumerDescription;
this.serviceDescription = serviceDescription;
diff --git a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
index 4ebdf74..7de2a8b 100644
--- a/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/AuthenticationTests.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test.OpenId {
using System;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OpenId;
@@ -135,8 +136,8 @@ namespace DotNetOpenAuth.Test.OpenId {
}
private void ParameterizedAuthenticationTest(Protocol protocol, bool statelessRP, bool sharedAssociation, bool positive, bool immediate, bool tamper) {
- ErrorUtilities.VerifyArgument(!statelessRP || !sharedAssociation, "The RP cannot be stateless while sharing an association with the OP.");
- ErrorUtilities.VerifyArgument(positive || !tamper, "Cannot tamper with a negative response.");
+ Contract.Requires<ArgumentException>(!statelessRP || !sharedAssociation, "The RP cannot be stateless while sharing an association with the OP.");
+ Contract.Requires<ArgumentException>(positive || !tamper, "Cannot tamper with a negative response.");
ProviderSecuritySettings securitySettings = new ProviderSecuritySettings();
Association association = sharedAssociation ? HmacShaAssociation.Create(protocol, protocol.Args.SignatureAlgorithm.Best, AssociationRelyingPartyType.Smart, securitySettings) : null;
var coordinator = new OpenIdCoordinator(
diff --git a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
index 5af1caf..29797dc 100644
--- a/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/ChannelElements/ExtensionsBindingElementTests.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text.RegularExpressions;
using DotNetOpenAuth.Messaging;
@@ -167,7 +168,7 @@ namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
}
private static void RegisterMockExtension(Channel channel) {
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
ExtensionTestUtilities.RegisterExtension(channel, MockOpenIdExtension.Factory);
}
@@ -178,7 +179,7 @@ namespace DotNetOpenAuth.Test.OpenId.ChannelElements {
/// <param name="protocol">The protocol to construct the message with.</param>
/// <returns>The message ready to send from OP to RP.</returns>
private IndirectSignedResponse CreateResponseWithExtensions(Protocol protocol) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
+ Contract.Requires<ArgumentNullException>(protocol != null);
IndirectSignedResponse response = new IndirectSignedResponse(protocol.Version, RPUri);
response.ProviderEndpoint = OPUri;
diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeRequestTests.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeRequestTests.cs
index 228bda3..48b5727 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeRequestTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/AttributeExchange/AttributeRequestTests.cs
@@ -25,7 +25,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions {
new AttributeRequest(string.Empty);
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void CtorNullTypeUri() {
new AttributeRequest(null);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestUtilities.cs b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestUtilities.cs
index 47c8ec4..334fc93 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestUtilities.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Extensions/ExtensionTestUtilities.cs
@@ -5,7 +5,9 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Test.OpenId.Extensions {
+ using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
@@ -71,7 +73,7 @@ namespace DotNetOpenAuth.Test.OpenId.Extensions {
}
internal static void RegisterExtension(Channel channel, StandardOpenIdExtensionFactory.CreateDelegate extensionFactory) {
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
var factory = (OpenIdExtensionFactoryAggregator)channel.BindingElements.OfType<ExtensionsBindingElement>().Single().ExtensionFactory;
factory.Factories.OfType<StandardOpenIdExtensionFactory>().Single().RegisterExtension(extensionFactory);
diff --git a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs
index 3e599e9..cc02265 100644
--- a/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/IdentifierTests.cs
@@ -75,7 +75,7 @@ namespace DotNetOpenAuth.Test.OpenId {
Assert.AreEqual(this.uri, ((UriIdentifier)id).Uri.AbsoluteUri);
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void ParseNull() {
Identifier.Parse(null);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectSignedResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectSignedResponseTests.cs
index e140b24..8b0937a 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectSignedResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Messages/IndirectSignedResponseTests.cs
@@ -127,7 +127,7 @@ namespace DotNetOpenAuth.Test.OpenId.Messages {
}
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void GetReturnToArgumentNullKey() {
this.response.GetReturnToArgument(null);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs b/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs
index af9c5db..0f9d472 100644
--- a/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/OpenIdCoordinator.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Test.OpenId {
using System;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
using DotNetOpenAuth.OpenId;
@@ -36,7 +37,7 @@ namespace DotNetOpenAuth.Test.OpenId {
}
private static Action<OpenIdRelyingParty> WrapAction(Action<OpenIdRelyingParty> action) {
- ErrorUtilities.VerifyArgumentNotNull(action, "action");
+ Contract.Requires<ArgumentNullException>(action != null);
return rp => {
action(rp);
@@ -45,7 +46,7 @@ namespace DotNetOpenAuth.Test.OpenId {
}
private static Action<OpenIdProvider> WrapAction(Action<OpenIdProvider> action) {
- ErrorUtilities.VerifyArgumentNotNull(action, "action");
+ Contract.Requires<ArgumentNullException>(action != null);
return op => {
action(op);
diff --git a/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs b/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
index 0a6cdcc..8528aa7 100644
--- a/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/Provider/OpenIdProviderTests.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test.OpenId.Provider {
using System;
using System.IO;
+ using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions;
@@ -74,6 +75,7 @@ namespace DotNetOpenAuth.Test.OpenId.Provider {
/// </summary>
[TestMethod, ExpectedException(typeof(InvalidOperationException))]
public void GetRequestNoContext() {
+ HttpContext.Current = null;
this.provider.GetRequest();
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/ProviderEndpointDescriptionTests.cs b/src/DotNetOpenAuth.Test/OpenId/ProviderEndpointDescriptionTests.cs
index 005b8a0..089265f 100644
--- a/src/DotNetOpenAuth.Test/OpenId/ProviderEndpointDescriptionTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/ProviderEndpointDescriptionTests.cs
@@ -29,7 +29,7 @@ namespace DotNetOpenAuth.Test.OpenId {
this.se.IsExtensionSupported((Type)null);
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void IsExtensionSupportedNullString() {
this.se.IsExtensionSupported((string)null);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdTextBoxTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdTextBoxTests.cs
new file mode 100644
index 0000000..67255e3
--- /dev/null
+++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/OpenIdTextBoxTests.cs
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdTextBoxTests.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
+ using DotNetOpenAuth.OpenId.RelyingParty;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class OpenIdTextBoxTests : OpenIdTestBase {
+ /// <summary>
+ /// Verifies that the Text and Identifier properties interact correctly.
+ /// </summary>
+ [TestMethod]
+ public void IdentifierTextInteraction() {
+ var box = new OpenIdTextBox();
+ Assert.AreEqual(string.Empty, box.Text);
+ Assert.IsNull(box.Identifier);
+
+ box.Text = "=arnott";
+ Assert.AreEqual("=arnott", box.Text);
+ Assert.AreEqual("=arnott", box.Identifier.ToString());
+
+ box.Identifier = "=bob";
+ Assert.AreEqual("=bob", box.Text);
+ Assert.AreEqual("=bob", box.Identifier.ToString());
+
+ box.Text = string.Empty;
+ Assert.AreEqual(string.Empty, box.Text);
+ Assert.IsNull(box.Identifier);
+
+ box.Text = null;
+ Assert.AreEqual(string.Empty, box.Text);
+ Assert.IsNull(box.Identifier);
+
+ // Invalid identifier case
+ box.Text = "/";
+ Assert.AreEqual("/", box.Text);
+ Assert.IsNull(box.Identifier);
+
+ // blank out the invalid case
+ box.Identifier = null;
+ Assert.AreEqual(string.Empty, box.Text);
+ Assert.IsNull(box.Identifier);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs
index 083b988..701bcae 100644
--- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/PositiveAuthenticationResponseTests.cs
@@ -38,7 +38,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
Assert.AreEqual(AuthenticationStatus.Authenticated, authResponse.Status);
Assert.IsNull(authResponse.Exception);
Assert.AreEqual<string>(assertion.ClaimedIdentifier, authResponse.ClaimedIdentifier);
- Assert.AreEqual<string>(authResponseAccessor.endpoint.FriendlyIdentifierForDisplay, authResponse.FriendlyIdentifierForDisplay);
+ Assert.AreEqual<string>(authResponse.Endpoint.FriendlyIdentifierForDisplay, authResponse.FriendlyIdentifierForDisplay);
Assert.AreSame(extension, authResponse.GetUntrustedExtension(typeof(ClaimsResponse)));
Assert.AreSame(extension, authResponse.GetUntrustedExtension<ClaimsResponse>());
Assert.IsNull(authResponse.GetCallbackArgument("a"));
diff --git a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs
index bd09bc9..0af234a 100644
--- a/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/RelyingParty/ServiceEndpointTests.cs
@@ -180,7 +180,7 @@ namespace DotNetOpenAuth.Test.OpenId.RelyingParty {
Assert.IsFalse(se.IsTypeUriPresent("http://someother"));
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void IsTypeUriPresentNull() {
ServiceEndpoint se = ServiceEndpoint.CreateForClaimedIdentifier(this.claimedXri, this.userSuppliedXri, this.localId, new ProviderEndpointDescription(this.providerEndpoint, this.v20TypeUris), this.servicePriority, this.uriPriority);
se.IsTypeUriPresent(null);
diff --git a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
index f1823e6..5a5182f 100644
--- a/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/UriIdentifierTests.cs
@@ -31,7 +31,7 @@ namespace DotNetOpenAuth.Test.OpenId {
new UriIdentifier((Uri)null);
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void CtorNullString() {
new UriIdentifier((string)null);
}
diff --git a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
index 87ecd4b..46427bb 100644
--- a/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
+++ b/src/DotNetOpenAuth.Test/OpenId/XriIdentifierTests.cs
@@ -22,7 +22,7 @@ namespace DotNetOpenAuth.Test.OpenId {
base.SetUp();
}
- [TestMethod, ExpectedException(typeof(ArgumentNullException))]
+ [TestMethod, ExpectedException(typeof(ArgumentException))]
public void CtorNull() {
new XriIdentifier(null);
}
diff --git a/src/DotNetOpenAuth.Test/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.Test/Properties/AssemblyInfo.cs
index d6fd020..4744bfe 100644
--- a/src/DotNetOpenAuth.Test/Properties/AssemblyInfo.cs
+++ b/src/DotNetOpenAuth.Test/Properties/AssemblyInfo.cs
@@ -29,4 +29,4 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("aef0bb13-b79c-4854-a69a-de58b8feb5d1")]
-[assembly: ContractVerification(false)] \ No newline at end of file
+[assembly: ContractVerification(true)] \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Test/TestBase.cs b/src/DotNetOpenAuth.Test/TestBase.cs
index f9db40c..9185874 100644
--- a/src/DotNetOpenAuth.Test/TestBase.cs
+++ b/src/DotNetOpenAuth.Test/TestBase.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Test {
using System.IO;
using System.Reflection;
+ using System.Web;
using DotNetOpenAuth.Messaging.Reflection;
using DotNetOpenAuth.OAuth.Messages;
using log4net;
@@ -48,6 +49,7 @@ namespace DotNetOpenAuth.Test {
log4net.Config.XmlConfigurator.Configure(Assembly.GetExecutingAssembly().GetManifestResourceStream("DotNetOpenAuth.Test.Logging.config"));
MessageBase.LowSecurityMode = true;
this.messageDescriptions = new MessageDescriptionCollection();
+ SetMockHttpContext();
}
/// <summary>
@@ -58,6 +60,15 @@ namespace DotNetOpenAuth.Test {
log4net.LogManager.Shutdown();
}
+ /// <summary>
+ /// Sets HttpContext.Current to some empty (but non-null!) value.
+ /// </summary>
+ protected internal static void SetMockHttpContext() {
+ HttpContext.Current = new HttpContext(
+ new HttpRequest("mock", "http://mock", "mock"),
+ new HttpResponse(new StringWriter()));
+ }
+
protected internal static void SuspendLogging() {
LogManager.GetLoggerRepository().Threshold = LogManager.GetLoggerRepository().LevelMap["OFF"];
}
diff --git a/src/DotNetOpenAuth.sln b/src/DotNetOpenAuth.sln
index e6aff81..2c15c50 100644
--- a/src/DotNetOpenAuth.sln
+++ b/src/DotNetOpenAuth.sln
@@ -78,7 +78,7 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "InfoCardRelyingParty", "..\
Release.AspNetCompiler.ForceOverwrite = "true"
Release.AspNetCompiler.FixedNames = "false"
Release.AspNetCompiler.Debug = "False"
- VWDPort = "4490"
+ VWDPort = "59719"
DefaultWebSiteLanguage = "Visual Basic"
EndProjectSection
EndProject
@@ -135,7 +135,7 @@ Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "OAuthConsumer", "..\samples
Release.AspNetCompiler.ForceOverwrite = "true"
Release.AspNetCompiler.FixedNames = "false"
Release.AspNetCompiler.Debug = "False"
- VWDPort = "10335"
+ VWDPort = "59721"
EndProjectSection
EndProject
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "OAuthServiceProvider", "..\samples\OAuthServiceProvider", "{7ADCCD5C-AC2B-4340-9410-FE3A31A48191}"
@@ -164,6 +164,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenIdOfflineProvider", "..
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{E9ED920D-1F83-48C0-9A4B-09CCE505FE6D}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Project Templates", "Project Templates", "{B9EB8729-4B54-4453-B089-FE6761BA3057}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebFormsRelyingParty", "..\projecttemplates\WebFormsRelyingParty\WebFormsRelyingParty.csproj", "{A78F8FC6-7B03-4230-BE41-761E400D6810}"
+EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = DotNetOpenAuth.vsmdi
@@ -258,6 +262,12 @@ Global
{5C65603B-235F-47E6-B536-06385C60DE7F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C65603B-235F-47E6-B536-06385C60DE7F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C65603B-235F-47E6-B536-06385C60DE7F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.CodeAnalysis|Any CPU.ActiveCfg = Release|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.CodeAnalysis|Any CPU.Build.0 = Release|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A78F8FC6-7B03-4230-BE41-761E400D6810}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -278,5 +288,6 @@ Global
{9ADBE36D-9960-48F6-82E9-B4AC559E9AC3} = {1E2CBAA5-60A3-4AED-912E-541F5753CDC6}
{7ADCCD5C-AC2B-4340-9410-FE3A31A48191} = {1E2CBAA5-60A3-4AED-912E-541F5753CDC6}
{5C65603B-235F-47E6-B536-06385C60DE7F} = {E9ED920D-1F83-48C0-9A4B-09CCE505FE6D}
+ {A78F8FC6-7B03-4230-BE41-761E400D6810} = {B9EB8729-4B54-4453-B089-FE6761BA3057}
EndGlobalSection
EndGlobal
diff --git a/src/DotNetOpenAuth.vsmdi b/src/DotNetOpenAuth.vsmdi
index a404b8e..2d3834c 100644
--- a/src/DotNetOpenAuth.vsmdi
+++ b/src/DotNetOpenAuth.vsmdi
@@ -81,6 +81,7 @@
<TestLink id="ee7a04ba-0419-e08f-b838-01ec0f2a838e" name="UnsolicitedAssertion" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="1dcbaac6-0b11-8d8f-50d7-237574abbab1" name="ToDictionaryWithSkippedNullKey" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="715dcbdd-28f5-3c33-7d88-e0a1b648d89a" name="CreateRequestDumbMode" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="a1ff4ada-fe5d-d2f3-b7fb-8e72db02b3c3" name="Full" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="85a71d28-5f2f-75ce-9008-94982438bb5f" name="EqualityTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f334cc44-b2d0-2d67-358a-532def3bee80" name="ContainsKeyValuePair" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="fa05cc5f-2aaf-da22-ff52-caf1c3c6bb08" name="InsecureIdentifiersRejectedWithRequireSsl" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -91,7 +92,7 @@
<TestLink id="a260d196-066f-b0ae-a40e-fb9d962b28a4" name="XrdsDirectDiscovery_20" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="13acd546-c82e-324c-220d-34f42a6d705e" name="DeserializeSimple" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b56cdf04-0d29-8b13-468c-fb4b4258c619" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="2c2b48d0-8009-e7e0-9ff4-34f9973f59da" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="d474830d-3636-522c-1564-1b83e7a844d3" name="EmptyLine" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f44fb549-fc8a-7469-6eed-09d9f86cebff" name="SendDirectMessageResponse" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="8fc08a6d-6dcf-6256-42ff-073d4e4b6859" name="RequireDirectedIdentity" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f20bd439-e277-dc27-4ec4-5d5949d1c6bf" name="RequestUsingAuthorizationHeaderScattered" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -118,22 +119,23 @@
<TestLink id="db8d66cc-8206-57cc-0ce5-c8117813d77c" name="UnifyExtensionsasSregFromSchemaOpenIdNet" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="ef8a2274-4e58-0dde-4c5c-7f286865fc3a" name="SendReplayProtectedMessageSetsNonce" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="63e5025b-5ccf-5f13-6e05-d1e44502a6e9" name="RequestBadPreferredScheme" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="decb3fef-ef61-6794-5bc6-f7ff722a146e" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="2eb7c3dd-08aa-bfc0-edc8-e14bd82f7507" name="IdentifierTextInteraction" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="0d99e0a9-295e-08a6-bc31-2abb79c00ff8" name="IsReturnUrlDiscoverableRequireSsl" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f41ce7ab-5500-7eea-ab4d-8c646bffff23" name="HttpSchemePrepended" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="55b078e4-3933-d4e0-1151-a0a61321638e" name="ReadFromRequestAuthorization" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="38239ff0-1dfd-1116-55df-2790243dc768" name="IsValid" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="04be6602-31a2-f4ae-8fdb-b9ad2ac370be" name="PrepareMessageForReceiving" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="2c2b48d0-8009-e7e0-9ff4-34f9973f59da" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="5dd2e6c9-ff0f-48de-3a1a-cbab61370843" name="SetCountNegative" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="182203f3-5a16-b736-ea8c-b59f6bf7df66" name="InvalidRealmTwoWildcards2" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="4fd5baa2-8f39-8bf6-db8f-aa92592bfc06" name="CtorRequest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="d474830d-3636-522c-1564-1b83e7a844d3" name="EmptyLine" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="385c302d-b546-c164-2a59-2e35f75d7d60" name="RemoveStructDeclaredProperty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="870cce9d-5b17-953c-028f-827ec8b56da2" name="GetInvalidMessageType" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="97f0277a-86e6-5b5a-8419-c5253cabf2e0" name="UserAuthorizationUriTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="643add47-e9f3-20b8-d8e0-69e3f8926d33" name="CreateRequestsWithEndpointFilter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="d66a3b7a-1738-f6b3-aed1-e9bc80734ae9" name="CtorNullString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f3f84a10-317f-817a-1988-fddc10b75c20" name="AddTwoAttributes" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="5e2555a0-c07a-6488-c0e9-40ececd5021f" name="Serbian" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="e03f0038-5bb7-92f2-87a7-00a7d2c31a77" name="MessageExpirationWithoutTamperResistance" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="1f3ea08b-9880-635f-368f-9fcd3e25f3cd" name="ReadFromRequestNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9104f36f-6652-dcbb-a8ae-0d6fc34d76ed" name="AddCallbackArgumentClearsPreviousArgument" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -204,6 +206,7 @@
<TestLink id="6c95f443-463e-2856-f500-b9029645e44c" name="RequestNullRecipient" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="afafb5ef-662e-2da3-35b8-1d67bb0d79ce" name="AddPolicies" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="d0a92f93-9bb4-1821-81cf-e9b50e3e7d62" name="SendDirectMessageResponse" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="a66588b5-989d-8f8e-4994-4a066220516b" name="FileSerializeMatchesLength" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="17267cde-a296-8293-5bd1-9ca629817e4b" name="OpenIdRelyingParty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="cab73921-470b-331f-e601-b44805b67c81" name="GetAttributeValue" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="14ce54ee-5507-ac70-5514-99b7b83ba3d6" name="ExtensionFactories" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -228,18 +231,19 @@
<TestLink id="32604ca2-2577-9c33-f778-ff7e4c985ce5" name="RequestTokenUriWithOAuthParametersTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="fdf439d0-3b74-4d32-d395-d5a2559ed88b" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="3df1f62b-4fb4-d399-cf7f-40b72001d9d6" name="CtorUnsolicited" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="90f06a50-7b81-05ec-3dc0-7b3e8ade8cfa" name="NormalizeCase" storage="..\bin\debug\dotnetopenauth.test.dll" enabled="false" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="7c688207-e58a-86ed-90d0-687e28ee7e38" name="MultiPartPostAscii" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="8b11aa63-4c0f-41ff-f70c-882aacf939fe" name="CtorCountNegative" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="83271647-7da8-70b1-48a3-f1253a636088" name="IsExtensionSupportedEmptyString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b671ea40-3b8c-58d5-7788-f776810c49be" name="UnicodeTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="5435ab79-de25-e2fc-0b2d-b05d5686d27d" name="IsUrlWithinRealmTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="501fa941-c1ac-d4ef-56e7-46827788b571" name="GetRequestNoContext" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="01e33554-07cc-ff90-46f8-7d0ca036c9f6" name="ToDictionaryNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="3aa4e498-fd14-8274-22da-895436c1659e" name="AssociateUnencrypted" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="33dd2f79-cd69-f1c0-0e47-f7a17b5a8a8b" name="MultiPartPostMultiByteCharacters" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="0215f125-3936-484e-a8d0-d940d85bbc27" name="AppendQueryArgsNullDictionary" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="7c048c58-c456-3406-995f-adb742cc2501" name="DeserializeInvalidMessage" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="704a32d0-3f50-d462-f767-fd9cf1981b7f" name="ProviderVersion" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f362baf3-da5b-1b8c-39ae-7c9b2051270a" name="AuthenticationTimeUtcSetUtc" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="decb3fef-ef61-6794-5bc6-f7ff722a146e" name="EqualsTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="3bb818b4-5423-ad91-8cd9-8606ec85d2cb" name="ReadFromRequestAuthorizationScattered" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="30f3c12b-e510-de63-5acd-ae8e32866592" name="CreateQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9302541c-9c30-9ce7-66db-348ee4e9f6ee" name="UnifyExtensionsAsSregWithSreg" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -309,6 +313,7 @@
<TestLink id="47e8fae9-542d-1ebb-e17c-568cf9594539" name="RelativeUriDecodeFails" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f3af5fd8-f661-dc4f-4539-947b081a8b54" name="ReceivedReplayProtectedMessageJustOnce" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a14ddf08-796b-6cf1-a9bf-856dd50520fa" name="RequiredProtection" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="3aa4e498-fd14-8274-22da-895436c1659e" name="AssociateUnencrypted" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="5b4fee50-7c15-8c6b-3398-c82279646e5f" name="RequiredOptionalLists" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="59295023-d248-e9c4-68b9-65f6ea38490c" name="VerifyArgumentNotNullDoesNotThrow" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="e137b84a-d2a7-9af6-d15d-a92417668ccf" name="Transport" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -349,6 +354,7 @@
<TestLink id="6ef9df5a-d069-0103-5260-593808f232da" name="XrdsDiscoveryFromHead" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="313faac6-6357-5468-2d4d-4c9fba001678" name="TryParseNoThrow" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="7cbe4350-38d0-db7e-335c-93d9398fc95b" name="ExtensionOnlyFacadeLevel" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="96a66127-1904-4372-b88f-822cf63fc40a" name="MultiPartPostMultiByteCharacters" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="2f5cfa57-bcb4-39af-e769-2d7c34e2598e" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="ff78d828-b437-aaeb-e48a-85a5ad1fe396" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="29e45877-ca7a-85de-5c39-6d43befe1a1e" name="DiscoveryRequireSslWithInsecureXrdsButSecureLinkTags" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -395,6 +401,8 @@
<TestLink id="46ec24da-deb7-27c7-6dc6-52090e4fd1fb" name="Serialize" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="e9a5efc6-fde8-8fa4-0bda-2675a4a7e06b" name="DefaultReferenceTypeDeclaredPropertyHasNoKey" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b70b4bd5-6dae-b4ad-349c-c3ad70603773" name="ReadFromRequestQueryString" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="3217df89-2501-38b5-e9f5-f237a4b87ab3" name="FileSerializeMatchesLength" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="19fa1b28-559f-9306-97da-31beca460123" name="FormDataSerializeMatchesLength" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="5f02e24c-2972-c598-ca71-ea362b2fe7d8" name="SecuritySettingsSetNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="98a2ece8-c9e6-e6f3-c65e-f915b22077fa" name="RequestUsingGet" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="2cfefc4a-918a-3e16-0670-53eb33634525" name="GeneratesOnlyRequiredElements" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -405,12 +413,13 @@
<TestLink id="e2b1ae2a-8f30-b6b3-bca6-ef28fc5a0175" name="ClaimedIdAndLocalIdSpecifiedIsValid" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="58d69d1e-3bd2-3379-0af1-188f9cff2dd0" name="IsTypeUriPresentEmpty" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="495dd486-08dd-d365-7a84-67d96fef8460" name="SendIndirectedUndirectedMessage" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="24fb403f-be35-278e-9beb-e11177f2cd1e" name="FormDataSerializeMatchesLength" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="7cdabb8a-aefa-e90e-c32e-047404b64c2d" name="SerializeTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b4b00582-dcc9-7672-0c02-52432b074a92" name="GetNullType" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="f6979feb-7016-4e2b-14e2-e6c2c392419f" name="RemoveByKeyValuePair" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="58df167c-cf19-351c-cb09-5c52ae9f97be" name="DeserializeNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="a778f331-f14e-9d6e-f942-a023423540f6" name="Ctor" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="a1ff4ada-fe5d-d2f3-b7fb-8e72db02b3c3" name="Full" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="90f06a50-7b81-05ec-3dc0-7b3e8ade8cfa" name="NormalizeCase" storage="..\bin\debug\dotnetopenauth.test.dll" enabled="false" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="be00d3ef-f24d-eb8a-d251-4d691736ee6f" name="AddAttributeRequestNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="593e1d86-a6c2-c937-a1b4-6d25a595a1f1" name="EnumerableCacheCurrentThrowsBefore" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="030ac3cf-cfb6-ca47-f822-ec1d2979f0b3" name="Defaults" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -460,6 +469,7 @@
<TestLink id="b2b54c72-1d26-8c28-ebf5-7a5a4beeec43" name="VerifyNonZeroLengthOnNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="9684f7bf-cdda-a2c5-0822-29cb0add3835" name="ResponseNonceGetter" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="c4001e1c-75ad-236b-284f-318905d2bc3a" name="CreateRequestOnNonOpenID" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="8bbc6a02-b5a4-ea8e-2a77-8d1b6671ceb5" name="ImplicitConverstionFromUriTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="b58e4791-68c0-1bc0-2e48-e1351459ee46" name="UserSetupUrlSetForV1Immediate" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="c0d7cfcc-4f7e-e7df-3de2-b578c4c3d6ee" name="SpreadSregToAxMultipleSchemas" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="32e95494-d0bb-cfc7-a8d6-652f8816c6b4" name="ReadFromResponse" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
@@ -482,7 +492,7 @@
<TestLink id="9f880280-aa8f-91bb-4a5f-3fe044b6815a" name="CreateVerificationCode" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="10a8b8e5-e147-838c-0708-be98d5e4490e" name="CtorFull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="6daa360b-71e4-a972-143f-01b801fada84" name="DeserializeWithExtraFields" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
- <TestLink id="8bbc6a02-b5a4-ea8e-2a77-8d1b6671ceb5" name="ImplicitConverstionFromUriTests" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
+ <TestLink id="dd8ce888-6fd7-8d1b-f33a-c631a08c6871" name="MultiPartPostAscii" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="80719076-10fd-20a7-7ff3-a0aa2bc661cb" name="CtorNull" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="90d3c411-8895-a07f-7a21-258b9d43c5b2" name="InvalidMessageNoNonceReceivedTest" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
<TestLink id="121983e3-1336-70cb-8d2a-498629e92bec" name="GetReturnToArgumentNullKey" storage="..\bin\debug\dotnetopenauth.test.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, PublicKeyToken=b03f5f7f11d50a3a" />
diff --git a/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverter.cs b/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverter.cs
index 1c8c555..864d001 100644
--- a/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverter.cs
+++ b/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverter.cs
@@ -16,6 +16,7 @@ namespace DotNetOpenAuth.ComponentModel {
/// A type that generates suggested strings for Intellisense,
/// but doesn't actually convert between strings and other types.
/// </summary>
+ [ContractClass(typeof(SuggestedStringsConverterContract))]
public abstract class SuggestedStringsConverter : ConverterBase<string> {
/// <summary>
/// Initializes a new instance of the <see cref="SuggestedStringsConverter"/> class.
@@ -35,6 +36,9 @@ namespace DotNetOpenAuth.ComponentModel {
/// <param name="type">The type to reflect over.</param>
/// <returns>A collection of values.</returns>
internal static ICollection GetStandardValuesForCacheShared(Type type) {
+ Contract.Requires<ArgumentNullException>(type != null);
+ Contract.Ensures(Contract.Result<ICollection>() != null);
+
var fields = from field in type.GetFields(BindingFlags.Static | BindingFlags.Public)
select field.GetValue(null);
var properties = from prop in type.GetProperties(BindingFlags.Static | BindingFlags.Public)
diff --git a/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverterContract.cs b/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverterContract.cs
new file mode 100644
index 0000000..1573208
--- /dev/null
+++ b/src/DotNetOpenAuth/ComponentModel/SuggestedStringsConverterContract.cs
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------
+// <copyright file="SuggestedStringsConverterContract.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.ComponentModel {
+ using System;
+ using System.Collections;
+ using System.ComponentModel.Design.Serialization;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Reflection;
+
+ /// <summary>
+ /// Contract class for the <see cref="SuggestedStringsConverter"/> class.
+ /// </summary>
+ [ContractClassFor(typeof(SuggestedStringsConverter))]
+ internal abstract class SuggestedStringsConverterContract : SuggestedStringsConverter {
+ /// <summary>
+ /// Gets the type to reflect over for the well known values.
+ /// </summary>
+ protected override Type WellKnownValuesType {
+ get {
+ Contract.Ensures(Contract.Result<Type>() != null);
+ throw new NotImplementedException();
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/ComponentModel/UriConverter.cs b/src/DotNetOpenAuth/ComponentModel/UriConverter.cs
index cf8dde3..5e7c22b 100644
--- a/src/DotNetOpenAuth/ComponentModel/UriConverter.cs
+++ b/src/DotNetOpenAuth/ComponentModel/UriConverter.cs
@@ -101,9 +101,13 @@ namespace DotNetOpenAuth.ComponentModel {
protected override ICollection GetStandardValuesForCache() {
if (this.WellKnownValuesType != null) {
var fields = from field in this.WellKnownValuesType.GetFields(BindingFlags.Static | BindingFlags.Public)
- select new Uri((string)field.GetValue(null));
+ let value = (string)field.GetValue(null)
+ where value != null
+ select new Uri(value);
var properties = from prop in this.WellKnownValuesType.GetProperties(BindingFlags.Static | BindingFlags.Public)
- select new Uri((string)prop.GetValue(null, null));
+ let value = (string)prop.GetValue(null, null)
+ where value != null
+ select new Uri(value);
return (fields.Concat(properties)).ToArray();
} else {
return new Uri[0];
diff --git a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
index 56c7389..881fcdb 100644
--- a/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
+++ b/src/DotNetOpenAuth/Configuration/AssociationTypeCollection.cs
@@ -54,8 +54,7 @@ namespace DotNetOpenAuth.Configuration {
/// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
/// </returns>
protected override object GetElementKey(ConfigurationElement element) {
- Contract.Assume(element != null); // this should be Contract.Requires in base class.
- return ((AssociationTypeElement)element).AssociationType;
+ return ((AssociationTypeElement)element).AssociationType ?? string.Empty;
}
}
}
diff --git a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
index 88a1615..c7d963b 100644
--- a/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
+++ b/src/DotNetOpenAuth/Configuration/HostNameOrRegexCollection.cs
@@ -64,7 +64,7 @@ namespace DotNetOpenAuth.Configuration {
/// </returns>
protected override object GetElementKey(ConfigurationElement element) {
Contract.Assume(element != null); // this should be Contract.Requires in base class.
- return ((HostNameElement)element).Name;
+ return ((HostNameElement)element).Name ?? string.Empty;
}
}
}
diff --git a/src/DotNetOpenAuth/Configuration/OpenIdElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
index 58a8276..404b2f6 100644
--- a/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
+++ b/src/DotNetOpenAuth/Configuration/OpenIdElement.cs
@@ -63,8 +63,17 @@ namespace DotNetOpenAuth.Configuration {
[ConfigurationProperty(MaxAuthenticationTimePropertyName, DefaultValue = "0:05")] // 5 minutes
[PositiveTimeSpanValidator]
internal TimeSpan MaxAuthenticationTime {
- get { return (TimeSpan)this[MaxAuthenticationTimePropertyName]; }
- set { this[MaxAuthenticationTimePropertyName] = value; }
+ get {
+ Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero);
+ TimeSpan result = (TimeSpan)this[MaxAuthenticationTimePropertyName];
+ Contract.Assume(result > TimeSpan.Zero); // our PositiveTimeSpanValidator should take care of this
+ return result;
+ }
+
+ set {
+ Contract.Requires<ArgumentOutOfRangeException>(value > TimeSpan.Zero);
+ this[MaxAuthenticationTimePropertyName] = value;
+ }
}
/// <summary>
diff --git a/src/DotNetOpenAuth/Configuration/TypeConfigurationCollection.cs b/src/DotNetOpenAuth/Configuration/TypeConfigurationCollection.cs
index d928c87..000cb6a 100644
--- a/src/DotNetOpenAuth/Configuration/TypeConfigurationCollection.cs
+++ b/src/DotNetOpenAuth/Configuration/TypeConfigurationCollection.cs
@@ -18,7 +18,8 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
/// <typeparam name="T">The type that all types specified in the elements must derive from.</typeparam>
[ContractVerification(true)]
- internal class TypeConfigurationCollection<T> : ConfigurationElementCollection {
+ internal class TypeConfigurationCollection<T> : ConfigurationElementCollection
+ where T : class {
/// <summary>
/// Initializes a new instance of the TypeConfigurationCollection class.
/// </summary>
@@ -30,8 +31,7 @@ namespace DotNetOpenAuth.Configuration {
/// </summary>
/// <param name="elements">The elements that should be added to the collection initially.</param>
internal TypeConfigurationCollection(IEnumerable<Type> elements) {
- Contract.Requires(elements != null);
- ErrorUtilities.VerifyArgumentNotNull(elements, "elements");
+ Contract.Requires<ArgumentNullException>(elements != null);
foreach (Type element in elements) {
this.BaseAdd(new TypeConfigurationElement<T> { TypeName = element.FullName });
@@ -70,7 +70,7 @@ namespace DotNetOpenAuth.Configuration {
protected override object GetElementKey(ConfigurationElement element) {
Contract.Assume(element != null); // this should be Contract.Requires in base class.
TypeConfigurationElement<T> typedElement = (TypeConfigurationElement<T>)element;
- return !string.IsNullOrEmpty(typedElement.TypeName) ? typedElement.TypeName : typedElement.XamlSource;
+ return (!string.IsNullOrEmpty(typedElement.TypeName) ? typedElement.TypeName : typedElement.XamlSource) ?? string.Empty;
}
}
}
diff --git a/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs b/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs
index c8cf2aa..5ac88da 100644
--- a/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs
+++ b/src/DotNetOpenAuth/Configuration/TypeConfigurationElement.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Configuration {
using System;
using System.Configuration;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Reflection;
using System.Web;
@@ -18,7 +19,8 @@ namespace DotNetOpenAuth.Configuration {
/// the full type that provides some service used by this library.
/// </summary>
/// <typeparam name="T">A constraint on the type the user may provide.</typeparam>
- internal class TypeConfigurationElement<T> : ConfigurationElement {
+ internal class TypeConfigurationElement<T> : ConfigurationElement
+ where T : class {
/// <summary>
/// The name of the attribute whose value is the full name of the type the user is specifying.
/// </summary>
@@ -75,6 +77,8 @@ namespace DotNetOpenAuth.Configuration {
/// <param name="defaultValue">The value to return if no type is given in the .config file.</param>
/// <returns>The newly instantiated type.</returns>
public T CreateInstance(T defaultValue) {
+ Contract.Ensures(Contract.Result<T>() != null || Contract.Result<T>() == defaultValue);
+
return this.CreateInstance(defaultValue, false);
}
@@ -85,6 +89,8 @@ namespace DotNetOpenAuth.Configuration {
/// <param name="allowInternals">if set to <c>true</c> then internal types may be instantiated.</param>
/// <returns>The newly instantiated type.</returns>
public T CreateInstance(T defaultValue, bool allowInternals) {
+ Contract.Ensures(Contract.Result<T>() != null || Contract.Result<T>() == defaultValue);
+
if (this.CustomType != null) {
if (!allowInternals) {
// Although .NET will usually prevent our instantiating non-public types,
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index ac2e516..8aacd1b 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -12,6 +12,11 @@
<AssemblyName>DotNetOpenAuth</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <StandardCopyright>
+Copyright (c) 2009, Andrew Arnott. All rights reserved.
+Code licensed under the Ms-PL License:
+http://opensource.org/licenses/ms-pl.html
+</StandardCopyright>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -25,7 +30,7 @@
<DocumentationFile>..\..\bin\Debug\DotNetOpenAuth.xml</DocumentationFile>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsCustomRewriterAssembly>
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
@@ -48,6 +53,11 @@
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
<CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -60,7 +70,7 @@
<DocumentationFile>..\..\bin\Release\DotNetOpenAuth.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055</CodeAnalysisRules>
- <CodeContractsEnableRuntimeChecking>False</CodeContractsEnableRuntimeChecking>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsCustomRewriterAssembly>
</CodeContractsCustomRewriterAssembly>
<CodeContractsCustomRewriterClass>
@@ -81,16 +91,24 @@
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
+ <PropertyGroup>
<SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
+ <DelaySign>true</DelaySign>
+ <AssemblyOriginatorKeyFile>..\official-build-key.pub</AssemblyOriginatorKeyFile>
<DefineConstants>$(DefineConstants);StrongNameSigned</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\..\bin\CodeAnalysis\</OutputPath>
- <DefineConstants>CONTRACTS_FULL;DEBUG;TRACE</DefineConstants>
+ <DefineConstants>$(DefineConstants);CONTRACTS_FULL;DEBUG;TRACE</DefineConstants>
<DocumentationFile>..\..\bin\CodeAnalysis\DotNetOpenAuth.xml</DocumentationFile>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -105,7 +123,7 @@
</CodeContractsCustomRewriterClass>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
- <CodeContractsBuildReferenceAssembly>False</CodeContractsBuildReferenceAssembly>
+ <CodeContractsBuildReferenceAssembly>True</CodeContractsBuildReferenceAssembly>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
<CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
<CodeContractsLibPaths>
@@ -120,6 +138,13 @@
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
<RunCodeAnalysis>true</RunCodeAnalysis>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
@@ -146,9 +171,15 @@
<Reference Include="System.IdentityModel.Selectors">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
<Reference Include="System.ServiceModel">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
+ <Reference Include="System.ServiceModel.Web">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -176,6 +207,7 @@
<ItemGroup>
<Compile Include="ComponentModel\ClaimTypeSuggestions.cs" />
<Compile Include="ComponentModel\ConverterBase.cs" />
+ <Compile Include="ComponentModel\SuggestedStringsConverterContract.cs" />
<Compile Include="ComponentModel\IssuersSuggestions.cs" />
<Compile Include="ComponentModel\IdentifierConverter.cs" />
<Compile Include="ComponentModel\SuggestedStringsConverter.cs" />
@@ -231,9 +263,11 @@
<Compile Include="Messaging\EmptyList.cs" />
<Compile Include="Messaging\ErrorUtilities.cs" />
<Compile Include="Messaging\IMessageWithEvents.cs" />
+ <Compile Include="Messaging\IncomingWebResponseContract.cs" />
<Compile Include="Messaging\IProtocolMessageWithExtensions.cs" />
<Compile Include="Messaging\InternalErrorException.cs" />
<Compile Include="Messaging\KeyedCollectionDelegate.cs" />
+ <Compile Include="Messaging\MultipartPostPart.cs" />
<Compile Include="Messaging\NetworkDirectWebResponse.cs" />
<Compile Include="Messaging\OutgoingWebResponseActionResult.cs" />
<Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" />
@@ -353,6 +387,7 @@
<Compile Include="OpenId\ChannelElements\OpenIdMessageFactory.cs" />
<Compile Include="OpenId\ChannelElements\ReturnToSignatureBindingElement.cs" />
<Compile Include="OpenId\ChannelElements\SkipSecurityBindingElement.cs" />
+ <Compile Include="OpenId\AssociationContract.cs" />
<Compile Include="OpenId\Extensions\AliasManager.cs" />
<Compile Include="OpenId\Extensions\AttributeExchange\AttributeRequest.cs" />
<Compile Include="OpenId\Extensions\AttributeExchange\AttributeValues.cs" />
@@ -399,6 +434,7 @@
<Compile Include="OpenId\Messages\CheckAuthenticationRequest.cs" />
<Compile Include="OpenId\Messages\CheckAuthenticationResponse.cs" />
<Compile Include="OpenId\Messages\CheckIdRequest.cs" />
+ <Compile Include="OpenId\Messages\AssociateSuccessfulResponseContract.cs" />
<Compile Include="OpenId\Messages\IErrorMessage.cs" />
<Compile Include="OpenId\Messages\IndirectResponseBase.cs" />
<Compile Include="OpenId\Messages\IndirectSignedResponse.cs" />
@@ -461,8 +497,15 @@
<Compile Include="OpenId\RelyingParty\AssociationPreference.cs" />
<Compile Include="OpenId\RelyingParty\AuthenticationRequest.cs" />
<Compile Include="OpenId\RelyingParty\AuthenticationRequestMode.cs" />
+ <Compile Include="OpenId\RelyingParty\SelectorButtonContract.cs" />
+ <Compile Include="OpenId\RelyingParty\SelectorProviderButton.cs" />
+ <Compile Include="OpenId\RelyingParty\SelectorOpenIdButton.cs" />
+ <Compile Include="OpenId\RelyingParty\SelectorInfoCardButton.cs" />
<Compile Include="OpenId\RelyingParty\IRelyingPartyBehavior.cs" />
+ <Compile Include="OpenId\RelyingParty\OpenIdSelector.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs" />
+ <Compile Include="OpenId\RelyingParty\IXrdsProviderEndpointContract.cs" />
+ <Compile Include="OpenId\RelyingParty\IAuthenticationRequestContract.cs" />
<Compile Include="OpenId\RelyingParty\NegativeAuthenticationResponse.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdAjaxTextBox.cs" />
<Compile Include="OpenId\RelyingParty\OpenIdButton.cs" />
@@ -491,9 +534,10 @@
<Compile Include="OpenId\ProviderEndpointDescription.cs" />
<Compile Include="OpenId\Provider\ProviderSecuritySettings.cs" />
<Compile Include="OpenId\RelyingParty\IRelyingPartyApplicationStore.cs" />
- <Compile Include="OpenId\RelyingParty\AuthenticationResponseSnapshot.cs" />
+ <Compile Include="OpenId\RelyingParty\PositiveAuthenticationResponseSnapshot.cs" />
<Compile Include="OpenId\RelyingParty\PrivateSecretManager.cs" />
<Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettings.cs" />
+ <Compile Include="OpenId\RelyingParty\SelectorButton.cs" />
<Compile Include="OpenId\RelyingParty\ServiceEndpoint.cs" />
<Compile Include="OpenId\OpenIdXrdsHelper.cs" />
<Compile Include="OpenId\RelyingParty\SimpleXrdsProviderEndpoint.cs" />
@@ -542,6 +586,8 @@
<None Include="Messaging\Bindings\Bindings.cd" />
<None Include="Messaging\Exceptions.cd" />
<None Include="Messaging\Messaging.cd" />
+ <None Include="OpenId\RelyingParty\Controls.cd" />
+ <None Include="OpenId\RelyingParty\OpenIdRelyingParty.cd" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Messaging\MessagingStrings.resx">
@@ -573,7 +619,9 @@
<EmbeddedResource Include="OpenId\RelyingParty\login_failure.png" />
<EmbeddedResource Include="OpenId\RelyingParty\login_success %28lock%29.png" />
<EmbeddedResource Include="OpenId\RelyingParty\login_success.png" />
- <EmbeddedResource Include="OpenId\RelyingParty\OpenIdAjaxTextBox.js" />
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdAjaxTextBox.js">
+ <Copyright>$(StandardCopyright)</Copyright>
+ </EmbeddedResource>
<EmbeddedResource Include="OpenId\RelyingParty\spinner.gif" />
</ItemGroup>
<ItemGroup>
@@ -594,18 +642,41 @@
<EmbeddedResource Include="InfoCard\infocard_71x50.png" />
<EmbeddedResource Include="InfoCard\infocard_81x57.png" />
<EmbeddedResource Include="InfoCard\infocard_92x64.png" />
- <EmbeddedResource Include="InfoCard\SupportingScript.js" />
+ <EmbeddedResource Include="InfoCard\SupportingScript.js">
+ <Copyright>$(StandardCopyright)</Copyright>
+ </EmbeddedResource>
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.js" />
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdRelyingPartyControlBase.js">
+ <Copyright>$(StandardCopyright)</Copyright>
+ </EmbeddedResource>
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="InfoCard\InfoCardStrings.sr.resx" />
+ <EmbeddedResource Include="Messaging\MessagingStrings.sr.resx" />
+ <EmbeddedResource Include="OAuth\OAuthStrings.sr.resx" />
<EmbeddedResource Include="OpenId\Behaviors\BehaviorStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>BehaviorStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
- <EmbeddedResource Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js" />
+ <EmbeddedResource Include="OpenId\Behaviors\BehaviorStrings.sr.resx" />
+ <EmbeddedResource Include="OpenId\OpenIdStrings.sr.resx" />
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.js">
+ <Copyright>$(StandardCopyright)</Copyright>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Strings.sr.resx" />
+ <EmbeddedResource Include="Xrds\XrdsStrings.sr.resx" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdAjaxTextBox.css" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdSelector.js" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="OpenId\RelyingParty\OpenIdSelector.css" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
-</Project>
+ <Import Project="..\..\tools\JavascriptPacker.targets" />
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/GlobalSuppressions.cs b/src/DotNetOpenAuth/GlobalSuppressions.cs
index d0e0d05..2124801 100644
--- a/src/DotNetOpenAuth/GlobalSuppressions.cs
+++ b/src/DotNetOpenAuth/GlobalSuppressions.cs
@@ -48,3 +48,5 @@
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "icam", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "idmanagement", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "no-pii", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "req", Scope = "member", Target = "DotNetOpenAuth.OpenId.Provider.IAuthenticationRequestContract.#DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest.ClaimedIdentifier")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "runat", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")]
diff --git a/src/DotNetOpenAuth/InfoCard/ClaimType.cs b/src/DotNetOpenAuth/InfoCard/ClaimType.cs
index 5a25ef8..9d3056a 100644
--- a/src/DotNetOpenAuth/InfoCard/ClaimType.cs
+++ b/src/DotNetOpenAuth/InfoCard/ClaimType.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.InfoCard {
using System;
using System.ComponentModel;
+ using System.Diagnostics.Contracts;
using System.IdentityModel.Claims;
using System.Web.UI;
@@ -15,6 +16,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
[PersistChildren(false)]
[Serializable]
+ [ContractVerification(true)]
public class ClaimType {
/// <summary>
/// Initializes a new instance of the <see cref="ClaimType"/> class.
@@ -47,7 +49,7 @@ namespace DotNetOpenAuth.InfoCard {
/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
/// </returns>
public override string ToString() {
- return this.Name != null ? this.Name : null;
+ return this.Name ?? "<no name>";
}
}
}
diff --git a/src/DotNetOpenAuth/InfoCard/InfoCardImage.cs b/src/DotNetOpenAuth/InfoCard/InfoCardImage.cs
index 2b7b25f..247f461 100644
--- a/src/DotNetOpenAuth/InfoCard/InfoCardImage.cs
+++ b/src/DotNetOpenAuth/InfoCard/InfoCardImage.cs
@@ -23,6 +23,7 @@
namespace DotNetOpenAuth.InfoCard {
using System;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
/// <summary>
@@ -129,6 +130,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <returns>The manifest resource stream name.</returns>
internal static string GetImageManifestResourceStreamName(InfoCardImageSize size) {
string imageSize = size.ToString();
+ Contract.Assume(imageSize.Length >= 6);
imageSize = imageSize.Substring(4);
return String.Format(CultureInfo.InvariantCulture, UrlFormatString, imageSize);
}
diff --git a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
index fe2c2a2..b4174bc 100644
--- a/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
+++ b/src/DotNetOpenAuth/InfoCard/InfoCardSelector.cs
@@ -16,6 +16,7 @@ namespace DotNetOpenAuth.InfoCard {
using System.Drawing.Design;
using System.Globalization;
using System.Linq;
+ using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
@@ -272,17 +273,20 @@ namespace DotNetOpenAuth.InfoCard {
}
set {
- if (this.Page != null && !this.DesignMode) {
- // Validate new value by trying to construct a Uri based on it.
- new Uri(new HttpRequestInfo(HttpContext.Current.Request).UrlBeforeRewriting, this.Page.ResolveUrl(value)); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
+ ErrorUtilities.VerifyOperation(string.IsNullOrEmpty(value) || this.Page == null || this.DesignMode || (HttpContext.Current != null && HttpContext.Current.Request != null), MessagingStrings.HttpContextRequired);
+ if (!string.IsNullOrEmpty(value)) {
+ if (this.Page != null && !this.DesignMode) {
+ // Validate new value by trying to construct a Uri based on it.
+ new Uri(new HttpRequestInfo(HttpContext.Current.Request).UrlBeforeRewriting, this.Page.ResolveUrl(value)); // throws an exception on failure.
} else {
- throw new UriFormatException();
+ // We can't fully test it, but it should start with either ~/ or a protocol.
+ if (Regex.IsMatch(value, @"^https?://")) {
+ new Uri(value); // make sure it's fully-qualified, but ignore wildcards
+ } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
+ // this is valid too
+ } else {
+ throw new UriFormatException();
+ }
}
}
@@ -448,8 +452,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <returns>The event arguments sent to the event handlers.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "decryptor", Justification = "By design")]
protected virtual ReceivingTokenEventArgs OnReceivingToken(string tokenXml) {
- Contract.Requires(tokenXml != null);
- ErrorUtilities.VerifyArgumentNotNull(tokenXml, "tokenXml");
+ Contract.Requires<ArgumentNullException>(tokenXml != null);
var args = new ReceivingTokenEventArgs(tokenXml);
var receivingToken = this.ReceivingToken;
@@ -465,8 +468,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
/// <param name="token">The token, if it was decrypted.</param>
protected virtual void OnReceivedToken(Token token) {
- Contract.Requires(token != null);
- ErrorUtilities.VerifyArgumentNotNull(token, "token");
+ Contract.Requires<ArgumentNullException>(token != null);
var receivedInfoCard = this.ReceivedToken;
if (receivedInfoCard != null) {
@@ -480,8 +482,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="unprocessedToken">The unprocessed token.</param>
/// <param name="ex">The exception generated while processing the token.</param>
protected virtual void OnTokenProcessingError(string unprocessedToken, Exception ex) {
- Contract.Requires(unprocessedToken != null);
- Contract.Requires(ex != null);
+ Contract.Requires<ArgumentNullException>(unprocessedToken != null);
+ Contract.Requires<ArgumentNullException>(ex != null);
var tokenProcessingError = this.TokenProcessingError;
if (tokenProcessingError != null) {
@@ -532,6 +534,8 @@ namespace DotNetOpenAuth.InfoCard {
// the privacy URL is present but the privacy version is not.
ErrorUtilities.VerifyOperation(string.IsNullOrEmpty(this.PrivacyUrl) || !string.IsNullOrEmpty(this.PrivacyVersion), InfoCardStrings.PrivacyVersionRequiredWithPrivacyUrl);
}
+
+ this.RegisterInfoCardSelectorObjectScript();
}
/// <summary>
@@ -540,12 +544,18 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="name">The parameter name.</param>
/// <param name="value">The parameter value.</param>
/// <returns>The control that renders to the Param tag.</returns>
- private static Control CreateParam(string name, string value) {
- Contract.Ensures(Contract.Result<Control>() != null);
- HtmlGenericControl control = new HtmlGenericControl(HtmlTextWriterTag.Param.ToString());
- control.Attributes.Add(HtmlTextWriterAttribute.Name.ToString(), name);
- control.Attributes.Add(HtmlTextWriterAttribute.Value.ToString(), value);
- return control;
+ private static string CreateParamJs(string name, string value) {
+ Contract.Ensures(Contract.Result<string>() != null);
+ string scriptFormat = @" objp = document.createElement('param');
+ objp.name = {0};
+ objp.value = {1};
+ obj.appendChild(objp);
+";
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ scriptFormat,
+ MessagingUtilities.GetSafeJavascriptValue(name),
+ MessagingUtilities.GetSafeJavascriptValue(value));
}
/// <summary>
@@ -565,17 +575,7 @@ namespace DotNetOpenAuth.InfoCard {
supportedPanel.Style[HtmlTextWriterStyle.Display] = "none";
}
- supportedPanel.Controls.Add(this.CreateInfoCardSelectorObject());
-
- // add clickable image
- Image image = new Image();
- image.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(InfoCardSelector), InfoCardImage.GetImageManifestResourceStreamName(this.ImageSize));
- image.AlternateText = InfoCardStrings.SelectorClickPrompt;
- image.ToolTip = this.ToolTip;
- image.Style[HtmlTextWriterStyle.Cursor] = "hand";
-
- image.Attributes["onclick"] = this.GetInfoCardSelectorActivationScript(false);
- supportedPanel.Controls.Add(image);
+ supportedPanel.Controls.Add(this.CreateInfoCardImage());
// trigger the selector at page load?
if (this.AutoPopup && !this.Page.IsPostBack) {
@@ -630,47 +630,74 @@ namespace DotNetOpenAuth.InfoCard {
}
/// <summary>
- /// Creates the info card selector &lt;object&gt; HTML tag.
+ /// Adds the javascript that adds the info card selector &lt;object&gt; HTML tag to the page.
/// </summary>
- /// <returns>A control that renders to the &lt;object&gt; tag.</returns>
[Pure]
- private Control CreateInfoCardSelectorObject() {
- HtmlGenericControl cardSpaceControl = new HtmlGenericControl(HtmlTextWriterTag.Object.ToString());
- cardSpaceControl.Attributes.Add(HtmlTextWriterAttribute.Type.ToString(), "application/x-informationcard");
- cardSpaceControl.Attributes.Add(HtmlTextWriterAttribute.Id.ToString(), this.ClientID + "_cs");
+ private void RegisterInfoCardSelectorObjectScript() {
+ string scriptFormat = @"{{
+ var obj = document.createElement('object');
+ obj.type = 'application/x-informationcard';
+ obj.id = {0};
+ obj.style.display = 'none';
+";
+ StringBuilder script = new StringBuilder();
+ script.AppendFormat(
+ CultureInfo.InvariantCulture,
+ scriptFormat,
+ MessagingUtilities.GetSafeJavascriptValue(this.ClientID + "_cs"));
if (!string.IsNullOrEmpty(this.Issuer)) {
- cardSpaceControl.Controls.Add(CreateParam("issuer", this.Issuer));
+ script.AppendLine(CreateParamJs("issuer", this.Issuer));
}
if (!string.IsNullOrEmpty(this.IssuerPolicy)) {
- cardSpaceControl.Controls.Add(CreateParam("issuerPolicy", this.IssuerPolicy));
+ script.AppendLine(CreateParamJs("issuerPolicy", this.IssuerPolicy));
}
if (!string.IsNullOrEmpty(this.TokenType)) {
- cardSpaceControl.Controls.Add(CreateParam("tokenType", this.TokenType));
+ script.AppendLine(CreateParamJs("tokenType", this.TokenType));
}
string requiredClaims, optionalClaims;
this.GetRequestedClaims(out requiredClaims, out optionalClaims);
ErrorUtilities.VerifyArgument(!string.IsNullOrEmpty(requiredClaims) || !string.IsNullOrEmpty(optionalClaims), InfoCardStrings.EmptyClaimListNotAllowed);
if (!string.IsNullOrEmpty(requiredClaims)) {
- cardSpaceControl.Controls.Add(CreateParam("requiredClaims", requiredClaims));
+ script.AppendLine(CreateParamJs("requiredClaims", requiredClaims));
}
if (!string.IsNullOrEmpty(optionalClaims)) {
- cardSpaceControl.Controls.Add(CreateParam("optionalClaims", optionalClaims));
+ script.AppendLine(CreateParamJs("optionalClaims", optionalClaims));
}
if (!string.IsNullOrEmpty(this.PrivacyUrl)) {
string privacyUrl = this.DesignMode ? this.PrivacyUrl : new Uri(Page.Request.Url, Page.ResolveUrl(this.PrivacyUrl)).AbsoluteUri;
- cardSpaceControl.Controls.Add(CreateParam("privacyUrl", privacyUrl));
+ script.AppendLine(CreateParamJs("privacyUrl", privacyUrl));
}
if (!string.IsNullOrEmpty(this.PrivacyVersion)) {
- cardSpaceControl.Controls.Add(CreateParam("privacyVersion", this.PrivacyVersion));
+ script.AppendLine(CreateParamJs("privacyVersion", this.PrivacyVersion));
}
- return cardSpaceControl;
+ script.AppendLine(@"if (document.infoCard.isSupported()) { document.write(obj.outerHTML); }
+}");
+
+ this.Page.ClientScript.RegisterClientScriptBlock(typeof(InfoCardSelector), this.ClientID + "tag", script.ToString(), true);
+ }
+
+ /// <summary>
+ /// Creates the info card clickable image.
+ /// </summary>
+ /// <returns>An Image object.</returns>
+ [Pure]
+ private Image CreateInfoCardImage() {
+ // add clickable image
+ Image image = new Image();
+ image.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(InfoCardSelector), InfoCardImage.GetImageManifestResourceStreamName(this.ImageSize));
+ image.AlternateText = InfoCardStrings.SelectorClickPrompt;
+ image.ToolTip = this.ToolTip;
+ image.Style[HtmlTextWriterStyle.Cursor] = "hand";
+
+ image.Attributes["onclick"] = this.GetInfoCardSelectorActivationScript(false);
+ return image;
}
/// <summary>
@@ -681,7 +708,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="optional">A space-delimited list of claim type URIs for claims that may optionally be included in a submitted Information Card.</param>
[Pure]
private void GetRequestedClaims(out string required, out string optional) {
- Contract.Requires(this.ClaimsRequested != null);
+ Contract.Requires<InvalidOperationException>(this.ClaimsRequested != null);
Contract.Ensures(Contract.ValueAtReturn<string>(out required) != null);
Contract.Ensures(Contract.ValueAtReturn<string>(out optional) != null);
@@ -696,10 +723,10 @@ namespace DotNetOpenAuth.InfoCard {
string[] requiredClaimsArray = requiredClaims.ToArray();
string[] optionalClaimsArray = optionalClaims.ToArray();
- Contract.Assume(requiredClaimsArray != null);
- Contract.Assume(optionalClaimsArray != null);
required = string.Join(" ", requiredClaimsArray);
optional = string.Join(" ", optionalClaimsArray);
+ Contract.Assume(required != null);
+ Contract.Assume(optional != null);
}
/// <summary>
@@ -707,7 +734,7 @@ namespace DotNetOpenAuth.InfoCard {
/// or to downgrade gracefully if the user agent lacks an Information Card selector.
/// </summary>
private void RenderSupportingScript() {
- Contract.Requires(this.infoCardSupportedPanel != null);
+ Contract.Requires<InvalidOperationException>(this.infoCardSupportedPanel != null);
this.Page.ClientScript.RegisterClientScriptResource(typeof(InfoCardSelector), ScriptResourceName);
@@ -726,4 +753,4 @@ namespace DotNetOpenAuth.InfoCard {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/DotNetOpenAuth/InfoCard/InfoCardStrings.sr.resx b/src/DotNetOpenAuth/InfoCard/InfoCardStrings.sr.resx
new file mode 100644
index 0000000..9df0429
--- /dev/null
+++ b/src/DotNetOpenAuth/InfoCard/InfoCardStrings.sr.resx
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="AudienceMismatch" xml:space="preserve">
+ <value>Token je neispravan: restrikcije u prijemu se ne slažu sa Relying Party.</value>
+ </data>
+ <data name="EmptyClaimListNotAllowed" xml:space="preserve">
+ <value>Tražena lista zahteva za ukljuÄivanje u InfoCard ne sme biti prazna.</value>
+ </data>
+ <data name="EncryptionAlgorithmNotFound" xml:space="preserve">
+ <value>encryptionAlgorithm nije pronađen.</value>
+ </data>
+ <data name="PpidClaimRequired" xml:space="preserve">
+ <value>Ova operacija zahteva da PPID zahtev bude ukljuÄen u InfoCard token.</value>
+ </data>
+ <data name="SelectorClickPrompt" xml:space="preserve">
+ <value>Kliknite ovde da odaberete vaš Information Card.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/InfoCard/ReceivedTokenEventArgs.cs b/src/DotNetOpenAuth/InfoCard/ReceivedTokenEventArgs.cs
index 1511e2d..6c6a5af 100644
--- a/src/DotNetOpenAuth/InfoCard/ReceivedTokenEventArgs.cs
+++ b/src/DotNetOpenAuth/InfoCard/ReceivedTokenEventArgs.cs
@@ -31,6 +31,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
protected void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
index f3722d7..aaf734b 100644
--- a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
+++ b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs
@@ -21,7 +21,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
/// <param name="tokenXml">The raw token XML, prior to any decryption.</param>
internal ReceivingTokenEventArgs(string tokenXml) {
- Contract.Requires(tokenXml != null);
+ Contract.Requires<ArgumentNullException>(tokenXml != null);
this.TokenXml = tokenXml;
this.IsEncrypted = Token.IsEncrypted(this.TokenXml);
@@ -63,7 +63,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
/// <param name="securityToken">The security token.</param>
public void AddDecryptingToken(SecurityToken securityToken) {
- Contract.Requires(securityToken != null);
+ Contract.Requires<ArgumentNullException>(securityToken != null);
this.DecryptingTokens.Add(securityToken);
}
@@ -72,8 +72,8 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
/// <param name="certificate">The certificate.</param>
public void AddDecryptingToken(X509Certificate2 certificate) {
- Contract.Requires(certificate != null);
- Contract.Requires(certificate.HasPrivateKey);
+ Contract.Requires<ArgumentNullException>(certificate != null);
+ Contract.Requires<ArgumentException>(certificate.HasPrivateKey);
this.AddDecryptingToken(new X509SecurityToken(certificate));
}
@@ -81,6 +81,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
protected void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/InfoCard/SupportingScript.js b/src/DotNetOpenAuth/InfoCard/SupportingScript.js
index ce4b02d..a883cd7 100644
--- a/src/DotNetOpenAuth/InfoCard/SupportingScript.js
+++ b/src/DotNetOpenAuth/InfoCard/SupportingScript.js
@@ -1,5 +1,7 @@
+/*jslint white: true, onevar: true, browser: true, undef: true, nomen: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */
+"use strict";
document.infoCard = {
- isSupported: function() {
+ isSupported: function () {
/// <summary>
/// Determines if information cards are supported by the
/// browser.
@@ -7,19 +9,20 @@ document.infoCard = {
/// <returns>
/// true-if the browser supports information cards.
///</returns>
+ var IEVer, embed, x, event;
- var IEVer = -1;
- if (navigator.appName == 'Microsoft Internet Explorer') {
- if (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) {
+ IEVer = -1;
+ if (navigator.appName === 'Microsoft Internet Explorer') {
+ if (new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})").exec(navigator.userAgent) !== null) {
IEVer = parseFloat(RegExp.$1);
}
}
// Look for IE 7+.
if (IEVer >= 7) {
- var embed = document.createElement("object");
+ embed = document.createElement("object");
embed.type = "application/x-informationcard";
- return !(embed.issuerPolicy === undefined) && embed.isInstalled;
+ return embed.issuerPolicy !== undefined && embed.isInstalled;
}
// not IE (any version)
@@ -32,22 +35,23 @@ document.infoCard = {
// check for the IdentitySelector event handler is there.
if (document.addEventListener) {
- var event = document.createEvent("Events");
+ event = document.createEvent("Events");
event.initEvent("IdentitySelectorAvailable", true, true);
top.dispatchEvent(event);
- if (top.IdentitySelectorAvailable == true) {
+ if (top.IdentitySelectorAvailable === true) {
return true;
}
}
}
-
+
return false;
},
- activate: function(selectorId, hiddenFieldName) {
- var selector = document.getElementById(selectorId);
- var hiddenField = document.getElementsByName(hiddenFieldName)[0];
+ activate: function (selectorId, hiddenFieldName) {
+ var selector, hiddenField;
+ selector = document.getElementById(selectorId);
+ hiddenField = document.getElementsByName(hiddenFieldName)[0];
try {
hiddenField.value = selector.value;
} catch (e) {
@@ -71,7 +75,7 @@ document.infoCard = {
}
},
- showStatic: function(divName) {
+ showStatic: function (divName) {
var div = document.getElementById(divName);
if (div) {
div.style.visibility = 'visible';
@@ -95,26 +99,26 @@ document.infoCard = {
checkDynamic: function (controlDiv, unsupportedDiv) {
if (this.isSupported()) {
this.showDynamic(controlDiv);
- if (unsupportedDiv != '') {
+ if (unsupportedDiv) {
this.hideDynamic(unsupportedDiv);
}
} else {
this.hideDynamic(controlDiv);
- if (unsupportedDiv != '') {
+ if (unsupportedDiv) {
this.showDynamic(unsupportedDiv);
}
}
},
- checkStatic: function(controlDiv, unsupportedDiv) {
+ checkStatic: function (controlDiv, unsupportedDiv) {
if (this.isSupported()) {
this.showStatic(controlDiv);
- if (unsupportedDiv != '') {
+ if (unsupportedDiv) {
this.hideStatic(unsupportedDiv);
}
} else {
this.hideStatic(controlDiv);
- if (unsupportedDiv != '') {
+ if (unsupportedDiv) {
this.showDynamic(unsupportedDiv);
}
}
diff --git a/src/DotNetOpenAuth/InfoCard/Token/Token.cs b/src/DotNetOpenAuth/InfoCard/Token/Token.cs
index 5c955ed..4656e3f 100644
--- a/src/DotNetOpenAuth/InfoCard/Token/Token.cs
+++ b/src/DotNetOpenAuth/InfoCard/Token/Token.cs
@@ -42,19 +42,20 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="decryptor">The decryptor to use to decrypt the token, if necessary..</param>
/// <exception cref="InformationCardException">Thrown for any problem decoding or decrypting the token.</exception>
private Token(string tokenXml, Uri audience, TokenDecryptor decryptor) {
- Contract.Requires(tokenXml != null && tokenXml.Length > 0);
- Contract.Requires(decryptor != null || !IsEncrypted(tokenXml));
- ErrorUtilities.VerifyNonZeroLength(tokenXml, "tokenXml");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires<ArgumentException>(decryptor != null || !IsEncrypted(tokenXml));
+ Contract.Ensures(this.AuthorizationContext != null);
byte[] decryptedBytes;
string decryptedString;
using (XmlReader tokenReader = XmlReader.Create(new StringReader(tokenXml))) {
+ Contract.Assume(tokenReader != null); // BCL contract should say XmlReader.Create result != null
if (IsEncrypted(tokenReader)) {
Logger.InfoCard.DebugFormat("Incoming SAML token, before decryption: {0}", tokenXml);
- ErrorUtilities.VerifyArgumentNotNull(decryptor, "decryptor");
decryptedBytes = decryptor.DecryptToken(tokenReader);
decryptedString = Encoding.UTF8.GetString(decryptedBytes);
+ Contract.Assume(decryptedString != null); // BCL contracts should be enhanced here
} else {
decryptedBytes = Encoding.UTF8.GetBytes(tokenXml);
decryptedString = tokenXml;
@@ -106,7 +107,7 @@ namespace DotNetOpenAuth.InfoCard {
/// </summary>
public string SiteSpecificId {
get {
- Contract.Requires(this.Claims.ContainsKey(ClaimTypes.PPID));
+ Contract.Requires<InvalidOperationException>(this.Claims.ContainsKey(ClaimTypes.PPID) && !string.IsNullOrEmpty(this.Claims[ClaimTypes.PPID]));
string ppidValue;
ErrorUtilities.VerifyOperation(this.Claims.TryGetValue(ClaimTypes.PPID, out ppidValue) && ppidValue != null, InfoCardStrings.PpidClaimRequired);
return TokenUtility.CalculateSiteSpecificID(ppidValue);
@@ -132,7 +133,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="tokenXml">The token XML.</param>
/// <returns>The deserialized token.</returns>
public static Token Read(string tokenXml) {
- Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml));
return Read(tokenXml, (Uri)null);
}
@@ -143,7 +144,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="audience">The URI that this token must have been crafted to be sent to. Use <c>null</c> to accept any intended audience.</param>
/// <returns>The deserialized token.</returns>
public static Token Read(string tokenXml, Uri audience) {
- Contract.Requires(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml));
return Read(tokenXml, audience, Enumerable.Empty<SecurityToken>());
}
@@ -154,8 +155,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
/// <returns>The deserialized token.</returns>
public static Token Read(string tokenXml, IEnumerable<SecurityToken> decryptionTokens) {
- Contract.Requires(!String.IsNullOrEmpty(tokenXml));
- Contract.Requires(decryptionTokens != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires<ArgumentNullException>(decryptionTokens != null);
return Read(tokenXml, null, decryptionTokens);
}
@@ -167,8 +168,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="decryptionTokens">Any X.509 certificates that may be used to decrypt the token, if necessary.</param>
/// <returns>The deserialized token.</returns>
public static Token Read(string tokenXml, Uri audience, IEnumerable<SecurityToken> decryptionTokens) {
- Contract.Requires(!String.IsNullOrEmpty(tokenXml));
- Contract.Requires(decryptionTokens != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml));
+ Contract.Requires<ArgumentNullException>(decryptionTokens != null);
Contract.Ensures(Contract.Result<Token>() != null);
TokenDecryptor decryptor = null;
@@ -190,14 +191,27 @@ namespace DotNetOpenAuth.InfoCard {
/// </returns>
[Pure]
internal static bool IsEncrypted(string tokenXml) {
- Contract.Requires(tokenXml != null);
- ErrorUtilities.VerifyArgumentNotNull(tokenXml, "tokenXml");
+ Contract.Requires<ArgumentNullException>(tokenXml != null);
using (XmlReader tokenReader = XmlReader.Create(new StringReader(tokenXml))) {
+ Contract.Assume(tokenReader != null); // CC missing for XmlReader.Create
return IsEncrypted(tokenReader);
}
}
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant()
+ {
+ Contract.Invariant(this.AuthorizationContext != null);
+ }
+#endif
+
/// <summary>
/// Determines whether the specified token XML is encrypted.
/// </summary>
@@ -206,8 +220,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <c>true</c> if the specified token XML is encrypted; otherwise, <c>false</c>.
/// </returns>
private static bool IsEncrypted(XmlReader tokenXmlReader) {
- Contract.Requires(tokenXmlReader != null);
- ErrorUtilities.VerifyArgumentNotNull(tokenXmlReader, "tokenXmlReader");
+ Contract.Requires<ArgumentNullException>(tokenXmlReader != null);
return tokenXmlReader.IsStartElement(TokenDecryptor.XmlEncryptionStrings.EncryptedData, TokenDecryptor.XmlEncryptionStrings.Namespace);
}
diff --git a/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs b/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
index 1038ad7..2257f15 100644
--- a/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
+++ b/src/DotNetOpenAuth/InfoCard/Token/TokenDecryptor.cs
@@ -89,9 +89,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="reader">The encrypted token XML reader.</param>
/// <returns>A byte array of the contents of the encrypted token</returns>
internal byte[] DecryptToken(XmlReader reader) {
- Contract.Requires(reader != null);
+ Contract.Requires<ArgumentNullException>(reader != null);
Contract.Ensures(Contract.Result<byte[]>() != null);
- ErrorUtilities.VerifyArgumentNotNull(reader, "reader");
byte[] securityTokenData;
string encryptionAlgorithm;
@@ -148,6 +147,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
protected void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/InfoCard/Token/TokenUtility.cs b/src/DotNetOpenAuth/InfoCard/Token/TokenUtility.cs
index 85b951d..48b7794 100644
--- a/src/DotNetOpenAuth/InfoCard/Token/TokenUtility.cs
+++ b/src/DotNetOpenAuth/InfoCard/Token/TokenUtility.cs
@@ -48,6 +48,8 @@ namespace DotNetOpenAuth.InfoCard {
/// The authorization context carried by the token.
/// </returns>
internal static AuthorizationContext AuthenticateToken(XmlReader reader, Uri audience) {
+ Contract.Ensures(Contract.Result<AuthorizationContext>() != null);
+
// Extensibility Point:
// in order to accept different token types, you would need to add additional
// code to create an authenticationcontext from the security token.
@@ -160,8 +162,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="authzContext">The Authorization Context</param>
/// <returns>A unique ID for this user at this web site.</returns>
internal static string GetUniqueName(AuthorizationContext authzContext) {
- Contract.Requires(authzContext != null);
- ErrorUtilities.VerifyArgumentNotNull(authzContext, "authzContext");
+ Contract.Requires<ArgumentNullException>(authzContext != null);
Claim uniqueIssuerClaim = null;
Claim uniqueUserClaim = null;
@@ -217,9 +218,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="ppid">The personal private identifier.</param>
/// <returns>A string containing the XXX-XXXX-XXX cosmetic value.</returns>
internal static string CalculateSiteSpecificID(string ppid) {
- Contract.Requires(ppid != null);
- ErrorUtilities.VerifyArgumentNotNull(ppid, "ppid");
- Contract.Ensures(Contract.Result<string>() != null && Contract.Result<string>().Length > 0);
+ Contract.Requires<ArgumentNullException>(ppid != null);
+ Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
int callSignChars = 10;
char[] charMap = "QL23456789ABCDEFGHJKMNPRSTUVWXYZ".ToCharArray();
@@ -246,8 +246,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="cs">the claimset which contains the claim</param>
/// <returns>a RSA claim</returns>
private static Claim GetUniqueRsaClaim(ClaimSet cs) {
- Contract.Requires(cs != null);
- ErrorUtilities.VerifyArgumentNotNull(cs, "cs");
+ Contract.Requires<ArgumentNullException>(cs != null);
Claim rsa = null;
@@ -269,11 +268,9 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="claimValue">the claim value to hash with.</param>
/// <returns>A base64 representation of the combined ID.</returns>
private static string ComputeCombinedId(RSA issuerKey, string claimValue) {
- Contract.Requires(issuerKey != null);
- Contract.Requires(claimValue != null);
+ Contract.Requires<ArgumentNullException>(issuerKey != null);
+ Contract.Requires<ArgumentNullException>(claimValue != null);
Contract.Ensures(Contract.Result<string>() != null);
- ErrorUtilities.VerifyArgumentNotNull(issuerKey, "issuerKey");
- ErrorUtilities.VerifyArgumentNotNull(claimValue, "claimValue");
int nameLength = Encoding.UTF8.GetByteCount(claimValue);
RSAParameters rsaParams = issuerKey.ExportParameters(false);
diff --git a/src/DotNetOpenAuth/InfoCard/TokenProcessingErrorEventArgs.cs b/src/DotNetOpenAuth/InfoCard/TokenProcessingErrorEventArgs.cs
index 1132ac0..1b4a62d 100644
--- a/src/DotNetOpenAuth/InfoCard/TokenProcessingErrorEventArgs.cs
+++ b/src/DotNetOpenAuth/InfoCard/TokenProcessingErrorEventArgs.cs
@@ -18,8 +18,8 @@ namespace DotNetOpenAuth.InfoCard {
/// <param name="tokenXml">The token XML.</param>
/// <param name="exception">The exception.</param>
internal TokenProcessingErrorEventArgs(string tokenXml, Exception exception) {
- Contract.Requires(tokenXml != null);
- Contract.Requires(exception != null);
+ Contract.Requires<ArgumentNullException>(tokenXml != null);
+ Contract.Requires<ArgumentNullException>(exception != null);
this.TokenXml = tokenXml;
this.Exception = exception;
}
@@ -38,6 +38,7 @@ namespace DotNetOpenAuth.InfoCard {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
protected void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/Logger.cs b/src/DotNetOpenAuth/Logger.cs
index 6015df5..ede8172 100644
--- a/src/DotNetOpenAuth/Logger.cs
+++ b/src/DotNetOpenAuth/Logger.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth {
using System;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using DotNetOpenAuth.Loggers;
using DotNetOpenAuth.Messaging;
@@ -131,7 +132,7 @@ namespace DotNetOpenAuth {
/// <param name="name">A name that will be included in the log file.</param>
/// <returns>The <see cref="ILog"/> instance created with the given name.</returns>
internal static ILog Create(string name) {
- ErrorUtilities.VerifyNonZeroLength(name, "name");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(name));
return InitializeFacade(name);
}
diff --git a/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs b/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs
index 7b00e34..ddfa88a 100644
--- a/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs
+++ b/src/DotNetOpenAuth/Messaging/Bindings/StandardExpirationBindingElement.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Messaging.Bindings {
using System;
+ using DotNetOpenAuth.Configuration;
/// <summary>
/// A message expiration enforcing binding element that supports messages
@@ -13,11 +14,6 @@ namespace DotNetOpenAuth.Messaging.Bindings {
/// </summary>
internal class StandardExpirationBindingElement : IChannelBindingElement {
/// <summary>
- /// The default maximum message age to use if the default constructor is called.
- /// </summary>
- internal static readonly TimeSpan DefaultMaximumMessageAge = TimeSpan.FromMinutes(13);
-
- /// <summary>
/// Initializes a new instance of the <see cref="StandardExpirationBindingElement"/> class.
/// </summary>
internal StandardExpirationBindingElement() {
diff --git a/src/DotNetOpenAuth/Messaging/Bindings/StandardReplayProtectionBindingElement.cs b/src/DotNetOpenAuth/Messaging/Bindings/StandardReplayProtectionBindingElement.cs
index c8d5873..0a7ddbd 100644
--- a/src/DotNetOpenAuth/Messaging/Bindings/StandardReplayProtectionBindingElement.cs
+++ b/src/DotNetOpenAuth/Messaging/Bindings/StandardReplayProtectionBindingElement.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Messaging.Bindings {
using System;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
/// <summary>
/// A binding element that checks/verifies a nonce message part.
@@ -41,7 +42,7 @@ namespace DotNetOpenAuth.Messaging.Bindings {
/// <param name="nonceStore">The store where nonces will be persisted and checked.</param>
/// <param name="allowEmptyNonces">A value indicating whether zero-length nonces will be allowed.</param>
internal StandardReplayProtectionBindingElement(INonceStore nonceStore, bool allowEmptyNonces) {
- ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
+ Contract.Requires<ArgumentNullException>(nonceStore != null);
this.nonceStore = nonceStore;
this.AllowZeroLengthNonce = allowEmptyNonces;
diff --git a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs
index 65cbba1..b37c93a 100644
--- a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs
@@ -15,6 +15,7 @@ namespace DotNetOpenAuth.Messaging {
/// <summary>
/// Cached details on the response from a direct web request to a remote party.
/// </summary>
+ [ContractVerification(true)]
[DebuggerDisplay("{Status} {ContentType.MediaType}, length: {ResponseStream.Length}")]
internal class CachedDirectWebResponse : IncomingWebResponse {
/// <summary>
@@ -36,6 +37,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="maximumBytesToRead">The maximum bytes to read.</param>
internal CachedDirectWebResponse(Uri requestUri, HttpWebResponse response, int maximumBytesToRead)
: base(requestUri, response) {
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+ Contract.Requires<ArgumentNullException>(response != null);
this.responseStream = CacheNetworkStreamAndClose(response, maximumBytesToRead);
// BUGBUG: if the response was exactly maximumBytesToRead, we'll incorrectly believe it was truncated.
@@ -54,8 +57,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="responseStream">The response stream.</param>
internal CachedDirectWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers, HttpStatusCode statusCode, string contentType, string contentEncoding, MemoryStream responseStream)
: base(requestUri, responseUri, headers, statusCode, contentType, contentEncoding) {
- ErrorUtilities.VerifyArgumentNotNull(responseStream, "responseStream");
-
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+ Contract.Requires<ArgumentNullException>(responseStream != null);
this.responseStream = responseStream;
}
@@ -149,7 +152,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="maximumBytesToRead">The maximum bytes to cache.</param>
/// <returns>The seekable Stream instance that contains a copy of what was returned in the HTTP response.</returns>
private static MemoryStream CacheNetworkStreamAndClose(HttpWebResponse response, int maximumBytesToRead) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
// Now read and cache the network stream
Stream networkStream = response.GetResponseStream();
diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs
index 2e0f1a8..718fac8 100644
--- a/src/DotNetOpenAuth/Messaging/Channel.cs
+++ b/src/DotNetOpenAuth/Messaging/Channel.cs
@@ -28,15 +28,15 @@ namespace DotNetOpenAuth.Messaging {
[ContractClass(typeof(ChannelContract))]
public abstract class Channel : IDisposable {
/// <summary>
- /// The content-type used on HTTP POST requests where the POST entity is a
- /// URL-encoded series of key=value pairs.
+ /// The encoding to use when writing out POST entity strings.
/// </summary>
- protected internal const string HttpFormUrlEncoded = "application/x-www-form-urlencoded";
+ internal static readonly Encoding PostEntityEncoding = new UTF8Encoding(false);
/// <summary>
- /// The encoding to use when writing out POST entity strings.
+ /// The content-type used on HTTP POST requests where the POST entity is a
+ /// URL-encoded series of key=value pairs.
/// </summary>
- private static readonly Encoding PostEntityEncoding = new UTF8Encoding(false);
+ protected internal const string HttpFormUrlEncoded = "application/x-www-form-urlencoded";
/// <summary>
/// The maximum allowable size for a 301 Redirect response before we send
@@ -112,8 +112,7 @@ namespace DotNetOpenAuth.Messaging {
/// </param>
/// <param name="bindingElements">The binding elements to use in sending and receiving messages.</param>
protected Channel(IMessageFactory messageTypeProvider, params IChannelBindingElement[] bindingElements) {
- Contract.Requires(messageTypeProvider != null);
- ErrorUtilities.VerifyArgumentNotNull(messageTypeProvider, "messageTypeProvider");
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
this.messageTypeProvider = messageTypeProvider;
this.WebRequestHandler = new StandardWebRequestHandler();
@@ -146,13 +145,11 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
internal MessageDescriptionCollection MessageDescriptions {
get {
- Contract.Ensures(Contract.Result<MessageDescriptionCollection>() != null);
return this.messageDescriptions;
}
set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.messageDescriptions = value;
}
}
@@ -180,7 +177,11 @@ namespace DotNetOpenAuth.Messaging {
/// Gets the binding elements used by this channel, in the order applied to incoming messages.
/// </summary>
protected internal ReadOnlyCollection<IChannelBindingElement> IncomingBindingElements {
- get { return this.incomingBindingElements.AsReadOnly(); }
+ get {
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<IChannelBindingElement>>().All(be => be.Channel != null));
+ Contract.Ensures(Contract.Result<ReadOnlyCollection<IChannelBindingElement>>().All(be => be != null));
+ return this.incomingBindingElements.AsReadOnly();
+ }
}
/// <summary>
@@ -209,8 +210,7 @@ namespace DotNetOpenAuth.Messaging {
}
set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.cachePolicy = value;
}
}
@@ -226,8 +226,8 @@ namespace DotNetOpenAuth.Messaging {
/// Requires an HttpContext.Current context.
/// </remarks>
public void Send(IProtocolMessage message) {
- Contract.Requires(HttpContext.Current != null);
- Contract.Requires(message != null);
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null, MessagingStrings.CurrentHttpContextRequired);
+ Contract.Requires<ArgumentNullException>(message != null);
this.PrepareResponse(message).Send();
}
@@ -238,9 +238,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="message">The one-way message to send</param>
/// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
public OutgoingWebResponse PrepareResponse(IProtocolMessage message) {
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
this.ProcessOutgoingMessage(message);
Logger.Channel.DebugFormat("Sending message: {0}", message.GetType().Name);
@@ -309,7 +308,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ProtocolException">Thrown when a request message of an unexpected type is received.</exception>
public bool TryReadFromRequest<TRequest>(HttpRequestInfo httpRequest, out TRequest request)
where TRequest : class, IProtocolMessage {
- Contract.Requires(httpRequest != null);
+ Contract.Requires<ArgumentNullException>(httpRequest != null);
Contract.Ensures(Contract.Result<bool>() == (Contract.ValueAtReturn<TRequest>(out request) != null));
IProtocolMessage untypedRequest = this.ReadFromRequest(httpRequest);
@@ -350,7 +349,7 @@ namespace DotNetOpenAuth.Messaging {
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "This returns and verifies the appropriate message type.")]
public TRequest ReadFromRequest<TRequest>(HttpRequestInfo httpRequest)
where TRequest : class, IProtocolMessage {
- Contract.Requires(httpRequest != null);
+ Contract.Requires<ArgumentNullException>(httpRequest != null);
TRequest request;
if (this.TryReadFromRequest<TRequest>(httpRequest, out request)) {
return request;
@@ -365,8 +364,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="httpRequest">The request to search for an embedded message.</param>
/// <returns>The deserialized message, if one is found. Null otherwise.</returns>
public IDirectedProtocolMessage ReadFromRequest(HttpRequestInfo httpRequest) {
- Contract.Requires(httpRequest != null);
- ErrorUtilities.VerifyArgumentNotNull(httpRequest, "httpRequest");
+ Contract.Requires<ArgumentNullException>(httpRequest != null);
if (Logger.Channel.IsInfoEnabled && httpRequest.UrlBeforeRewriting != null) {
Logger.Channel.InfoFormat("Scanning incoming request for messages: {0}", httpRequest.UrlBeforeRewriting.AbsoluteUri);
@@ -393,7 +391,7 @@ namespace DotNetOpenAuth.Messaging {
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "This returns and verifies the appropriate message type.")]
public TResponse Request<TResponse>(IDirectedProtocolMessage requestMessage)
where TResponse : class, IProtocolMessage {
- Contract.Requires(requestMessage != null);
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
Contract.Ensures(Contract.Result<TResponse>() != null);
IProtocolMessage response = this.Request(requestMessage);
@@ -412,8 +410,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The remote party's response. Guaranteed to never be null.</returns>
/// <exception cref="ProtocolException">Thrown if the response does not include a protocol message.</exception>
public IProtocolMessage Request(IDirectedProtocolMessage requestMessage) {
- Contract.Requires(requestMessage != null);
- ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage");
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
this.ProcessOutgoingMessage(requestMessage);
Logger.Channel.DebugFormat("Sending {0} request.", requestMessage.GetType().Name);
@@ -448,9 +445,14 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Costly call should not be a property.")]
protected internal virtual HttpRequestInfo GetRequestFromContext() {
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
Contract.Ensures(Contract.Result<HttpRequestInfo>() != null);
- ErrorUtilities.VerifyHttpContext();
+ Contract.Ensures(Contract.Result<HttpRequestInfo>().Url != null);
+ Contract.Ensures(Contract.Result<HttpRequestInfo>().RawUrl != null);
+ Contract.Ensures(Contract.Result<HttpRequestInfo>().UrlBeforeRewriting != null);
+ Contract.Assume(HttpContext.Current.Request.Url != null);
+ Contract.Assume(HttpContext.Current.Request.RawUrl != null);
return new HttpRequestInfo(HttpContext.Current.Request);
}
@@ -492,8 +494,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="message">The message about to be encoded and sent.</param>
protected virtual void OnSending(IProtocolMessage message) {
- Contract.Requires(message != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
var sending = this.Sending;
if (sending != null) {
@@ -508,8 +509,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The response to the web request.</returns>
/// <exception cref="ProtocolException">Thrown on network or protocol errors.</exception>
protected virtual IncomingWebResponse GetDirectResponse(HttpWebRequest webRequest) {
- Contract.Requires(webRequest != null);
- ErrorUtilities.VerifyArgumentNotNull(webRequest, "webRequest");
+ Contract.Requires<ArgumentNullException>(webRequest != null);
return this.WebRequestHandler.GetResponse(webRequest);
}
@@ -524,7 +524,9 @@ namespace DotNetOpenAuth.Messaging {
/// this method to eliminate all use of an HTTP transport.
/// </remarks>
protected virtual IProtocolMessage RequestCore(IDirectedProtocolMessage request) {
- Contract.Requires(request != null);
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(request.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
+
HttpWebRequest webRequest = this.CreateHttpRequest(request);
IDictionary<string, string> responseFields;
IDirectResponseProtocolMessage responseMessage;
@@ -535,6 +537,9 @@ namespace DotNetOpenAuth.Messaging {
}
responseFields = this.ReadFromResponseCore(response);
+ if (responseFields == null) {
+ return null;
+ }
responseMessage = this.MessageFactory.GetNewResponseMessage(request, responseFields);
if (responseMessage == null) {
@@ -564,8 +569,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The request to search for an embedded message.</param>
/// <returns>The deserialized message, if one is found. Null otherwise.</returns>
protected virtual IDirectedProtocolMessage ReadFromRequestCore(HttpRequestInfo request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
Logger.Channel.DebugFormat("Incoming HTTP request: {0} {1}", request.HttpMethod, request.UrlBeforeRewriting.AbsoluteUri);
@@ -586,8 +590,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="recipient">Information about where the message was directed. Null for direct response messages.</param>
/// <returns>The deserialized message, or null if no message could be recognized in the provided data.</returns>
protected virtual IProtocolMessage Receive(Dictionary<string, string> fields, MessageReceivingEndpoint recipient) {
- Contract.Requires(fields != null);
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
+ Contract.Requires<ArgumentNullException>(fields != null);
IProtocolMessage message = this.MessageFactory.GetNewRequestMessage(recipient, fields);
@@ -613,11 +616,13 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="message">The message to send.</param>
/// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
protected virtual OutgoingWebResponse PrepareIndirectResponse(IDirectedProtocolMessage message) {
- Contract.Requires(message != null && message.Recipient != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentException>(message.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Assert(message != null && message.Recipient != null);
var messageAccessor = this.MessageDescriptions.GetAccessor(message);
+ Contract.Assert(message != null && message.Recipient != null);
var fields = messageAccessor.Serialize();
// First try creating a 301 redirect, and fallback to a form POST
@@ -637,15 +642,13 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="message">The message to forward.</param>
/// <param name="fields">The pre-serialized fields from the message.</param>
/// <returns>The encoded HTTP response.</returns>
+ [Pure]
protected virtual OutgoingWebResponse Create301RedirectResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields) {
- Contract.Requires(message != null && message.Recipient != null);
- Contract.Requires(fields != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentException>(message.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
+ Contract.Requires<ArgumentNullException>(fields != null);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- ErrorUtilities.VerifyArgumentNamed(message.Recipient != null, "message", MessagingStrings.DirectedMessageMissingRecipient);
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
WebHeaderCollection headers = new WebHeaderCollection();
UriBuilder builder = new UriBuilder(message.Recipient);
MessagingUtilities.AppendQueryArgs(builder, fields);
@@ -669,12 +672,10 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="fields">The pre-serialized fields from the message.</param>
/// <returns>The encoded HTTP response.</returns>
protected virtual OutgoingWebResponse CreateFormPostResponse(IDirectedProtocolMessage message, IDictionary<string, string> fields) {
- Contract.Requires(message != null && message.Recipient != null);
- Contract.Requires(fields != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentException>(message.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
+ Contract.Requires<ArgumentNullException>(fields != null);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- ErrorUtilities.VerifyArgumentNamed(message.Recipient != null, "message", MessagingStrings.DirectedMessageMissingRecipient);
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.ContentType, "text/html");
@@ -719,7 +720,8 @@ namespace DotNetOpenAuth.Messaging {
/// is overridden and does not require this method.
/// </remarks>
protected virtual HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
- Contract.Requires(request != null);
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(request.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
Contract.Ensures(Contract.Result<HttpWebRequest>() != null);
throw new NotImplementedException();
}
@@ -744,8 +746,7 @@ namespace DotNetOpenAuth.Messaging {
/// except when sending ONE WAY request messages.
/// </remarks>
protected void ProcessOutgoingMessage(IProtocolMessage message) {
- Contract.Requires(message != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
Logger.Channel.DebugFormat("Preparing to send {0} ({1}) message.", message.GetType().Name, message.Version);
this.OnSending(message);
@@ -758,6 +759,7 @@ namespace DotNetOpenAuth.Messaging {
MessageProtections appliedProtection = MessageProtections.None;
foreach (IChannelBindingElement bindingElement in this.outgoingBindingElements) {
+ Contract.Assume(bindingElement.Channel != null);
MessageProtections? elementProtection = bindingElement.ProcessOutgoingMessage(message);
if (elementProtection.HasValue) {
Logger.Bindings.DebugFormat("Binding element {0} applied to message.", bindingElement.GetType().FullName);
@@ -803,8 +805,8 @@ namespace DotNetOpenAuth.Messaging {
/// This method satisfies OAuth 1.0 section 5.2, item #3.
/// </remarks>
protected virtual HttpWebRequest InitializeRequestAsGet(IDirectedProtocolMessage requestMessage) {
- Contract.Requires(requestMessage != null);
- ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage");
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
+ Contract.Requires<ArgumentException>(requestMessage.Recipient != null, MessagingStrings.DirectedMessageMissingRecipient);
var messageAccessor = this.MessageDescriptions.GetAccessor(requestMessage);
var fields = messageAccessor.Serialize();
@@ -827,9 +829,8 @@ namespace DotNetOpenAuth.Messaging {
/// This method satisfies OAuth 1.0 section 5.2, item #2 and OpenID 2.0 section 4.1.2.
/// </remarks>
protected virtual HttpWebRequest InitializeRequestAsPost(IDirectedProtocolMessage requestMessage) {
- Contract.Requires(requestMessage != null);
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
Contract.Ensures(Contract.Result<HttpWebRequest>() != null);
- ErrorUtilities.VerifyArgumentNotNull(requestMessage, "requestMessage");
var messageAccessor = this.MessageDescriptions.GetAccessor(requestMessage);
var fields = messageAccessor.Serialize();
@@ -843,6 +844,40 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Prepares to send a request to the Service Provider as the query string in a PUT request.
+ /// </summary>
+ /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
+ /// <returns>The web request ready to send.</returns>
+ /// <remarks>
+ /// This method is simply a standard HTTP PUT request with the message parts serialized to the query string.
+ /// </remarks>
+ protected virtual HttpWebRequest InitializeRequestAsPut(IDirectedProtocolMessage requestMessage) {
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
+ Contract.Ensures(Contract.Result<HttpWebRequest>() != null);
+
+ HttpWebRequest request = this.InitializeRequestAsGet(requestMessage);
+ request.Method = "PUT";
+ return request;
+ }
+
+ /// <summary>
+ /// Prepares to send a request to the Service Provider as the query string in a DELETE request.
+ /// </summary>
+ /// <param name="requestMessage">The message to be transmitted to the ServiceProvider.</param>
+ /// <returns>The web request ready to send.</returns>
+ /// <remarks>
+ /// This method is simply a standard HTTP DELETE request with the message parts serialized to the query string.
+ /// </remarks>
+ protected virtual HttpWebRequest InitializeRequestAsDelete(IDirectedProtocolMessage requestMessage) {
+ Contract.Requires<ArgumentNullException>(requestMessage != null);
+ Contract.Ensures(Contract.Result<HttpWebRequest>() != null);
+
+ HttpWebRequest request = this.InitializeRequestAsGet(requestMessage);
+ request.Method = "DELETE";
+ return request;
+ }
+
+ /// <summary>
/// Sends the given parameters in the entity stream of an HTTP request.
/// </summary>
/// <param name="httpRequest">The HTTP request.</param>
@@ -852,10 +887,8 @@ namespace DotNetOpenAuth.Messaging {
/// the request stream, but does not call <see cref="HttpWebRequest.GetResponse"/>.
/// </remarks>
protected void SendParametersInEntity(HttpWebRequest httpRequest, IDictionary<string, string> fields) {
- Contract.Requires(httpRequest != null);
- Contract.Requires(fields != null);
- ErrorUtilities.VerifyArgumentNotNull(httpRequest, "httpRequest");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
+ Contract.Requires<ArgumentNullException>(httpRequest != null);
+ Contract.Requires<ArgumentNullException>(fields != null);
httpRequest.ContentType = HttpFormUrlEncoded;
@@ -889,7 +922,7 @@ namespace DotNetOpenAuth.Messaging {
/// This can be due to tampering, replay attack or expiration, among other things.
/// </exception>
protected virtual void ProcessIncomingMessage(IProtocolMessage message) {
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
if (Logger.Channel.IsInfoEnabled) {
var messageAccessor = this.MessageDescriptions.GetAccessor(message);
@@ -902,7 +935,8 @@ namespace DotNetOpenAuth.Messaging {
}
MessageProtections appliedProtection = MessageProtections.None;
- foreach (IChannelBindingElement bindingElement in this.incomingBindingElements) {
+ foreach (IChannelBindingElement bindingElement in this.IncomingBindingElements) {
+ Contract.Assume(bindingElement.Channel != null); // CC bug: this.IncomingBindingElements ensures this... why must we assume it here?
MessageProtections? elementProtection = bindingElement.ProcessIncomingMessage(message);
if (elementProtection.HasValue) {
Logger.Bindings.DebugFormat("Binding element {0} applied to message.", bindingElement.GetType().FullName);
@@ -963,10 +997,8 @@ namespace DotNetOpenAuth.Messaging {
/// </remarks>
/// <exception cref="ArgumentException">Thrown if a binding element is new or missing in one of the ordered lists.</exception>
protected void CustomizeBindingElementOrder(IEnumerable<IChannelBindingElement> outgoingOrder, IEnumerable<IChannelBindingElement> incomingOrder) {
- Contract.Requires(outgoingOrder != null);
- Contract.Requires(incomingOrder != null);
- ErrorUtilities.VerifyArgumentNotNull(outgoingOrder, "outgoingOrder");
- ErrorUtilities.VerifyArgumentNotNull(incomingOrder, "incomingOrder");
+ Contract.Requires<ArgumentNullException>(outgoingOrder != null);
+ Contract.Requires<ArgumentNullException>(incomingOrder != null);
ErrorUtilities.VerifyArgument(this.IsBindingElementOrderValid(outgoingOrder), MessagingStrings.InvalidCustomBindingElementOrder);
ErrorUtilities.VerifyArgument(this.IsBindingElementOrderValid(incomingOrder), MessagingStrings.InvalidCustomBindingElementOrder);
@@ -976,6 +1008,18 @@ namespace DotNetOpenAuth.Messaging {
this.incomingBindingElements.AddRange(incomingOrder);
}
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(this.MessageDescriptions != null);
+ }
+#endif
+
/// <summary>
/// Ensures a consistent and secure set of binding elements and
/// sorts them as necessary for a valid sequence of operations.
@@ -984,14 +1028,12 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The properly ordered list of elements.</returns>
/// <exception cref="ProtocolException">Thrown when the binding elements are incomplete or inconsistent with each other.</exception>
private static IEnumerable<IChannelBindingElement> ValidateAndPrepareBindingElements(IEnumerable<IChannelBindingElement> elements) {
- Contract.Requires(elements == null || elements.All(e => e != null));
+ Contract.Requires<ArgumentException>(elements == null || elements.All(e => e != null));
Contract.Ensures(Contract.Result<IEnumerable<IChannelBindingElement>>() != null);
if (elements == null) {
return new IChannelBindingElement[0];
}
- ErrorUtilities.VerifyArgumentNamed(!elements.Contains(null), "elements", MessagingStrings.SequenceContainsNullElement);
-
// Filter the elements between the mere transforming ones and the protection ones.
var transformationElements = new List<IChannelBindingElement>(
elements.Where(element => element.Protection == MessageProtections.None));
@@ -1047,7 +1089,7 @@ namespace DotNetOpenAuth.Messaging {
/// Thrown when any required message part does not have a value.
/// </exception>
private void EnsureValidMessageParts(IProtocolMessage message) {
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
MessageDictionary dictionary = this.MessageDescriptions.GetAccessor(message);
MessageDescription description = this.MessageDescriptions.Get(message);
description.EnsureMessagePartsPassBasicValidation(dictionary);
@@ -1063,8 +1105,7 @@ namespace DotNetOpenAuth.Messaging {
/// </returns>
[Pure]
private bool IsBindingElementOrderValid(IEnumerable<IChannelBindingElement> order) {
- Contract.Requires(order != null);
- ErrorUtilities.VerifyArgumentNotNull(order, "order");
+ Contract.Requires<ArgumentNullException>(order != null);
// Check that the same number of binding elements are defined.
if (order.Count() != this.OutgoingBindingElements.Count) {
diff --git a/src/DotNetOpenAuth/Messaging/ChannelContract.cs b/src/DotNetOpenAuth/Messaging/ChannelContract.cs
index 551d7c4..9b85d28 100644
--- a/src/DotNetOpenAuth/Messaging/ChannelContract.cs
+++ b/src/DotNetOpenAuth/Messaging/ChannelContract.cs
@@ -30,7 +30,7 @@ namespace DotNetOpenAuth.Messaging {
/// </returns>
/// <exception cref="ProtocolException">Thrown when the response is not valid.</exception>
protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) {
- Contract.Requires(response != null);
+ Contract.Requires<ArgumentNullException>(response != null);
throw new NotImplementedException();
}
@@ -46,7 +46,7 @@ namespace DotNetOpenAuth.Messaging {
/// This method implements spec V1.0 section 5.3.
/// </remarks>
protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- Contract.Requires(response != null);
+ Contract.Requires<ArgumentNullException>(response != null);
Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/Messaging/ChannelEventArgs.cs b/src/DotNetOpenAuth/Messaging/ChannelEventArgs.cs
index 29310dc..1e71bf2 100644
--- a/src/DotNetOpenAuth/Messaging/ChannelEventArgs.cs
+++ b/src/DotNetOpenAuth/Messaging/ChannelEventArgs.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Messaging {
using System;
+ using System.Diagnostics.Contracts;
/// <summary>
/// The data packet sent with Channel events.
@@ -16,7 +17,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="message">The message behind the fired event..</param>
internal ChannelEventArgs(IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
this.Message = message;
}
diff --git a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
index 0a60b19..b560fdc 100644
--- a/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/ErrorUtilities.cs
@@ -26,7 +26,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>The newly constructed (unthrown) exception.</returns>
[Pure]
internal static Exception Wrap(Exception inner, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Assume(errorMessage != null);
return new ProtocolException(string.Format(CultureInfo.CurrentCulture, errorMessage, args), inner);
}
@@ -73,7 +73,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="InternalErrorException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyInternal(bool condition, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<InternalErrorException>(!condition);
Contract.Assume(errorMessage != null);
@@ -122,7 +122,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="NotSupportedException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifySupported(bool condition, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<NotSupportedException>(!condition);
Contract.Assume(errorMessage != null);
@@ -140,7 +140,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="InvalidOperationException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyOperation(bool condition, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<InvalidOperationException>(!condition);
Contract.Assume(errorMessage != null);
@@ -160,7 +160,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="InfoCard.InformationCardException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyInfoCard(bool condition, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<InfoCard.InformationCardException>(!condition);
Contract.Assume(errorMessage != null);
@@ -179,7 +179,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="HostErrorException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyHost(bool condition, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<ProtocolException>(!condition);
Contract.Assume(errorMessage != null);
@@ -198,7 +198,8 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ProtocolException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyProtocol(bool condition, IProtocolMessage faultedMessage, string errorMessage, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
+ Contract.Requires<ArgumentNullException>(faultedMessage != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<ProtocolException>(!condition);
Contract.Assume(errorMessage != null);
@@ -216,7 +217,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ProtocolException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyProtocol(bool condition, string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<ProtocolException>(!condition);
Contract.Assume(message != null);
@@ -248,7 +249,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ProtocolException">Always thrown.</exception>
[Pure]
internal static Exception ThrowProtocol(string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Assume(message != null);
VerifyProtocol(false, message, args);
@@ -264,7 +265,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>Nothing. It's just here so the caller can throw this method for C# compilation check.</returns>
[Pure]
internal static Exception ThrowFormat(string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Assume(message != null);
throw new FormatException(string.Format(CultureInfo.CurrentCulture, message, args));
}
@@ -278,7 +279,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="FormatException">Thrown when <paramref name="condition"/> is <c>false</c>.</exception>
[Pure]
internal static void VerifyFormat(bool condition, string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<FormatException>(!condition);
Contract.Assume(message != null);
@@ -296,7 +297,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyArgument(bool condition, string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<ArgumentException>(!condition);
Contract.Assume(message != null);
@@ -308,38 +309,6 @@ namespace DotNetOpenAuth.Messaging {
/// <summary>
/// Verifies something about the argument supplied to a method.
/// </summary>
- /// <param name="condition">The condition that must evaluate to true to avoid an exception.</param>
- /// <param name="parameterName">Name of the parameter.</param>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
- [Pure]
- internal static void VerifyArgumentInRange(bool condition, string parameterName) {
- Contract.Requires(condition);
- if (!condition) {
- throw new ArgumentOutOfRangeException(parameterName);
- }
- }
-
- /// <summary>
- /// Verifies something about the argument supplied to a method.
- /// </summary>
- /// <param name="condition">The condition that must evaluate to true to avoid an exception.</param>
- /// <param name="parameterName">Name of the parameter.</param>
- /// <param name="message">The unformatted message.</param>
- /// <param name="args">The string formatting arguments.</param>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
- [Pure]
- internal static void VerifyArgumentInRange(bool condition, string parameterName, string message, params object[] args) {
- Contract.Requires(condition);
- Contract.Requires(args != null);
- Contract.Assume(message != null);
- if (!condition) {
- throw new ArgumentOutOfRangeException(parameterName, string.Format(CultureInfo.CurrentCulture, message, args));
- }
- }
-
- /// <summary>
- /// Verifies something about the argument supplied to a method.
- /// </summary>
/// <param name="parameterName">Name of the parameter.</param>
/// <param name="message">The message to use in the exception if the condition is false.</param>
/// <param name="args">The string formatting arguments, if any.</param>
@@ -347,7 +316,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static Exception ThrowArgumentNamed(string parameterName, string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Assume(message != null);
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, message, args), parameterName);
}
@@ -362,7 +331,7 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentException">Thrown if <paramref name="condition"/> evaluates to <c>false</c>.</exception>
[Pure]
internal static void VerifyArgumentNamed(bool condition, string parameterName, string message, params object[] args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(condition);
Contract.EnsuresOnThrow<ArgumentException>(!condition);
Contract.Assume(message != null);
@@ -379,7 +348,8 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
[Pure]
internal static void VerifyArgumentNotNull(object value, string paramName) {
- Contract.Requires(value != null);
+ Contract.Ensures(value != null);
+ Contract.EnsuresOnThrow<ArgumentNullException>(value == null);
if (value == null) {
throw new ArgumentNullException(paramName);
}
@@ -394,7 +364,8 @@ namespace DotNetOpenAuth.Messaging {
/// <exception cref="ArgumentException">Thrown if <paramref name="value"/> has zero length.</exception>
[Pure]
internal static void VerifyNonZeroLength(string value, string paramName) {
- Contract.Requires((value != null && value.Length > 0) || !string.IsNullOrEmpty(value));
+ Contract.Ensures((value != null && value.Length > 0) && !string.IsNullOrEmpty(value));
+ Contract.EnsuresOnThrow<ArgumentException>(value == null || value.Length == 0);
VerifyArgumentNotNull(value, paramName);
if (value.Length == 0) {
throw new ArgumentException(MessagingStrings.UnexpectedEmptyString, paramName);
@@ -409,9 +380,7 @@ namespace DotNetOpenAuth.Messaging {
internal static void VerifyHttpContext() {
Contract.Ensures(HttpContext.Current != null);
Contract.Ensures(HttpContext.Current.Request != null);
-
- ErrorUtilities.VerifyOperation(HttpContext.Current != null, MessagingStrings.HttpContextRequired);
- ErrorUtilities.VerifyOperation(HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
+ ErrorUtilities.VerifyOperation(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
}
}
}
diff --git a/src/DotNetOpenAuth/Messaging/HttpDeliveryMethods.cs b/src/DotNetOpenAuth/Messaging/HttpDeliveryMethods.cs
index cbbe28e..17c8f7a 100644
--- a/src/DotNetOpenAuth/Messaging/HttpDeliveryMethods.cs
+++ b/src/DotNetOpenAuth/Messaging/HttpDeliveryMethods.cs
@@ -34,5 +34,20 @@ namespace DotNetOpenAuth.Messaging {
/// Added to the URLs in the query part (as defined by [RFC3986] (Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,†.) section 3).
/// </summary>
GetRequest = 0x4,
+
+ /// <summary>
+ /// Added to the URLs in the query part (as defined by [RFC3986] (Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,†.) section 3).
+ /// </summary>
+ PutRequest = 0x8,
+
+ /// <summary>
+ /// Added to the URLs in the query part (as defined by [RFC3986] (Berners-Lee, T., “Uniform Resource Identifiers (URI): Generic Syntax,†.) section 3).
+ /// </summary>
+ DeleteRequest = 0x10,
+
+ /// <summary>
+ /// The flags that control HTTP verbs.
+ /// </summary>
+ HttpVerbMask = PostRequest | GetRequest | PutRequest | DeleteRequest,
}
}
diff --git a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
index 0693926..16b4546 100644
--- a/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
+++ b/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs
@@ -50,8 +50,15 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="request">The ASP.NET structure to copy from.</param>
public HttpRequestInfo(HttpRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Ensures(this.HttpMethod == request.HttpMethod);
+ Contract.Ensures(this.Url == request.Url);
+ Contract.Ensures(this.RawUrl == request.RawUrl);
+ Contract.Ensures(this.UrlBeforeRewriting != null);
+ Contract.Ensures(this.Headers != null);
+ Contract.Ensures(this.InputStream == request.InputStream);
+ Contract.Ensures(this.form == request.Form);
+ Contract.Ensures(this.queryString == request.QueryString);
this.HttpMethod = request.HttpMethod;
this.Url = request.Url;
@@ -78,14 +85,10 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="headers">Headers in the HTTP request.</param>
/// <param name="inputStream">The entity stream, if any. (POST requests typically have these). Use <c>null</c> for GET requests.</param>
public HttpRequestInfo(string httpMethod, Uri requestUrl, string rawUrl, WebHeaderCollection headers, Stream inputStream) {
- Contract.Requires(!string.IsNullOrEmpty(httpMethod));
- Contract.Requires(requestUrl != null);
- Contract.Requires(rawUrl != null);
- Contract.Requires(headers != null);
- ErrorUtilities.VerifyNonZeroLength(httpMethod, "httpMethod");
- ErrorUtilities.VerifyArgumentNotNull(requestUrl, "requestUrl");
- ErrorUtilities.VerifyArgumentNotNull(rawUrl, "rawUrl");
- ErrorUtilities.VerifyArgumentNotNull(headers, "headers");
+ Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(httpMethod));
+ Contract.Requires<ArgumentNullException>(requestUrl != null);
+ Contract.Requires<ArgumentNullException>(rawUrl != null);
+ Contract.Requires<ArgumentNullException>(headers != null);
this.HttpMethod = httpMethod;
this.Url = requestUrl;
@@ -100,8 +103,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="listenerRequest">Details on the incoming HTTP request.</param>
public HttpRequestInfo(HttpListenerRequest listenerRequest) {
- Contract.Requires(listenerRequest != null);
- ErrorUtilities.VerifyArgumentNotNull(listenerRequest, "listenerRequest");
+ Contract.Requires<ArgumentNullException>(listenerRequest != null);
this.HttpMethod = listenerRequest.HttpMethod;
this.Url = listenerRequest.Url;
@@ -121,10 +123,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The WCF incoming request structure to get the HTTP information from.</param>
/// <param name="requestUri">The URI of the service endpoint.</param>
public HttpRequestInfo(HttpRequestMessageProperty request, Uri requestUri) {
- Contract.Requires(request != null);
- Contract.Requires(requestUri != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(requestUri != null);
this.HttpMethod = request.Method;
this.Headers = request.Headers;
@@ -137,6 +137,9 @@ namespace DotNetOpenAuth.Messaging {
/// Initializes a new instance of the <see cref="HttpRequestInfo"/> class.
/// </summary>
internal HttpRequestInfo() {
+ Contract.Ensures(this.HttpMethod == "GET");
+ Contract.Ensures(this.Headers != null);
+
this.HttpMethod = "GET";
this.Headers = new WebHeaderCollection();
}
@@ -146,8 +149,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="request">The HttpWebRequest (that was never used) to copy from.</param>
internal HttpRequestInfo(WebRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
this.HttpMethod = request.Method;
this.Url = request.RequestUri;
@@ -164,11 +166,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="httpMethod">The HTTP method that the incoming request came in on, whether or not <paramref name="message"/> is null.</param>
internal HttpRequestInfo(IDirectedProtocolMessage message, HttpDeliveryMethods httpMethod) {
this.message = message;
- if ((httpMethod & HttpDeliveryMethods.GetRequest) != 0) {
- this.HttpMethod = "GET";
- } else if ((httpMethod & HttpDeliveryMethods.PostRequest) != 0) {
- this.HttpMethod = "POST";
- }
+ this.HttpMethod = MessagingUtilities.GetHttpVerb(httpMethod);
}
/// <summary>
@@ -307,14 +305,24 @@ namespace DotNetOpenAuth.Messaging {
return query;
}
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ }
+#endif
+
/// <summary>
/// Gets the public facing URL for the given incoming HTTP request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>The URI that the outside world used to create this request.</returns>
private static Uri GetPublicFacingUrl(HttpRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
// Due to URL rewriting, cloud computing (i.e. Azure)
// and web farms, etc., we have to be VERY careful about what
@@ -328,7 +336,7 @@ namespace DotNetOpenAuth.Messaging {
UriBuilder publicRequestUri = new UriBuilder(request.Url);
Uri hostAndPort = new Uri(request.Url.Scheme + Uri.SchemeDelimiter + request.ServerVariables["HTTP_HOST"]);
publicRequestUri.Host = hostAndPort.Host;
- publicRequestUri.Port = hostAndPort.Port;
+ publicRequestUri.Port = hostAndPort.Port; // CC missing Uri.Port contract that's on UriBuilder.Port
if (request.ServerVariables["HTTP_X_FORWARDED_PROTO"] != null) {
publicRequestUri.Scheme = request.ServerVariables["HTTP_X_FORWARDED_PROTO"];
}
@@ -352,7 +360,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="url">A full URL.</param>
/// <returns>A raw URL that might have come in on the HTTP verb.</returns>
private static string MakeUpRawUrlFromUrl(Uri url) {
- Contract.Requires(url != null);
+ Contract.Requires<ArgumentNullException>(url != null);
return url.AbsolutePath + url.Query + url.Fragment;
}
@@ -362,7 +370,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="pairs">The collection a HTTP headers.</param>
/// <returns>A new collection of the given headers.</returns>
private static WebHeaderCollection GetHeaderCollection(NameValueCollection pairs) {
- Debug.Assert(pairs != null, "pairs == null");
+ Contract.Requires<ArgumentNullException>(pairs != null);
WebHeaderCollection headers = new WebHeaderCollection();
foreach (string key in pairs) {
diff --git a/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs b/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs
index 5ae07c3..db5dd24 100644
--- a/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs
+++ b/src/DotNetOpenAuth/Messaging/IChannelBindingElement.cs
@@ -107,8 +107,8 @@ namespace DotNetOpenAuth.Messaging {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
- Contract.Requires(((IChannelBindingElement)this).Channel != null);
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<InvalidOperationException>(((IChannelBindingElement)this).Channel != null);
throw new NotImplementedException();
}
@@ -130,8 +130,8 @@ namespace DotNetOpenAuth.Messaging {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
MessageProtections? IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message) {
- Contract.Requires(((IChannelBindingElement)this).Channel != null);
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<InvalidOperationException>(((IChannelBindingElement)this).Channel != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs
index 380e2d5..af03ba9 100644
--- a/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs
+++ b/src/DotNetOpenAuth/Messaging/IDirectWebRequestHandler.cs
@@ -5,7 +5,9 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Messaging {
+ using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
using DotNetOpenAuth.Messaging;
@@ -16,6 +18,7 @@ namespace DotNetOpenAuth.Messaging {
/// <remarks>
/// Implementations of this interface must be thread safe.
/// </remarks>
+ [ContractClass(typeof(IDirectWebRequestHandlerContract))]
public interface IDirectWebRequestHandler {
/// <summary>
/// Determines whether this instance can support the specified options.
@@ -24,6 +27,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>
/// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>.
/// </returns>
+ [Pure]
bool CanSupport(DirectWebRequestOptions options);
/// <summary>
@@ -98,4 +102,117 @@ namespace DotNetOpenAuth.Messaging {
/// </remarks>
IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IDirectWebRequestHandler"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IDirectWebRequestHandler))]
+ internal abstract class IDirectWebRequestHandlerContract : IDirectWebRequestHandler {
+ #region IDirectWebRequestHandler Members
+
+ /// <summary>
+ /// Determines whether this instance can support the specified options.
+ /// </summary>
+ /// <param name="options">The set of options that might be given in a subsequent web request.</param>
+ /// <returns>
+ /// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>.
+ /// </returns>
+ bool IDirectWebRequestHandler.CanSupport(DirectWebRequestOptions options) {
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity.
+ /// </summary>
+ /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param>
+ /// <returns>
+ /// The stream the caller should write out the entity data to.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown for any network error.</exception>
+ /// <remarks>
+ /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/>
+ /// and any other appropriate properties <i>before</i> calling this method.
+ /// Callers <i>must</i> close and dispose of the request stream when they are done
+ /// writing to it to avoid taking up the connection too long and causing long waits on
+ /// subsequent requests.</para>
+ /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a
+ /// <see cref="ProtocolException"/> to abstract away the transport and provide
+ /// a single exception type for hosts to catch.</para>
+ /// </remarks>
+ Stream IDirectWebRequestHandler.GetRequestStream(HttpWebRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Prepares an <see cref="HttpWebRequest"/> that contains an POST entity for sending the entity.
+ /// </summary>
+ /// <param name="request">The <see cref="HttpWebRequest"/> that should contain the entity.</param>
+ /// <param name="options">The options to apply to this web request.</param>
+ /// <returns>
+ /// The stream the caller should write out the entity data to.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown for any network error.</exception>
+ /// <remarks>
+ /// <para>The caller should have set the <see cref="HttpWebRequest.ContentLength"/>
+ /// and any other appropriate properties <i>before</i> calling this method.
+ /// Callers <i>must</i> close and dispose of the request stream when they are done
+ /// writing to it to avoid taking up the connection too long and causing long waits on
+ /// subsequent requests.</para>
+ /// <para>Implementations should catch <see cref="WebException"/> and wrap it in a
+ /// <see cref="ProtocolException"/> to abstract away the transport and provide
+ /// a single exception type for hosts to catch.</para>
+ /// </remarks>
+ Stream IDirectWebRequestHandler.GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<NotSupportedException>(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported);
+ ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name));
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Processes an <see cref="HttpWebRequest"/> and converts the
+ /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance.
+ /// </summary>
+ /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param>
+ /// <returns>
+ /// An instance of <see cref="IncomingWebResponse"/> describing the response.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown for any network error.</exception>
+ /// <remarks>
+ /// Implementations should catch <see cref="WebException"/> and wrap it in a
+ /// <see cref="ProtocolException"/> to abstract away the transport and provide
+ /// a single exception type for hosts to catch. The <see cref="WebException.Response"/>
+ /// value, if set, shoud be Closed before throwing.
+ /// </remarks>
+ IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Processes an <see cref="HttpWebRequest"/> and converts the
+ /// <see cref="HttpWebResponse"/> to a <see cref="IncomingWebResponse"/> instance.
+ /// </summary>
+ /// <param name="request">The <see cref="HttpWebRequest"/> to handle.</param>
+ /// <param name="options">The options to apply to this web request.</param>
+ /// <returns>
+ /// An instance of <see cref="IncomingWebResponse"/> describing the response.
+ /// </returns>
+ /// <exception cref="ProtocolException">Thrown for any network error.</exception>
+ /// <remarks>
+ /// Implementations should catch <see cref="WebException"/> and wrap it in a
+ /// <see cref="ProtocolException"/> to abstract away the transport and provide
+ /// a single exception type for hosts to catch. The <see cref="WebException.Response"/>
+ /// value, if set, shoud be Closed before throwing.
+ /// </remarks>
+ IncomingWebResponse IDirectWebRequestHandler.GetResponse(HttpWebRequest request, DirectWebRequestOptions options) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<NotSupportedException>(((IDirectWebRequestHandler)this).CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported);
+ ////ErrorUtilities.VerifySupported(((IDirectWebRequestHandler)this).CanSupport(options), string.Format(MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name));
+ throw new System.NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/Messaging/IMessageFactory.cs b/src/DotNetOpenAuth/Messaging/IMessageFactory.cs
index 9ce5f89..3718545 100644
--- a/src/DotNetOpenAuth/Messaging/IMessageFactory.cs
+++ b/src/DotNetOpenAuth/Messaging/IMessageFactory.cs
@@ -7,11 +7,13 @@
namespace DotNetOpenAuth.Messaging {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
/// <summary>
/// A tool to analyze an incoming message to figure out what concrete class
/// is designed to deserialize it and instantiates that class.
/// </summary>
+ [ContractClass(typeof(IMessageFactoryContract))]
public interface IMessageFactory {
/// <summary>
/// Analyzes an incoming request message payload to discover what kind of
@@ -39,4 +41,47 @@ namespace DotNetOpenAuth.Messaging {
/// </returns>
IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IMessageFactory"/> interface.
+ /// </summary>
+ [ContractClassFor(typeof(IMessageFactory))]
+ internal class IMessageFactoryContract : IMessageFactory {
+ #region IMessageFactory Members
+
+ /// <summary>
+ /// Analyzes an incoming request message payload to discover what kind of
+ /// message is embedded in it and returns the type, or null if no match is found.
+ /// </summary>
+ /// <param name="recipient">The intended or actual recipient of the request message.</param>
+ /// <param name="fields">The name/value pairs that make up the message payload.</param>
+ /// <returns>
+ /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
+ /// deserialize to. Null if the request isn't recognized as a valid protocol message.
+ /// </returns>
+ IDirectedProtocolMessage IMessageFactory.GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
+ Contract.Requires<ArgumentNullException>(recipient != null);
+ Contract.Requires<ArgumentNullException>(fields != null);
+
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Analyzes an incoming request message payload to discover what kind of
+ /// message is embedded in it and returns the type, or null if no match is found.
+ /// </summary>
+ /// <param name="request">The message that was sent as a request that resulted in the response.</param>
+ /// <param name="fields">The name/value pairs that make up the message payload.</param>
+ /// <returns>
+ /// A newly instantiated <see cref="IProtocolMessage"/>-derived object that this message can
+ /// deserialize to. Null if the request isn't recognized as a valid protocol message.
+ /// </returns>
+ IDirectResponseProtocolMessage IMessageFactory.GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(fields != null);
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs b/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
index e471a06..70b1032 100644
--- a/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/IncomingWebResponse.cs
@@ -6,8 +6,8 @@
namespace DotNetOpenAuth.Messaging {
using System;
- using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Net;
@@ -17,6 +17,8 @@ namespace DotNetOpenAuth.Messaging {
/// <summary>
/// Details on the incoming response from a direct web request to a remote party.
/// </summary>
+ [ContractVerification(true)]
+ [ContractClass(typeof(IncomingWebResponseContract))]
public abstract class IncomingWebResponse : IDisposable {
/// <summary>
/// The encoding to use in reading a response that does not declare its own content encoding.
@@ -37,8 +39,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="requestUri">The original request URI.</param>
/// <param name="response">The response to initialize from. The network stream is used by this class directly.</param>
protected IncomingWebResponse(Uri requestUri, HttpWebResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+ Contract.Requires<ArgumentNullException>(response != null);
this.RequestUri = requestUri;
if (!string.IsNullOrEmpty(response.ContentType)) {
@@ -64,7 +66,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="contentType">Type of the content.</param>
/// <param name="contentEncoding">The content encoding.</param>
protected IncomingWebResponse(Uri requestUri, Uri responseUri, WebHeaderCollection headers, HttpStatusCode statusCode, string contentType, string contentEncoding) {
- ErrorUtilities.VerifyArgumentNotNull(requestUri, "requestUri");
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+
this.RequestUri = requestUri;
this.Status = statusCode;
if (!string.IsNullOrEmpty(contentType)) {
diff --git a/src/DotNetOpenAuth/Messaging/IncomingWebResponseContract.cs b/src/DotNetOpenAuth/Messaging/IncomingWebResponseContract.cs
new file mode 100644
index 0000000..e9c1941
--- /dev/null
+++ b/src/DotNetOpenAuth/Messaging/IncomingWebResponseContract.cs
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------
+// <copyright file="IncomingWebResponseContract.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Messaging {
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+
+ /// <summary>
+ /// Code contract for the <see cref="IncomingWebResponse"/> class.
+ /// </summary>
+ [ContractClassFor(typeof(IncomingWebResponse))]
+ internal abstract class IncomingWebResponseContract : IncomingWebResponse {
+ /// <summary>
+ /// Gets the body of the HTTP response.
+ /// </summary>
+ /// <value></value>
+ public override Stream ResponseStream {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Creates a text reader for the response stream.
+ /// </summary>
+ /// <returns>
+ /// The text reader, initialized for the proper encoding.
+ /// </returns>
+ public override StreamReader GetResponseReader() {
+ Contract.Ensures(Contract.Result<StreamReader>() != null);
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets an offline snapshot version of this instance.
+ /// </summary>
+ /// <param name="maximumBytesToCache">The maximum bytes from the response stream to cache.</param>
+ /// <returns>A snapshot version of this instance.</returns>
+ /// <remarks>
+ /// If this instance is a <see cref="NetworkDirectWebResponse"/> creating a snapshot
+ /// will automatically close and dispose of the underlying response stream.
+ /// If this instance is a <see cref="CachedDirectWebResponse"/>, the result will
+ /// be the self same instance.
+ /// </remarks>
+ internal override CachedDirectWebResponse GetSnapshot(int maximumBytesToCache) {
+ Contract.Requires<ArgumentOutOfRangeException>(maximumBytesToCache >= 0);
+ Contract.Requires<InvalidOperationException>(this.RequestUri != null);
+ Contract.Ensures(Contract.Result<CachedDirectWebResponse>() != null);
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs b/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs
index 16786e3..5555f9c 100644
--- a/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs
+++ b/src/DotNetOpenAuth/Messaging/KeyedCollectionDelegate.cs
@@ -27,8 +27,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="getKeyForItemDelegate">The delegate that gets the key for a given item.</param>
internal KeyedCollectionDelegate(Func<TItem, TKey> getKeyForItemDelegate) {
- Contract.Requires(getKeyForItemDelegate != null);
- ErrorUtilities.VerifyArgumentNotNull(getKeyForItemDelegate, "getKeyForItemDelegate");
+ Contract.Requires<ArgumentNullException>(getKeyForItemDelegate != null);
this.getKeyForItemDelegate = getKeyForItemDelegate;
}
@@ -39,7 +38,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="item">The element from which to extract the key.</param>
/// <returns>The key for the specified element.</returns>
protected override TKey GetKeyForItem(TItem item) {
- ErrorUtilities.VerifyArgumentNotNull(item, "item");
+ ErrorUtilities.VerifyArgumentNotNull(item, "item"); // null items not supported.
return this.getKeyForItemDelegate(item);
}
}
diff --git a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
index 79a1107..c7ac581 100644
--- a/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
+++ b/src/DotNetOpenAuth/Messaging/MessageReceivingEndpoint.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Messaging {
using System;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
/// <summary>
/// An immutable description of a URL that receives messages.
@@ -28,9 +29,9 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="location">The URL of this endpoint.</param>
/// <param name="method">The HTTP method(s) allowed.</param>
public MessageReceivingEndpoint(Uri location, HttpDeliveryMethods method) {
- ErrorUtilities.VerifyArgumentNotNull(location, "location");
- ErrorUtilities.VerifyArgumentInRange(method != HttpDeliveryMethods.None, "method");
- ErrorUtilities.VerifyArgumentInRange((method & (HttpDeliveryMethods.PostRequest | HttpDeliveryMethods.GetRequest)) != 0, "method", MessagingStrings.GetOrPostFlagsRequired);
+ Contract.Requires<ArgumentNullException>(location != null);
+ Contract.Requires<ArgumentOutOfRangeException>(method != HttpDeliveryMethods.None, "method");
+ Contract.Requires<ArgumentOutOfRangeException>((method & HttpDeliveryMethods.HttpVerbMask) != 0, MessagingStrings.GetOrPostFlagsRequired);
this.Location = location;
this.AllowedMethods = method;
diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
index 1aafc11..a21559e 100644
--- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
+++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs
@@ -33,17 +33,9 @@ namespace DotNetOpenAuth.Messaging {
/// that will be serialized and deserialized using this class.</param>
[ContractVerification(false)] // bugs/limitations in CC static analysis
private MessageSerializer(Type messageType) {
- Contract.Requires(messageType != null);
- Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType));
+ Contract.Requires<ArgumentNullException>(messageType != null);
+ Contract.Requires<ArgumentException>(typeof(IMessage).IsAssignableFrom(messageType));
Contract.Ensures(this.messageType != null);
-
- ErrorUtilities.VerifyArgumentNamed(
- typeof(IMessage).IsAssignableFrom(messageType),
- "messageType",
- MessagingStrings.UnexpectedType,
- typeof(IMessage).FullName,
- messageType.FullName);
-
this.messageType = messageType;
}
@@ -54,9 +46,8 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>A message serializer for the given message type.</returns>
[ContractVerification(false)] // bugs/limitations in CC static analysis
internal static MessageSerializer Get(Type messageType) {
- Contract.Requires(messageType != null);
- Contract.Requires(typeof(IMessage).IsAssignableFrom(messageType));
- ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
+ Contract.Requires<ArgumentNullException>(messageType != null);
+ Contract.Requires<ArgumentException>(typeof(IMessage).IsAssignableFrom(messageType));
return new MessageSerializer(messageType);
}
@@ -66,11 +57,11 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="messageDictionary">The message to be serialized.</param>
/// <returns>The dictionary of values to send for the message.</returns>
+ [Pure]
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Parallel design with Deserialize method.")]
internal IDictionary<string, string> Serialize(MessageDictionary messageDictionary) {
- Contract.Requires(messageDictionary != null);
+ Contract.Requires<ArgumentNullException>(messageDictionary != null);
Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null);
- ErrorUtilities.VerifyArgumentNotNull(messageDictionary, "messageDictionary");
// Rather than hand back the whole message dictionary (which
// includes keys with blank values), create a new dictionary
@@ -100,10 +91,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="messageDictionary">The message to deserialize into.</param>
/// <exception cref="ProtocolException">Thrown when protocol rules are broken by the incoming message.</exception>
internal void Deserialize(IDictionary<string, string> fields, MessageDictionary messageDictionary) {
- Contract.Requires(fields != null);
- Contract.Requires(messageDictionary != null);
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
- ErrorUtilities.VerifyArgumentNotNull(messageDictionary, "messageDictionary");
+ Contract.Requires<ArgumentNullException>(fields != null);
+ Contract.Requires<ArgumentNullException>(messageDictionary != null);
var messageDescription = messageDictionary.Description;
@@ -124,6 +113,7 @@ namespace DotNetOpenAuth.Messaging {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
protected void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
index 13e83e1..f2c9add 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.Designer.cs
@@ -115,7 +115,7 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
- /// Looks up a localized string similar to The given set of options ({0}) is not supported by {1}..
+ /// Looks up a localized string similar to The given set of options is not supported by this web request handler..
/// </summary>
internal static string DirectWebRequestOptionsNotSupported {
get {
@@ -304,6 +304,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to A non-empty string was expected..
+ /// </summary>
+ internal static string NonEmptyStringExpected {
+ get {
+ return ResourceManager.GetString("NonEmptyStringExpected", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to A message response is already queued for sending in the response stream..
/// </summary>
internal static string QueuedMessageResponseAlreadyExists {
@@ -394,6 +403,15 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Looks up a localized string similar to The stream must have a known length..
+ /// </summary>
+ internal static string StreamMustHaveKnownLength {
+ get {
+ return ResourceManager.GetString("StreamMustHaveKnownLength", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to The stream&apos;s CanRead property returned false..
/// </summary>
internal static string StreamUnreadable {
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
index 4bc92a7..3d4e317 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.resx
@@ -136,7 +136,7 @@
<value>The directed message's Recipient property must not be null.</value>
</data>
<data name="DirectWebRequestOptionsNotSupported" xml:space="preserve">
- <value>The given set of options ({0}) is not supported by {1}.</value>
+ <value>The given set of options is not supported by this web request handler.</value>
</data>
<data name="ErrorDeserializingMessage" xml:space="preserve">
<value>Error while deserializing message {0}.</value>
@@ -291,4 +291,10 @@
<data name="UnsupportedHttpVerb" xml:space="preserve">
<value>The HTTP verb '{0}' is unrecognized and unsupported.</value>
</data>
+ <data name="NonEmptyStringExpected" xml:space="preserve">
+ <value>A non-empty string was expected.</value>
+ </data>
+ <data name="StreamMustHaveKnownLength" xml:space="preserve">
+ <value>The stream must have a known length.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Messaging/MessagingStrings.sr.resx b/src/DotNetOpenAuth/Messaging/MessagingStrings.sr.resx
new file mode 100644
index 0000000..5b7b716
--- /dev/null
+++ b/src/DotNetOpenAuth/Messaging/MessagingStrings.sr.resx
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="ArgumentPropertyMissing" xml:space="preserve">
+ <value>Svojstvo {0}.{1} argumenta je neophodno, ali je ono prazno ili nepostojeće.</value>
+ </data>
+ <data name="CurrentHttpContextRequired" xml:space="preserve">
+ <value>HttpContext.Current je nepostojeći. Mora postojati ASP.NET zahtev u procesu da bi ova operacija bila uspešna.</value>
+ </data>
+ <data name="DataContractMissingFromMessageType" xml:space="preserve">
+ <value>DataContractSerializer se ne može inicijalizovati na tipu poruke {0}. Da li nedostaje [DataContract] atribut?</value>
+ </data>
+ <data name="DataContractMissingNamespace" xml:space="preserve">
+ <value>DataContractSerializer se ne može inicijalizovati na tipu poruke {0} jer svojstvo DataContractAttribute.Namespace property nije podešeno.</value>
+ </data>
+ <data name="DerivedTypeNotExpected" xml:space="preserve">
+ <value>Instanca tipa {0} je bila oÄekivana, a primljena je neoÄekivana izvedena instanca tipa {1}.</value>
+ </data>
+ <data name="DirectedMessageMissingRecipient" xml:space="preserve">
+ <value>Svojstvo Recipient usmerene poruke ne sme biti nepostojeće.</value>
+ </data>
+ <data name="DirectWebRequestOptionsNotSupported" xml:space="preserve">
+ <value>Dati set opcija ({0}) nije podržan od strane {1}.</value>
+ </data>
+ <data name="ErrorDeserializingMessage" xml:space="preserve">
+ <value>Greška prilikom deserijalizacije poruke {0}.</value>
+ </data>
+ <data name="ErrorInRequestReplyMessage" xml:space="preserve">
+ <value>Greška se desila tokom slanja usmerene poruke ili tokom primanja odgovora.</value>
+ </data>
+ <data name="ExceptionNotConstructedForTransit" xml:space="preserve">
+ <value>Ovaj izuzetak nije napravljen sa poÄetnom porukom koja ga je izazvala.</value>
+ </data>
+ <data name="ExpectedMessageNotReceived" xml:space="preserve">
+ <value>OÄekivana je poruka {0} a primljena poruka nije prepoznata.</value>
+ </data>
+ <data name="ExpiredMessage" xml:space="preserve">
+ <value>Poruka istiÄe u {0} a sada je {1}.</value>
+ </data>
+ <data name="GetOrPostFlagsRequired" xml:space="preserve">
+ <value>Bar jedan od GET ili POST flegova mora biti prisutan.</value>
+ </data>
+ <data name="HttpContextRequired" xml:space="preserve">
+ <value>Ovaj metod zahteva tekući HttpContext. Kao alternativa, koristite preklopljeni metod koji dozvoljava da se prosledi informacija bez HttpContext-a.</value>
+ </data>
+ <data name="IndirectMessagesMustImplementIDirectedProtocolMessage" xml:space="preserve">
+ <value>Poruke koje ukazuju na indirektni transport moraju implementirati {0} interfejs.</value>
+ </data>
+ <data name="InsecureWebRequestWithSslRequired" xml:space="preserve">
+ <value>Nebezbedan web zahtev za '{0}' prekinut zbog bezbednosnih zahteva koji zahtevaju HTTPS.</value>
+ </data>
+ <data name="InsufficientMessageProtection" xml:space="preserve">
+ <value>Poruka {0} je zahtevala zaštite {{{1}}} ali prenosni kanal nije mogao primeniti {{{2}}}.</value>
+ </data>
+ <data name="InvalidCustomBindingElementOrder" xml:space="preserve">
+ <value>Redosled prilagođenih vezujućih elemenata je neispravan.</value>
+ </data>
+ <data name="InvalidMessageParts" xml:space="preserve">
+ <value>Neki deo ili delovi poruke imaju nevalidne vrednosti: {0}</value>
+ </data>
+ <data name="InvalidNonceReceived" xml:space="preserve">
+ <value>Primljena poruka imala je neispravan ili nedostajući jedinstveni identifikator.</value>
+ </data>
+ <data name="KeyAlreadyExists" xml:space="preserve">
+ <value>Element sa istom vrednošću kljuÄa je već dodat.</value>
+ </data>
+ <data name="MessageNotExtensible" xml:space="preserve">
+ <value>Poruka {0} ne podržava ekstenzije.</value>
+ </data>
+ <data name="MessagePartEncoderWrongType" xml:space="preserve">
+ <value>Vrednost za {0}.{1} Älana {1} je trebala da bude izvedena od {2} ali je izvedena od {3}.</value>
+ </data>
+ <data name="MessagePartReadFailure" xml:space="preserve">
+ <value>GreÅ¡ka prilikom Äitanja poruke '{0}' parametar '{1}' sa vrednošću '{2}'.</value>
+ </data>
+ <data name="MessagePartValueBase64DecodingFault" xml:space="preserve">
+ <value>Parametar poruke '{0}' sa vrednošću '{1}' nije se base64-dekodovao.</value>
+ </data>
+ <data name="MessagePartWriteFailure" xml:space="preserve">
+ <value>Greška prilikom pripremanja poruke '{0}' parametra '{1}' za slanje.</value>
+ </data>
+ <data name="QueuedMessageResponseAlreadyExists" xml:space="preserve">
+ <value>Poruka-odgovor je već u redu za slanje u stream-u za odgovore.</value>
+ </data>
+ <data name="ReplayAttackDetected" xml:space="preserve">
+ <value>Ova poruka je već obrađena. Ovo može ukazivati na replay napad u toku.</value>
+ </data>
+ <data name="ReplayProtectionNotSupported" xml:space="preserve">
+ <value>Ovaj kanal ne podržava replay zaštitu.</value>
+ </data>
+ <data name="RequiredNonEmptyParameterWasEmpty" xml:space="preserve">
+ <value>Sledeći zahtevani parametri koji ne smeju biti prazni su bili prazni u {0} poruke: {1}</value>
+ </data>
+ <data name="RequiredParametersMissing" xml:space="preserve">
+ <value>Sledeći zahtevani parametri nedostaju u {0} poruke: {1}</value>
+ </data>
+ <data name="RequiredProtectionMissing" xml:space="preserve">
+ <value>Povezujući element koji nudi {0} zaštitu zahteva drugu zaštitu koja nije ponuđena.</value>
+ </data>
+ <data name="SequenceContainsNoElements" xml:space="preserve">
+ <value>Lista je prazna.</value>
+ </data>
+ <data name="SequenceContainsNullElement" xml:space="preserve">
+ <value>Lista sadrži prazan (null) element.</value>
+ </data>
+ <data name="SignatureInvalid" xml:space="preserve">
+ <value>Potpis poruke je neispravan.</value>
+ </data>
+ <data name="SigningNotSupported" xml:space="preserve">
+ <value>Ovaj kanal ne podržava potpisivanje poruka. Da bi podržao potpisivanje poruka, izvedeni tip Channel mora preklopiti Sign i IsSignatureValid metode.</value>
+ </data>
+ <data name="StreamUnreadable" xml:space="preserve">
+ <value>Svojstvo stream-a CanRead je vratilo false.</value>
+ </data>
+ <data name="StreamUnwritable" xml:space="preserve">
+ <value>Svojstvo stream-a CanWrite je vratilo false.</value>
+ </data>
+ <data name="TooManyBindingsOfferingSameProtection" xml:space="preserve">
+ <value>OÄekivano je da najviÅ¡e 1 povezujući element primeni zaÅ¡titu {0}, ali je viÅ¡e njih primenjeno.</value>
+ </data>
+ <data name="TooManyRedirects" xml:space="preserve">
+ <value>Maksimalno dozvoljeni broj redirekcija je prekoraÄen u toku zahtevanja '{0}'.</value>
+ </data>
+ <data name="UnexpectedEmptyArray" xml:space="preserve">
+ <value>Niz ne sme biti prazan.</value>
+ </data>
+ <data name="UnexpectedEmptyString" xml:space="preserve">
+ <value>Prazan string nije dozvoljen.</value>
+ </data>
+ <data name="UnexpectedMessagePartValue" xml:space="preserve">
+ <value>Parametar poruke '{0}' ima neoÄekivanu '{1}'.</value>
+ </data>
+ <data name="UnexpectedMessagePartValueForConstant" xml:space="preserve">
+ <value>OÄekivano je da od poruke {0} parametar '{1}' ima vrednost '{2}' ali je imao vrednost '{3}'.</value>
+ </data>
+ <data name="UnexpectedMessageReceived" xml:space="preserve">
+ <value>OÄekivana je poruka {0} ali je umesto nje primljena {1}.</value>
+ </data>
+ <data name="UnexpectedMessageReceivedOfMany" xml:space="preserve">
+ <value>Poruka neoÄekivanog tipa je primljena.</value>
+ </data>
+ <data name="UnexpectedNullKey" xml:space="preserve">
+ <value>null kljuÄ je ukljuÄen a nije dozvoljen.</value>
+ </data>
+ <data name="UnexpectedNullOrEmptyKey" xml:space="preserve">
+ <value>null ili prazan kljuÄ je ukljuÄen a nije dozvoljen.</value>
+ </data>
+ <data name="UnexpectedNullValue" xml:space="preserve">
+ <value>null vrednost je ukljuÄena za kljuÄ '{0}' a nije dozvoljena.</value>
+ </data>
+ <data name="UnexpectedType" xml:space="preserve">
+ <value>Tip {0} ili izvedeni tip je oÄekivan, a dat je {1}.</value>
+ </data>
+ <data name="UnrecognizedEnumValue" xml:space="preserve">
+ <value>{0} svojstvo ima nepoznatu vrednost {1}.</value>
+ </data>
+ <data name="UnsafeWebRequestDetected" xml:space="preserve">
+ <value>URL '{0}' je rangiran kao nebezbedan i ne može se zahtevati na ovaj naÄin.</value>
+ </data>
+ <data name="UntrustedRedirectsOnPOSTNotSupported" xml:space="preserve">
+ <value>Redirekcije na POST zahteve usmerene ka serverima kojima se ne veruje nisu podržane.</value>
+ </data>
+ <data name="WebRequestFailed" xml:space="preserve">
+ <value>Web zahtev za '{0}' nije uspeo.</value>
+ </data>
+ <data name="ExceptionUndeliverable" xml:space="preserve">
+ <value>Ovaj izuzetak mora se kreirati zajedno sa primaocem koji će primiti poruku o grešci ili sa instancom poruke direktnog zahteva na koju će ovaj izuzetak odgovoriti.</value>
+ </data>
+ <data name="UnsupportedHttpVerbForMessageType" xml:space="preserve">
+ <value>'{0}' poruka ne može biti primljeno sa HTTP glagolom '{1}'.</value>
+ </data>
+ <data name="UnexpectedHttpStatusCode" xml:space="preserve">
+ <value>OÄekivano je da direktan odgovor koristi HTTP status kod {0} a korišćen je {1}.</value>
+ </data>
+ <data name="UnsupportedHttpVerb" xml:space="preserve">
+ <value>HTTP glagol '{0}' je neprepoznat i nije podržan.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
index 7d89b4e..2ab628a 100644
--- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
+++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs
@@ -10,6 +10,7 @@ namespace DotNetOpenAuth.Messaging {
using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
+ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
@@ -90,8 +91,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="response">The response to send to the uesr agent.</param>
/// <returns>The <see cref="ActionResult"/> instance to be returned by the Controller's action method.</returns>
public static ActionResult AsActionResult(this OutgoingWebResponse response) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
return new OutgoingWebResponseActionResult(response);
}
@@ -103,7 +103,7 @@ namespace DotNetOpenAuth.Messaging {
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "The Uri merging requires use of a string value.")]
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Expensive call should not be a property.")]
public static Uri GetRequestUrlFromContext() {
- ErrorUtilities.VerifyHttpContext();
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
HttpContext context = HttpContext.Current;
// We use Request.Url for the full path to the server, and modify it
@@ -123,8 +123,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="prefix">The prefix for parameters to remove. A period is NOT automatically appended.</param>
/// <returns>Either a new Uri with the parameters removed if there were any to remove, or the same Uri instance if no parameters needed to be removed.</returns>
public static Uri StripQueryArgumentsWithPrefix(this Uri uri, string prefix) {
- ErrorUtilities.VerifyArgumentNotNull(uri, "uri");
- ErrorUtilities.VerifyNonZeroLength(prefix, "prefix");
+ Contract.Requires<ArgumentNullException>(uri != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(prefix));
NameValueCollection queryArgs = HttpUtility.ParseQueryString(uri.Query);
var matchingKeys = queryArgs.Keys.OfType<string>().Where(key => key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)).ToList();
@@ -141,6 +141,54 @@ namespace DotNetOpenAuth.Messaging {
}
/// <summary>
+ /// Sends an multipart HTTP POST request (useful for posting files).
+ /// </summary>
+ /// <param name="request">The HTTP request.</param>
+ /// <param name="requestHandler">The request handler.</param>
+ /// <param name="parts">The parts to include in the POST entity.</param>
+ /// <returns>The HTTP response.</returns>
+ public static IncomingWebResponse PostMultipart(this HttpWebRequest request, IDirectWebRequestHandler requestHandler, IEnumerable<MultipartPostPart> parts) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(requestHandler != null);
+ Contract.Requires<ArgumentNullException>(parts != null);
+
+ string boundary = Guid.NewGuid().ToString();
+ string partLeadingBoundary = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}\r\n", boundary);
+ string finalTrailingBoundary = string.Format(CultureInfo.InvariantCulture, "\r\n--{0}--\r\n", boundary);
+
+ request.Method = "POST";
+ request.ContentType = "multipart/form-data; boundary=" + boundary;
+ request.ContentLength = parts.Sum(p => partLeadingBoundary.Length + p.Length) + finalTrailingBoundary.Length;
+
+ // Setting the content-encoding to "utf-8" causes Google to reply
+ // with a 415 UnsupportedMediaType. But adding it doesn't buy us
+ // anything specific, so we disable it until we know how to get it right.
+ ////request.Headers[HttpRequestHeader.ContentEncoding] = Channel.PostEntityEncoding.WebName;
+
+ var requestStream = requestHandler.GetRequestStream(request);
+ try {
+ StreamWriter writer = new StreamWriter(requestStream, Channel.PostEntityEncoding);
+ foreach (var part in parts) {
+ writer.Write(partLeadingBoundary);
+ part.Serialize(writer);
+ part.Dispose();
+ }
+
+ writer.Write(finalTrailingBoundary);
+ writer.Flush();
+ } finally {
+ // We need to be sure to close the request stream...
+ // unless it is a MemoryStream, which is a clue that we're in
+ // a mock stream situation and closing it would preclude reading it later.
+ if (!(requestStream is MemoryStream)) {
+ requestStream.Dispose();
+ }
+ }
+
+ return requestHandler.GetResponse(request);
+ }
+
+ /// <summary>
/// Assembles a message comprised of the message on a given exception and all inner exceptions.
/// </summary>
/// <param name="exception">The exception.</param>
@@ -206,8 +254,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="allowableCharacters">The allowable characters.</param>
/// <returns>A random string.</returns>
internal static string GetRandomString(int length, string allowableCharacters) {
- Contract.Requires(length >= 0);
- Contract.Requires(allowableCharacters != null && allowableCharacters.Length >= 2);
+ Contract.Requires<ArgumentOutOfRangeException>(length >= 0);
+ Contract.Requires<ArgumentException>(allowableCharacters != null && allowableCharacters.Length >= 2);
char[] randomString = new char[length];
for (int i = 0; i < length; i++) {
@@ -225,8 +273,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="headers">The headers to add.</param>
/// <param name="response">The <see cref="HttpResponse"/> instance to set the appropriate values to.</param>
internal static void ApplyHeadersToResponse(WebHeaderCollection headers, HttpResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(headers, "headers");
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(headers != null);
+ Contract.Requires<ArgumentNullException>(response != null);
foreach (string headerName in headers) {
switch (headerName) {
@@ -250,8 +298,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="headers">The headers to add.</param>
/// <param name="response">The <see cref="HttpListenerResponse"/> instance to set the appropriate values to.</param>
internal static void ApplyHeadersToResponse(WebHeaderCollection headers, HttpListenerResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(headers, "headers");
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(headers != null);
+ Contract.Requires<ArgumentNullException>(response != null);
foreach (string headerName in headers) {
switch (headerName) {
@@ -293,10 +341,10 @@ namespace DotNetOpenAuth.Messaging {
/// The positions are NOT reset after copying is complete.
/// </remarks>
internal static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) {
- ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
- ErrorUtilities.VerifyArgumentNotNull(copyTo, "copyTo");
- ErrorUtilities.VerifyArgument(copyFrom.CanRead, MessagingStrings.StreamUnreadable);
- ErrorUtilities.VerifyArgument(copyTo.CanWrite, MessagingStrings.StreamUnwritable, "copyTo");
+ Contract.Requires<ArgumentNullException>(copyFrom != null);
+ Contract.Requires<ArgumentNullException>(copyTo != null);
+ Contract.Requires<ArgumentException>(copyFrom.CanRead, MessagingStrings.StreamUnreadable);
+ Contract.Requires<ArgumentException>(copyTo.CanWrite, MessagingStrings.StreamUnwritable);
byte[] buffer = new byte[1024];
int readBytes;
@@ -317,7 +365,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="copyFrom">The stream to copy bytes from.</param>
/// <returns>A seekable stream with the same contents as the original.</returns>
internal static Stream CreateSnapshot(this Stream copyFrom) {
- ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
+ Contract.Requires<ArgumentNullException>(copyFrom != null);
MemoryStream copyTo = new MemoryStream(copyFrom.CanSeek ? (int)copyFrom.Length : 4 * 1024);
copyFrom.CopyTo(copyTo);
@@ -331,7 +379,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The request to clone.</param>
/// <returns>The newly created instance.</returns>
internal static HttpWebRequest Clone(this HttpWebRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
return Clone(request, request.RequestUri);
}
@@ -342,8 +390,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="newRequestUri">The new recipient of the request.</param>
/// <returns>The newly created instance.</returns>
internal static HttpWebRequest Clone(this HttpWebRequest request, Uri newRequestUri) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(newRequestUri, "newRequestUri");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(newRequestUri != null);
var newRequest = (HttpWebRequest)WebRequest.Create(newRequestUri);
@@ -409,8 +457,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="second">The second array in the comparison. May not be null.</param>
/// <returns>True if the arrays equal; false otherwise.</returns>
internal static bool AreEquivalent<T>(T[] first, T[] second) {
- ErrorUtilities.VerifyArgumentNotNull(first, "first");
- ErrorUtilities.VerifyArgumentNotNull(second, "second");
+ Contract.Requires<ArgumentNullException>(first != null);
+ Contract.Requires<ArgumentNullException>(second != null);
if (first.Length != second.Length) {
return false;
}
@@ -510,9 +558,9 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="args">The dictionary of key/values to read from.</param>
/// <returns>The formulated querystring style string.</returns>
internal static string CreateQueryString(IEnumerable<KeyValuePair<string, string>> args) {
- Contract.Requires(args != null);
+ Contract.Requires<ArgumentNullException>(args != null);
Contract.Ensures(Contract.Result<string>() != null);
- ErrorUtilities.VerifyArgumentNotNull(args, "args");
+
if (args.Count() == 0) {
return string.Empty;
}
@@ -546,7 +594,7 @@ namespace DotNetOpenAuth.Messaging {
/// in the query string, the existing ones are <i>not</i> replaced.
/// </remarks>
internal static void AppendQueryArgs(this UriBuilder builder, IEnumerable<KeyValuePair<string, string>> args) {
- ErrorUtilities.VerifyArgumentNotNull(builder, "builder");
+ Contract.Requires<ArgumentNullException>(builder != null);
if (args != null && args.Count() > 0) {
StringBuilder sb = new StringBuilder(50 + (args.Count() * 10));
@@ -570,7 +618,7 @@ namespace DotNetOpenAuth.Messaging {
/// If null, <paramref name="builder"/> is not changed.
/// </param>
internal static void AppendAndReplaceQueryArgs(this UriBuilder builder, IEnumerable<KeyValuePair<string, string>> args) {
- ErrorUtilities.VerifyArgumentNotNull(builder, "builder");
+ Contract.Requires<ArgumentNullException>(builder != null);
if (args != null && args.Count() > 0) {
NameValueCollection aggregatedArgs = HttpUtility.ParseQueryString(builder.Query);
@@ -588,7 +636,47 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The request to get recipient information from.</param>
/// <returns>The recipient.</returns>
internal static MessageReceivingEndpoint GetRecipient(this HttpRequestInfo request) {
- return new MessageReceivingEndpoint(request.UrlBeforeRewriting, request.HttpMethod == "GET" ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest);
+ return new MessageReceivingEndpoint(request.UrlBeforeRewriting, GetHttpDeliveryMethod(request.HttpMethod));
+ }
+
+ /// <summary>
+ /// Gets the <see cref="HttpDeliveryMethods"/> enum value for a given HTTP verb.
+ /// </summary>
+ /// <param name="httpVerb">The HTTP verb.</param>
+ /// <returns>A <see cref="HttpDeliveryMethods"/> enum value that is within the <see cref="HttpDeliveryMethods.HttpVerbMask"/>.</returns>
+ internal static HttpDeliveryMethods GetHttpDeliveryMethod(string httpVerb) {
+ if (httpVerb == "GET") {
+ return HttpDeliveryMethods.GetRequest;
+ } else if (httpVerb == "POST") {
+ return HttpDeliveryMethods.PostRequest;
+ } else if (httpVerb == "PUT") {
+ return HttpDeliveryMethods.PutRequest;
+ } else if (httpVerb == "DELETE") {
+ return HttpDeliveryMethods.DeleteRequest;
+ } else {
+ throw ErrorUtilities.ThrowArgumentNamed("httpVerb", MessagingStrings.UnsupportedHttpVerb, httpVerb);
+ }
+ }
+
+ /// <summary>
+ /// Gets the HTTP verb to use for a given <see cref="HttpDeliveryMethods"/> enum value.
+ /// </summary>
+ /// <param name="httpMethod">The HTTP method.</param>
+ /// <returns>An HTTP verb, such as GET, POST, PUT, or DELETE.</returns>
+ internal static string GetHttpVerb(HttpDeliveryMethods httpMethod) {
+ if ((httpMethod & HttpDeliveryMethods.GetRequest) != 0) {
+ return "GET";
+ } else if ((httpMethod & HttpDeliveryMethods.PostRequest) != 0) {
+ return "POST";
+ } else if ((httpMethod & HttpDeliveryMethods.PutRequest) != 0) {
+ return "PUT";
+ } else if ((httpMethod & HttpDeliveryMethods.DeleteRequest) != 0) {
+ return "DELETE";
+ } else if ((httpMethod & HttpDeliveryMethods.AuthorizationHeaderRequest) != 0) {
+ return "GET"; // if AuthorizationHeaderRequest is specified without an explicit HTTP verb, assume GET.
+ } else {
+ throw ErrorUtilities.ThrowArgumentNamed("httpMethod", MessagingStrings.UnsupportedHttpVerb, httpMethod);
+ }
}
/// <summary>
@@ -597,7 +685,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="messageDictionary">The message to copy the extra data into.</param>
/// <param name="extraParameters">The extra data to copy into the message. May be null to do nothing.</param>
internal static void AddExtraParameters(this MessageDictionary messageDictionary, IDictionary<string, string> extraParameters) {
- ErrorUtilities.VerifyArgumentNotNull(messageDictionary, "messageAccessor");
+ Contract.Requires<ArgumentNullException>(messageDictionary != null);
if (extraParameters != null) {
foreach (var pair in extraParameters) {
@@ -664,6 +752,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="comparer">A comparison function to compare keys.</param>
/// <returns>An System.Linq.IOrderedEnumerable&lt;TElement&gt; whose elements are sorted according to a key.</returns>
internal static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Comparison<TKey> comparer) {
+ Contract.Ensures(Contract.Result<IOrderedEnumerable<TSource>>() != null);
return System.Linq.Enumerable.OrderBy<TSource, TKey>(source, keySelector, new ComparisonHelper<TKey>(comparer));
}
@@ -680,7 +769,7 @@ namespace DotNetOpenAuth.Messaging {
/// if their <see cref="IDirectedProtocolMessage.Recipient"/> property is non-null.
/// </remarks>
internal static bool IsRequest(this IDirectedProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return message.Recipient != null;
}
@@ -698,7 +787,7 @@ namespace DotNetOpenAuth.Messaging {
/// <see cref="IDirectResponseProtocolMessage.OriginatingRequest"/> property is non-null.
/// </remarks>
internal static bool IsDirectResponse(this IDirectResponseProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return message.OriginatingRequest != null;
}
@@ -707,15 +796,16 @@ namespace DotNetOpenAuth.Messaging {
/// on the user agent when assigned to a variable.
/// </summary>
/// <param name="namesAndValues">The untrusted names and untrusted values to inject into the JSON object.</param>
+ /// <param name="valuesPreEncoded">if set to <c>true</c> the values will NOT be escaped as if it were a pure string.</param>
/// <returns>The Javascript JSON object as a string.</returns>
- internal static string CreateJsonObject(IEnumerable<KeyValuePair<string, string>> namesAndValues) {
+ internal static string CreateJsonObject(IEnumerable<KeyValuePair<string, string>> namesAndValues, bool valuesPreEncoded) {
StringBuilder builder = new StringBuilder();
builder.Append("{ ");
foreach (var pair in namesAndValues) {
builder.Append(MessagingUtilities.GetSafeJavascriptValue(pair.Key));
builder.Append(": ");
- builder.Append(MessagingUtilities.GetSafeJavascriptValue(pair.Value));
+ builder.Append(valuesPreEncoded ? pair.Value : MessagingUtilities.GetSafeJavascriptValue(pair.Value));
builder.Append(",");
}
diff --git a/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs
new file mode 100644
index 0000000..9cbf11b
--- /dev/null
+++ b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs
@@ -0,0 +1,202 @@
+//-----------------------------------------------------------------------
+// <copyright file="MultipartPostPart.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Messaging {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Net;
+ using System.Text;
+
+ /// <summary>
+ /// Represents a single part in a HTTP multipart POST request.
+ /// </summary>
+ public class MultipartPostPart : IDisposable {
+ /// <summary>
+ /// The "Content-Disposition" string.
+ /// </summary>
+ private const string ContentDispositionHeader = "Content-Disposition";
+
+ /// <summary>
+ /// The two-character \r\n newline character sequence to use.
+ /// </summary>
+ private const string NewLine = "\r\n";
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MultipartPostPart"/> class.
+ /// </summary>
+ /// <param name="contentDisposition">The content disposition of the part.</param>
+ public MultipartPostPart(string contentDisposition) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(contentDisposition));
+
+ this.ContentDisposition = contentDisposition;
+ this.ContentAttributes = new Dictionary<string, string>();
+ this.PartHeaders = new WebHeaderCollection();
+ }
+
+ /// <summary>
+ /// Gets the content disposition.
+ /// </summary>
+ /// <value>The content disposition.</value>
+ public string ContentDisposition { get; private set; }
+
+ /// <summary>
+ /// Gets the key=value attributes that appear on the same line as the Content-Disposition.
+ /// </summary>
+ /// <value>The content attributes.</value>
+ public IDictionary<string, string> ContentAttributes { get; private set; }
+
+ /// <summary>
+ /// Gets the headers that appear on subsequent lines after the Content-Disposition.
+ /// </summary>
+ public WebHeaderCollection PartHeaders { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the content of the part.
+ /// </summary>
+ public Stream Content { get; set; }
+
+ /// <summary>
+ /// Gets the length of this entire part.
+ /// </summary>
+ /// <remarks>Useful for calculating the ContentLength HTTP header to send before actually serializing the content.</remarks>
+ public long Length {
+ get {
+ ErrorUtilities.VerifyOperation(this.Content != null && this.Content.Length >= 0, MessagingStrings.StreamMustHaveKnownLength);
+
+ long length = 0;
+ length += ContentDispositionHeader.Length;
+ length += ": ".Length;
+ length += this.ContentDisposition.Length;
+ foreach (var pair in this.ContentAttributes) {
+ length += "; ".Length + pair.Key.Length + "=\"".Length + pair.Value.Length + "\"".Length;
+ }
+
+ length += NewLine.Length;
+ foreach (string headerName in this.PartHeaders) {
+ length += headerName.Length;
+ length += ": ".Length;
+ length += this.PartHeaders[headerName].Length;
+ length += NewLine.Length;
+ }
+
+ length += NewLine.Length;
+ length += this.Content.Length;
+
+ return length;
+ }
+ }
+
+ /// <summary>
+ /// Creates a part that represents a simple form field.
+ /// </summary>
+ /// <param name="name">The name of the form field.</param>
+ /// <param name="value">The value.</param>
+ /// <returns>The constructed part.</returns>
+ public static MultipartPostPart CreateFormPart(string name, string value) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name));
+ Contract.Requires<ArgumentException>(value != null);
+
+ var part = new MultipartPostPart("form-data");
+ part.ContentAttributes["name"] = name;
+ part.Content = new MemoryStream(Encoding.UTF8.GetBytes(value));
+ return part;
+ }
+
+ /// <summary>
+ /// Creates a part that represents a file attachment.
+ /// </summary>
+ /// <param name="name">The name of the form field.</param>
+ /// <param name="filePath">The path to the file to send.</param>
+ /// <param name="contentType">Type of the content in HTTP Content-Type format.</param>
+ /// <returns>The constructed part.</returns>
+ public static MultipartPostPart CreateFormFilePart(string name, string filePath, string contentType) {
+ string fileName = Path.GetFileName(filePath);
+ return CreateFormFilePart(name, fileName, contentType, File.OpenRead(filePath));
+ }
+
+ /// <summary>
+ /// Creates a part that represents a file attachment.
+ /// </summary>
+ /// <param name="name">The name of the form field.</param>
+ /// <param name="fileName">Name of the file as the server should see it.</param>
+ /// <param name="contentType">Type of the content in HTTP Content-Type format.</param>
+ /// <param name="content">The content of the file.</param>
+ /// <returns>The constructed part.</returns>
+ public static MultipartPostPart CreateFormFilePart(string name, string fileName, string contentType, Stream content) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name));
+ Contract.Requires<ArgumentException>(fileName != null);
+ Contract.Requires<ArgumentException>(contentType != null);
+ Contract.Requires<ArgumentException>(content != null);
+
+ var part = new MultipartPostPart("form-data");
+ part.ContentAttributes["name"] = name;
+ part.ContentAttributes["filename"] = fileName;
+ part.PartHeaders[HttpRequestHeader.ContentType] = contentType;
+ if (!contentType.StartsWith("text/", StringComparison.Ordinal)) {
+ part.PartHeaders["Content-Transfer-Encoding"] = "binary";
+ }
+ part.Content = content;
+ return part;
+ }
+
+ /// <summary>
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ /// </summary>
+ public void Dispose() {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Serializes the part to a stream.
+ /// </summary>
+ /// <param name="streamWriter">The stream writer.</param>
+ internal void Serialize(StreamWriter streamWriter) {
+ // VERY IMPORTANT: any changes at all made to this must be kept in sync with the
+ // Length property which calculates exactly how many bytes this method will write.
+ streamWriter.NewLine = NewLine;
+ streamWriter.Write("{0}: {1}", ContentDispositionHeader, this.ContentDisposition);
+ foreach (var pair in this.ContentAttributes) {
+ streamWriter.Write("; {0}=\"{1}\"", pair.Key, pair.Value);
+ }
+
+ streamWriter.WriteLine();
+ foreach (string headerName in this.PartHeaders) {
+ streamWriter.WriteLine("{0}: {1}", headerName, this.PartHeaders[headerName]);
+ }
+
+ streamWriter.WriteLine();
+ streamWriter.Flush();
+ this.Content.CopyTo(streamWriter.BaseStream);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing) {
+ if (disposing) {
+ this.Content.Dispose();
+ }
+ }
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void Invariant() {
+ Contract.Invariant(!string.IsNullOrEmpty(this.ContentDisposition));
+ Contract.Invariant(this.PartHeaders != null);
+ Contract.Invariant(this.ContentAttributes != null);
+ }
+#endif
+ }
+}
diff --git a/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs
index 2ee7feb..643cf81 100644
--- a/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Messaging {
using System;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
using System.Text;
@@ -15,6 +16,7 @@ namespace DotNetOpenAuth.Messaging {
/// A live network HTTP response
/// </summary>
[DebuggerDisplay("{Status} {ContentType.MediaType}")]
+ [ContractVerification(true)]
internal class NetworkDirectWebResponse : IncomingWebResponse, IDisposable {
/// <summary>
/// The network response object, used to initialize this instance, that still needs
@@ -40,6 +42,8 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="response">The response.</param>
internal NetworkDirectWebResponse(Uri requestUri, HttpWebResponse response)
: base(requestUri, response) {
+ Contract.Requires<ArgumentNullException>(requestUri != null);
+ Contract.Requires<ArgumentNullException>(response != null);
this.httpWebResponse = response;
this.responseStream = response.GetResponseStream();
}
@@ -82,6 +86,8 @@ namespace DotNetOpenAuth.Messaging {
/// </remarks>
internal override CachedDirectWebResponse GetSnapshot(int maximumBytesToCache) {
ErrorUtilities.VerifyOperation(!this.streamReadBegun, "Network stream reading has already begun.");
+ ErrorUtilities.VerifyOperation(this.httpWebResponse != null, "httpWebResponse != null");
+
this.streamReadBegun = true;
var result = new CachedDirectWebResponse(this.RequestUri, this.httpWebResponse, maximumBytesToCache);
this.Dispose();
diff --git a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
index 147cd66..f6a930c 100644
--- a/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
+++ b/src/DotNetOpenAuth/Messaging/OutgoingWebResponse.cs
@@ -49,7 +49,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="response">The <see cref="HttpWebResponse"/> to clone.</param>
/// <param name="maximumBytesToRead">The maximum bytes to read from the response stream.</param>
protected internal OutgoingWebResponse(HttpWebResponse response, int maximumBytesToRead) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.Status = response.StatusCode;
this.Headers = response.Headers;
@@ -125,8 +125,7 @@ namespace DotNetOpenAuth.Messaging {
/// Requires a current HttpContext.
/// </remarks>
public virtual void Send() {
- Contract.Requires(HttpContext.Current != null);
- ErrorUtilities.VerifyHttpContext();
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
this.Send(HttpContext.Current);
}
@@ -139,8 +138,7 @@ namespace DotNetOpenAuth.Messaging {
/// Typically this is <see cref="HttpContext.Current"/>.</param>
/// <exception cref="ThreadAbortException">Thrown by ASP.NET in order to prevent additional data from the page being sent to the client and corrupting the response.</exception>
public virtual void Send(HttpContext context) {
- Contract.Requires(context != null);
- ErrorUtilities.VerifyArgumentNotNull(context, "context");
+ Contract.Requires<ArgumentNullException>(context != null);
context.Response.Clear();
context.Response.StatusCode = (int)this.Status;
@@ -167,8 +165,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="response">The response to set to this message.</param>
public virtual void Send(HttpListenerResponse response) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
response.StatusCode = (int)this.Status;
MessagingUtilities.ApplyHeadersToResponse(this.Headers, response);
@@ -191,8 +188,7 @@ namespace DotNetOpenAuth.Messaging {
/// rather than cause a redirect.
/// </remarks>
internal Uri GetDirectUriRequest(Channel channel) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
var message = this.OriginalMessage as IDirectedProtocolMessage;
if (message == null) {
diff --git a/src/DotNetOpenAuth/Messaging/OutgoingWebResponseActionResult.cs b/src/DotNetOpenAuth/Messaging/OutgoingWebResponseActionResult.cs
index 2da1ebf..1cfc638 100644
--- a/src/DotNetOpenAuth/Messaging/OutgoingWebResponseActionResult.cs
+++ b/src/DotNetOpenAuth/Messaging/OutgoingWebResponseActionResult.cs
@@ -5,6 +5,7 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Messaging {
+ using System;
using System.Diagnostics.Contracts;
using System.Web.Mvc;
using DotNetOpenAuth.Messaging;
@@ -24,8 +25,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="response">The response.</param>
internal OutgoingWebResponseActionResult(OutgoingWebResponse response) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
}
diff --git a/src/DotNetOpenAuth/Messaging/ProtocolException.cs b/src/DotNetOpenAuth/Messaging/ProtocolException.cs
index daf13d7..25f8eee 100644
--- a/src/DotNetOpenAuth/Messaging/ProtocolException.cs
+++ b/src/DotNetOpenAuth/Messaging/ProtocolException.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Messaging {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Security.Permissions;
/// <summary>
@@ -43,7 +44,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="faultedMessage">The message that was the cause of the exception. Must not be null.</param>
protected internal ProtocolException(string message, IProtocolMessage faultedMessage)
: base(message) {
- ErrorUtilities.VerifyArgumentNotNull(faultedMessage, "faultedMessage");
+ Contract.Requires<ArgumentNullException>(faultedMessage != null);
this.FaultedMessage = faultedMessage;
}
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/IMessagePartEncoder.cs b/src/DotNetOpenAuth/Messaging/Reflection/IMessagePartEncoder.cs
index d2c9596..03534f2 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/IMessagePartEncoder.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/IMessagePartEncoder.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.Messaging.Reflection {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
@@ -16,6 +17,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <remarks>
/// Implementations of this interface must include a default constructor and must be thread-safe.
/// </remarks>
+ [ContractClass(typeof(IMessagePartEncoderContract))]
public interface IMessagePartEncoder {
/// <summary>
/// Encodes the specified value.
@@ -32,4 +34,45 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <exception cref="FormatException">Thrown when the string value given cannot be decoded into the required object type.</exception>
object Decode(string value);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IMessagePartEncoder"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IMessagePartEncoder))]
+ internal abstract class IMessagePartEncoderContract : IMessagePartEncoder {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IMessagePartEncoderContract"/> class.
+ /// </summary>
+ protected IMessagePartEncoderContract() {
+ }
+
+ #region IMessagePartEncoder Members
+
+ /// <summary>
+ /// Encodes the specified value.
+ /// </summary>
+ /// <param name="value">The value. Guaranteed to never be null.</param>
+ /// <returns>
+ /// The <paramref name="value"/> in string form, ready for message transport.
+ /// </returns>
+ string IMessagePartEncoder.Encode(object value) {
+ Contract.Requires<ArgumentNullException>(value != null);
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Decodes the specified value.
+ /// </summary>
+ /// <param name="value">The string value carried by the transport. Guaranteed to never be null, although it may be empty.</param>
+ /// <returns>
+ /// The deserialized form of the given string.
+ /// </returns>
+ /// <exception cref="FormatException">Thrown when the string value given cannot be decoded into the required object type.</exception>
+ object IMessagePartEncoder.Decode(string value) {
+ Contract.Requires<ArgumentNullException>(value != null);
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
index 5cb7877..f250a57 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescription.cs
@@ -40,10 +40,9 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="messageType">Type of the message.</param>
/// <param name="messageVersion">The message version.</param>
internal MessageDescription(Type messageType, Version messageVersion) {
- Contract.Requires(messageType != null && typeof(IMessage).IsAssignableFrom(messageType));
- Contract.Requires(messageVersion != null);
- ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
- ErrorUtilities.VerifyArgumentNotNull(messageVersion, "messageVersion");
+ Contract.Requires<ArgumentNullException>(messageType != null);
+ Contract.Requires<ArgumentException>(typeof(IMessage).IsAssignableFrom(messageType));
+ Contract.Requires<ArgumentNullException>(messageVersion != null);
if (!typeof(IMessage).IsAssignableFrom(messageType)) {
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
@@ -70,10 +69,10 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// </summary>
/// <param name="message">The message the dictionary should provide access to.</param>
/// <returns>The dictionary accessor to the message</returns>
+ [Pure]
internal MessageDictionary GetDictionary(IMessage message) {
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
Contract.Ensures(Contract.Result<MessageDictionary>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
return new MessageDictionary(message, this);
}
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs
index 9af4bdf..ff8b74b 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs
@@ -33,12 +33,12 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="messageType">A type that implements <see cref="IMessage"/>.</param>
/// <param name="messageVersion">The protocol version of the message.</param>
/// <returns>A <see cref="MessageDescription"/> instance.</returns>
+ [Pure]
internal MessageDescription Get(Type messageType, Version messageVersion) {
- Contract.Requires(messageType != null && typeof(IMessage).IsAssignableFrom(messageType));
- Contract.Requires(messageVersion != null);
+ Contract.Requires<ArgumentNullException>(messageType != null);
+ Contract.Requires<ArgumentException>(typeof(IMessage).IsAssignableFrom(messageType));
+ Contract.Requires<ArgumentNullException>(messageVersion != null);
Contract.Ensures(Contract.Result<MessageDescription>() != null);
- ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
- ErrorUtilities.VerifyArgumentNotNull(messageVersion, "messageVersion");
MessageTypeAndVersion key = new MessageTypeAndVersion(messageType, messageVersion);
@@ -63,10 +63,10 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <returns>
/// A <see cref="MessageDescription"/> instance.
/// </returns>
+ [Pure]
internal MessageDescription Get(IMessage message) {
- Contract.Requires(message != null);
+ Contract.Requires<ArgumentNullException>(message != null);
Contract.Ensures(Contract.Result<MessageDescription>() != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
return this.Get(message.GetType(), message.Version);
}
@@ -75,9 +75,9 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// </summary>
/// <param name="message">The message.</param>
/// <returns>The dictionary.</returns>
+ [Pure]
internal MessageDictionary GetAccessor(IMessage message) {
- Contract.Requires(message != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return this.Get(message).GetDictionary(message);
}
@@ -102,10 +102,8 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="messageType">Type of the message.</param>
/// <param name="messageVersion">The message version.</param>
internal MessageTypeAndVersion(Type messageType, Version messageVersion) {
- Contract.Requires(messageType != null);
- Contract.Requires(messageVersion != null);
- ErrorUtilities.VerifyArgumentNotNull(messageType, "messageType");
- ErrorUtilities.VerifyArgumentNotNull(messageVersion, "messageVersion");
+ Contract.Requires<ArgumentNullException>(messageType != null);
+ Contract.Requires<ArgumentNullException>(messageVersion != null);
this.type = messageType;
this.version = messageVersion;
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessageDictionary.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessageDictionary.cs
index 0b5b6d0..3d2b5ae 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessageDictionary.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessageDictionary.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
/// <summary>
@@ -16,27 +17,27 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// provides access to both well-defined message properties and "extra"
/// name/value pairs that have no properties associated with them.
/// </summary>
+ [ContractVerification(false)]
internal class MessageDictionary : IDictionary<string, string> {
/// <summary>
/// The <see cref="IMessage"/> instance manipulated by this dictionary.
/// </summary>
- private IMessage message;
+ private readonly IMessage message;
/// <summary>
/// The <see cref="MessageDescription"/> instance that describes the message type.
/// </summary>
- private MessageDescription description;
+ private readonly MessageDescription description;
/// <summary>
/// Initializes a new instance of the <see cref="MessageDictionary"/> class.
/// </summary>
/// <param name="message">The message instance whose values will be manipulated by this dictionary.</param>
/// <param name="description">The message description.</param>
+ [Pure]
internal MessageDictionary(IMessage message, MessageDescription description) {
- Contract.Requires(message != null);
- Contract.Requires(description != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- ErrorUtilities.VerifyArgumentNotNull(description, "description");
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentNullException>(description != null);
this.message = message;
this.description = description;
@@ -202,9 +203,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// Thrown if <paramref name="value"/> is null.
/// </exception>
public void Add(string key, string value) {
- if (value == null) {
- throw new ArgumentNullException("value");
- }
+ ErrorUtilities.VerifyArgumentNotNull(value, "value");
MessagePart part;
if (this.description.Mapping.TryGetValue(key, out part)) {
@@ -371,7 +370,9 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// Saves the data in a message to a standard dictionary.
/// </summary>
/// <returns>The generated dictionary.</returns>
+ [Pure]
public IDictionary<string, string> Serialize() {
+ Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null);
return this.Serializer.Serialize(this);
}
@@ -380,7 +381,21 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// </summary>
/// <param name="fields">The data to load into the message.</param>
public void Deserialize(IDictionary<string, string> fields) {
+ Contract.Requires<ArgumentNullException>(fields != null);
this.Serializer.Deserialize(fields, this);
}
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(this.Message != null);
+ Contract.Invariant(this.Description != null);
+ }
+#endif
}
}
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
index f4bc3fe..32d2fec 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Net.Security;
@@ -19,6 +20,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <summary>
/// Describes an individual member of a message and assists in its serialization.
/// </summary>
+ [ContractVerification(true)]
[DebuggerDisplay("MessagePart {Name}")]
internal class MessagePart {
/// <summary>
@@ -63,12 +65,37 @@ namespace DotNetOpenAuth.Messaging.Reflection {
[SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "By design.")]
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Much more efficient initialization when we can call methods.")]
static MessagePart() {
- Map<Uri>(uri => uri.AbsoluteUri, str => new Uri(str));
+ Func<string, Uri> safeUri = str => {
+ Contract.Assume(str != null);
+ return new Uri(str);
+ };
+ Func<string, bool> safeBool = str => {
+ Contract.Assume(str != null);
+ return bool.Parse(str);
+ };
+ Func<string, Identifier> safeIdentfier = str => {
+ Contract.Assume(str != null);
+ ErrorUtilities.VerifyFormat(str.Length > 0, MessagingStrings.NonEmptyStringExpected);
+ return Identifier.Parse(str);
+ };
+ Func<byte[], string> safeFromByteArray = bytes => {
+ Contract.Assume(bytes != null);
+ return Convert.ToBase64String(bytes);
+ };
+ Func<string, byte[]> safeToByteArray = str => {
+ Contract.Assume(str != null);
+ return Convert.FromBase64String(str);
+ };
+ Func<string, Realm> safeRealm = str => {
+ Contract.Assume(str != null);
+ return new Realm(str);
+ };
+ Map<Uri>(uri => uri.AbsoluteUri, safeUri);
Map<DateTime>(dt => XmlConvert.ToString(dt, XmlDateTimeSerializationMode.Utc), str => XmlConvert.ToDateTime(str, XmlDateTimeSerializationMode.Utc));
- Map<byte[]>(bytes => Convert.ToBase64String(bytes), str => Convert.FromBase64String(str));
- Map<Realm>(realm => realm.ToString(), str => new Realm(str));
- Map<Identifier>(id => id.ToString(), str => Identifier.Parse(str));
- Map<bool>(value => value.ToString().ToLowerInvariant(), str => bool.Parse(str));
+ Map<byte[]>(safeFromByteArray, safeToByteArray);
+ Map<Realm>(realm => realm.ToString(), safeRealm);
+ Map<Identifier>(id => id.ToString(), safeIdentfier);
+ Map<bool>(value => value.ToString().ToLowerInvariant(), safeBool);
Map<CultureInfo>(c => c.Name, str => new CultureInfo(str));
Map<CultureInfo[]>(cs => string.Join(",", cs.Select(c => c.Name).ToArray()), str => str.Split(',').Select(s => new CultureInfo(s)).ToArray());
}
@@ -84,27 +111,14 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// The attribute discovered on <paramref name="member"/> that describes the
/// serialization requirements of the message part.
/// </param>
+ [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts requires it.")]
internal MessagePart(MemberInfo member, MessagePartAttribute attribute) {
- if (member == null) {
- throw new ArgumentNullException("member");
- }
+ Contract.Requires<ArgumentNullException>(member != null);
+ Contract.Requires<ArgumentException>(member is FieldInfo || member is PropertyInfo);
+ Contract.Requires<ArgumentNullException>(attribute != null);
this.field = member as FieldInfo;
this.property = member as PropertyInfo;
- if (this.field == null && this.property == null) {
- throw new ArgumentException(
- string.Format(
- CultureInfo.CurrentCulture,
- MessagingStrings.UnexpectedType,
- typeof(FieldInfo).Name + ", " + typeof(PropertyInfo).Name,
- member.GetType().Name),
- "member");
- }
-
- if (attribute == null) {
- throw new ArgumentNullException("attribute");
- }
-
this.Name = attribute.Name ?? member.Name;
this.RequiredProtection = attribute.RequiredProtection;
this.IsRequired = attribute.IsRequired;
@@ -112,6 +126,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
this.memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType;
this.defaultMemberValue = DeriveDefaultValue(this.memberDeclaredType);
+ Contract.Assume(this.memberDeclaredType != null); // CC missing PropertyInfo.PropertyType ensures result != null
if (attribute.Encoder == null) {
if (!converters.TryGetValue(this.memberDeclaredType, out this.converter)) {
this.converter = new ValueMapping(
@@ -169,9 +184,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="message">The message instance containing the member whose value should be set.</param>
/// <param name="value">The string representation of the value to set.</param>
internal void SetValue(IMessage message, string value) {
- if (message == null) {
- throw new ArgumentNullException("message");
- }
+ Contract.Requires<ArgumentNullException>(message != null);
try {
if (this.IsConstantValue) {
diff --git a/src/DotNetOpenAuth/Messaging/Reflection/ValueMapping.cs b/src/DotNetOpenAuth/Messaging/Reflection/ValueMapping.cs
index 332274e..1c7631e 100644
--- a/src/DotNetOpenAuth/Messaging/Reflection/ValueMapping.cs
+++ b/src/DotNetOpenAuth/Messaging/Reflection/ValueMapping.cs
@@ -6,10 +6,12 @@
namespace DotNetOpenAuth.Messaging.Reflection {
using System;
+ using System.Diagnostics.Contracts;
/// <summary>
/// A pair of conversion functions to map some type to a string and back again.
/// </summary>
+ [ContractVerification(true)]
internal struct ValueMapping {
/// <summary>
/// The mapping function that converts some custom type to a string.
@@ -27,8 +29,8 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// <param name="toString">The mapping function that converts some custom type to a string.</param>
/// <param name="toValue">The mapping function that converts a string to some custom type.</param>
internal ValueMapping(Func<object, string> toString, Func<string, object> toValue) {
- ErrorUtilities.VerifyArgumentNotNull(toString, "toString");
- ErrorUtilities.VerifyArgumentNotNull(toValue, "toValue");
+ Contract.Requires<ArgumentNullException>(toString != null);
+ Contract.Requires<ArgumentNullException>(toValue != null);
this.ValueToString = toString;
this.StringToValue = toValue;
@@ -39,7 +41,7 @@ namespace DotNetOpenAuth.Messaging.Reflection {
/// </summary>
/// <param name="encoder">The encoder.</param>
internal ValueMapping(IMessagePartEncoder encoder) {
- ErrorUtilities.VerifyArgumentNotNull(encoder, "encoder");
+ Contract.Requires<ArgumentNullException>(encoder != null);
var nullEncoder = encoder as IMessagePartNullEncoder;
string nullString = nullEncoder != null ? nullEncoder.EncodedNullValue : null;
diff --git a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs
index cc991cd..5b17c09 100644
--- a/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs
+++ b/src/DotNetOpenAuth/Messaging/StandardWebRequestHandler.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Messaging {
using System;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
using System.Net.Sockets;
@@ -16,7 +17,7 @@ namespace DotNetOpenAuth.Messaging {
/// The default handler for transmitting <see cref="HttpWebRequest"/> instances
/// and returning the responses.
/// </summary>
- internal class StandardWebRequestHandler : IDirectWebRequestHandler {
+ public class StandardWebRequestHandler : IDirectWebRequestHandler {
/// <summary>
/// The set of options this web request handler supports.
/// </summary>
@@ -36,6 +37,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>
/// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>.
/// </returns>
+ [Pure]
public bool CanSupport(DirectWebRequestOptions options) {
return (options & ~SupportedOptions) == 0;
}
@@ -76,9 +78,6 @@ namespace DotNetOpenAuth.Messaging {
/// a single exception type for hosts to catch.</para>
/// </remarks>
public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifySupported(this.CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name);
-
return GetRequestStreamCore(request);
}
@@ -118,9 +117,6 @@ namespace DotNetOpenAuth.Messaging {
/// value, if set, shoud be Closed before throwing.</para>
/// </remarks>
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifySupported(this.CanSupport(options), MessagingStrings.DirectWebRequestOptionsNotSupported, options, this.GetType().Name);
-
// This request MAY have already been prepared by GetRequestStream, but
// we have no guarantee, so do it just to be safe.
PrepareRequest(request, false);
@@ -229,7 +225,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The request.</param>
/// <param name="preparingPost"><c>true</c> if this is a POST request whose headers have not yet been sent out; <c>false</c> otherwise.</param>
private static void PrepareRequest(HttpWebRequest request, bool preparingPost) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
// Be careful to not try to change the HTTP headers that have already gone out.
if (preparingPost || request.Method == "GET") {
diff --git a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
index 1656155..3ea1bf2 100644
--- a/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
+++ b/src/DotNetOpenAuth/Messaging/UntrustedWebRequestHandler.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.Messaging {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Net;
@@ -87,7 +88,7 @@ namespace DotNetOpenAuth.Messaging {
/// </summary>
/// <param name="chainedWebRequestHandler">The chained web request handler.</param>
public UntrustedWebRequestHandler(IDirectWebRequestHandler chainedWebRequestHandler) {
- ErrorUtilities.VerifyArgumentNotNull(chainedWebRequestHandler, "chainedWebRequestHandler");
+ Contract.Requires<ArgumentNullException>(chainedWebRequestHandler != null);
this.chainedWebRequestHandler = chainedWebRequestHandler;
if (Debugger.IsAttached) {
@@ -111,7 +112,7 @@ namespace DotNetOpenAuth.Messaging {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value >= 2048, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value >= 2048);
this.maximumBytesToRead = value;
}
}
@@ -126,7 +127,7 @@ namespace DotNetOpenAuth.Messaging {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value >= 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
this.maximumRedirections = value;
}
}
@@ -185,6 +186,7 @@ namespace DotNetOpenAuth.Messaging {
/// <returns>
/// <c>true</c> if this instance can support the specified options; otherwise, <c>false</c>.
/// </returns>
+ [Pure]
public bool CanSupport(DirectWebRequestOptions options) {
// We support whatever our chained handler supports, plus RequireSsl.
return this.chainedWebRequestHandler.CanSupport(options & ~DirectWebRequestOptions.RequireSsl);
@@ -207,7 +209,6 @@ namespace DotNetOpenAuth.Messaging {
/// a single exception type for hosts to catch.</para>
/// </remarks>
public Stream GetRequestStream(HttpWebRequest request, DirectWebRequestOptions options) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
this.EnsureAllowableRequestUri(request.RequestUri, (options & DirectWebRequestOptions.RequireSsl) != 0);
this.PrepareRequest(request, true);
@@ -234,8 +235,6 @@ namespace DotNetOpenAuth.Messaging {
/// </remarks>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")]
public IncomingWebResponse GetResponse(HttpWebRequest request, DirectWebRequestOptions options) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
// This request MAY have already been prepared by GetRequestStream, but
// we have no guarantee, so do it just to be safe.
this.PrepareRequest(request, false);
@@ -315,7 +314,7 @@ namespace DotNetOpenAuth.Messaging {
/// <c>true</c> if this is a loopback IP address; <c>false</c> otherwise.
/// </returns>
private static bool IsIPv6Loopback(IPAddress ip) {
- ErrorUtilities.VerifyArgumentNotNull(ip, "ip");
+ Contract.Requires<ArgumentNullException>(ip != null);
byte[] addressBytes = ip.GetAddressBytes();
for (int i = 0; i < addressBytes.Length - 1; i++) {
if (addressBytes[i] != 0) {
@@ -338,9 +337,9 @@ namespace DotNetOpenAuth.Messaging {
/// <c>true</c> if the specified host falls within at least one of the given lists; otherwise, <c>false</c>.
/// </returns>
private static bool IsHostInList(string host, ICollection<string> stringList, ICollection<Regex> regexList) {
- ErrorUtilities.VerifyNonZeroLength(host, "host");
- ErrorUtilities.VerifyArgumentNotNull(stringList, "stringList");
- ErrorUtilities.VerifyArgumentNotNull(regexList, "regexList");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(host));
+ Contract.Requires<ArgumentNullException>(stringList != null);
+ Contract.Requires<ArgumentNullException>(regexList != null);
foreach (string testHost in stringList) {
if (string.Equals(host, testHost, StringComparison.OrdinalIgnoreCase)) {
return true;
@@ -396,7 +395,7 @@ namespace DotNetOpenAuth.Messaging {
/// <c>true</c> if [is URI allowable] [the specified URI]; otherwise, <c>false</c>.
/// </returns>
private bool IsUriAllowable(Uri uri) {
- ErrorUtilities.VerifyArgumentNotNull(uri, "uri");
+ Contract.Requires<ArgumentNullException>(uri != null);
if (!this.allowableSchemes.Contains(uri.Scheme)) {
Logger.Http.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri);
return false;
@@ -456,7 +455,7 @@ namespace DotNetOpenAuth.Messaging {
/// <param name="request">The request to prepare.</param>
/// <param name="preparingPost"><c>true</c> if this is a POST request whose headers have not yet been sent out; <c>false</c> otherwise.</param>
private void PrepareRequest(HttpWebRequest request, bool preparingPost) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
// Be careful to not try to change the HTTP headers that have already gone out.
if (preparingPost || request.Method == "GET") {
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs
index 42a38fe..53930bc 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs
@@ -31,7 +31,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This method signs the message per OAuth 1.0 section 9.2.
/// </remarks>
protected override string GetSignature(ITamperResistantOAuthMessage message) {
- ErrorUtilities.VerifyOperation(this.Channel != null, "Channel property has not been set.");
string key = GetConsumerAndTokenSecretString(message);
HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key));
string baseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message));
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
index ff004cb..dd28e71 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ICombinedOpenIdProviderTokenManager.cs
@@ -15,7 +15,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This interface should be implemented by the same class that implements
/// <see cref="ITokenManager"/> in order to enable the OpenID+OAuth extension.
/// </remarks>
- public interface ICombinedOpenIdProviderTokenManager {
+ public interface ICombinedOpenIdProviderTokenManager : IOpenIdOAuthTokenManager, ITokenManager {
/// <summary>
/// Gets the OAuth consumer key for a given OpenID relying party realm.
/// </summary>
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs
index 02ebffb..afeaab3 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/IServiceProviderTokenManager.cs
@@ -50,5 +50,19 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// log and throw the appropriate error.
/// </remarks>
IServiceProviderAccessToken GetAccessToken(string token);
+
+ /// <summary>
+ /// Persists any changes made to the token.
+ /// </summary>
+ /// <param name="token">The token whose properties have been changed.</param>
+ /// <remarks>
+ /// This library will invoke this method after making a set
+ /// of changes to the token as part of a web request to give the host
+ /// the opportunity to persist those changes to a database.
+ /// Depending on the object persistence framework the host site uses,
+ /// this method MAY not need to do anything (if changes made to the token
+ /// will automatically be saved without any extra handling).
+ /// </remarks>
+ void UpdateToken(IServiceProviderRequestToken token);
}
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs
index 46aa03f..d303393 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ITokenManager.cs
@@ -32,6 +32,12 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="request">The request message that resulted in the generation of a new unauthorized request token.</param>
/// <param name="response">The response message that includes the unauthorized request token.</param>
/// <exception cref="ArgumentException">Thrown if the consumer key is not registered, or a required parameter was not found in the parameters collection.</exception>
+ /// <remarks>
+ /// Request tokens stored by this method SHOULD NOT associate any user account with this token.
+ /// It usually opens up security holes in your application to do so. Instead, you associate a user
+ /// account with access tokens (not request tokens) in the <see cref="ExpireRequestTokenAndStoreNewAccessToken"/>
+ /// method.
+ /// </remarks>
void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response);
/// <summary>
@@ -54,9 +60,20 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="accessToken">The new access token that is being issued to the Consumer.</param>
/// <param name="accessTokenSecret">The secret associated with the newly issued access token.</param>
/// <remarks>
+ /// <para>
/// Any scope of granted privileges associated with the request token from the
/// original call to <see cref="StoreNewRequestToken"/> should be carried over
/// to the new Access Token.
+ /// </para>
+ /// <para>
+ /// To associate a user account with the new access token,
+ /// <see cref="System.Web.HttpContext.User">HttpContext.Current.User</see> may be
+ /// useful in an ASP.NET web application within the implementation of this method.
+ /// Alternatively you may store the access token here without associating with a user account,
+ /// and wait until <see cref="WebConsumer.ProcessUserAuthorization()"/> or
+ /// <see cref="DesktopConsumer.ProcessUserAuthorization(string, string)"/> return the access
+ /// token to associate the access token with a user account at that point.
+ /// </para>
/// </remarks>
void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret);
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
index d325825..8c5980f 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs
@@ -64,11 +64,11 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </param>
internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, IMessageFactory messageTypeProvider)
: base(messageTypeProvider, InitializeBindingElements(signingBindingElement, store, tokenManager)) {
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
+ Contract.Requires<ArgumentNullException>(signingBindingElement != null);
+ Contract.Requires<ArgumentException>(signingBindingElement.SignatureCallback == null, OAuthStrings.SigningElementAlreadyAssociatedWithChannel);
this.TokenManager = tokenManager;
- ErrorUtilities.VerifyArgumentNamed(signingBindingElement.SignatureCallback == null, "signingBindingElement", OAuthStrings.SigningElementAlreadyAssociatedWithChannel);
-
signingBindingElement.SignatureCallback = this.SignatureCallback;
}
@@ -101,7 +101,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="request">The message to attach.</param>
/// <returns>The initialized web request.</returns>
internal HttpWebRequest InitializeRequest(IDirectedProtocolMessage request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
ProcessOutgoingMessage(request);
return this.CreateHttpRequest(request);
@@ -114,8 +114,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="request">The HTTP request to search.</param>
/// <returns>The deserialized message, if one is found. Null otherwise.</returns>
protected override IDirectedProtocolMessage ReadFromRequestCore(HttpRequestInfo request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
var fields = new Dictionary<string, string>();
// First search the Authorization header.
@@ -178,8 +176,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// The deserialized message parts, if found. Null otherwise.
/// </returns>
protected override IDictionary<string, string> ReadFromResponseCore(IncomingWebResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
-
string body = response.GetResponseReader().ReadToEnd();
return HttpUtility.ParseQueryString(body).ToDictionary();
}
@@ -192,21 +188,19 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// The <see cref="HttpRequest"/> prepared to send the request.
/// </returns>
protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNamed(request.Recipient != null, "request", MessagingStrings.DirectedMessageMissingRecipient);
-
- IDirectedProtocolMessage oauthRequest = request as IDirectedProtocolMessage;
- ErrorUtilities.VerifyArgument(oauthRequest != null, MessagingStrings.UnexpectedType, typeof(IDirectedProtocolMessage), request.GetType());
-
HttpWebRequest httpRequest;
- HttpDeliveryMethods transmissionMethod = oauthRequest.HttpMethods;
+ HttpDeliveryMethods transmissionMethod = request.HttpMethods;
if ((transmissionMethod & HttpDeliveryMethods.AuthorizationHeaderRequest) != 0) {
httpRequest = this.InitializeRequestAsAuthHeader(request);
} else if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0) {
httpRequest = this.InitializeRequestAsPost(request);
} else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0) {
httpRequest = InitializeRequestAsGet(request);
+ } else if ((transmissionMethod & HttpDeliveryMethods.PutRequest) != 0) {
+ httpRequest = this.InitializeRequestAsPut(request);
+ } else if ((transmissionMethod & HttpDeliveryMethods.DeleteRequest) != 0) {
+ httpRequest = InitializeRequestAsDelete(request);
} else {
throw new NotSupportedException();
}
@@ -223,8 +217,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This method implements spec V1.0 section 5.3.
/// </remarks>
protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
-
var messageAccessor = this.MessageDescriptions.GetAccessor(response);
var fields = messageAccessor.Serialize();
string responseBody = MessagingUtilities.CreateQueryString(fields);
@@ -273,8 +265,8 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="source">The dictionary with names and values to encode.</param>
/// <param name="destination">The dictionary to add the encoded pairs to.</param>
private static void UriEscapeParameters(IDictionary<string, string> source, IDictionary<string, string> destination) {
- ErrorUtilities.VerifyArgumentNotNull(source, "source");
- ErrorUtilities.VerifyArgumentNotNull(destination, "destination");
+ Contract.Requires<ArgumentNullException>(source != null);
+ Contract.Requires<ArgumentNullException>(destination != null);
foreach (var pair in source) {
var key = MessagingUtilities.EscapeUriDataStringRfc3986(pair.Key);
@@ -289,14 +281,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="message">The message.</param>
/// <returns>"POST", "GET" or some other similar http verb.</returns>
private static string GetHttpMethod(IDirectedProtocolMessage message) {
- Contract.Requires(message != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
var signedMessage = message as ITamperResistantOAuthMessage;
if (signedMessage != null) {
return signedMessage.HttpMethod;
} else {
- return (message.HttpMethods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET";
+ return MessagingUtilities.GetHttpVerb(message.HttpMethods);
}
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs
index e05bb62..327b923 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthConsumerMessageFactory.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth.Messages;
@@ -38,9 +39,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// UserAuthorizationResponse
/// </remarks>
public virtual IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(recipient, "recipient");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
MessageBase message = null;
if (fields.ContainsKey("oauth_token")) {
@@ -74,9 +72,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// AuthorizedTokenResponse
/// </remarks>
public virtual IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
MessageBase message = null;
// All response messages have the oauth_token field.
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs
index c9df0e8..37fb80b 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthHttpMethodBindingElement.cs
@@ -42,15 +42,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
if (oauthMessage != null) {
HttpDeliveryMethods transmissionMethod = oauthMessage.HttpMethods;
- if ((transmissionMethod & HttpDeliveryMethods.PostRequest) != 0) {
- oauthMessage.HttpMethod = "POST";
- } else if ((transmissionMethod & HttpDeliveryMethods.GetRequest) != 0) {
- oauthMessage.HttpMethod = "GET";
- } else {
+ try {
+ oauthMessage.HttpMethod = MessagingUtilities.GetHttpVerb(transmissionMethod);
+ return MessageProtections.None;
+ } catch (ArgumentException ex) {
+ Logger.OAuth.Error("Unrecognized HttpDeliveryMethods value.", ex);
return null;
}
-
- return MessageProtections.None;
} else {
return null;
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthIdentity.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthIdentity.cs
index bd57012..65bde20 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthIdentity.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthIdentity.cs
@@ -24,8 +24,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </summary>
/// <param name="username">The username.</param>
internal OAuthIdentity(string username) {
- Contract.Requires(!String.IsNullOrEmpty(username));
- ErrorUtilities.VerifyNonZeroLength(username, "username");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(username));
this.Name = username;
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs
index a9f363a..025ef09 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthPrincipal.cs
@@ -31,7 +31,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="token">The access token.</param>
internal OAuthPrincipal(IServiceProviderAccessToken token)
: this(token.Username, token.Roles) {
- Contract.Requires(token != null);
+ Contract.Requires<ArgumentNullException>(token != null);
this.AccessToken = token.Token;
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
index abb99d8..5b3c918 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthServiceProviderMessageFactory.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth.Messages;
@@ -25,7 +26,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </summary>
/// <param name="tokenManager">The token manager instance to use.</param>
public OAuthServiceProviderMessageFactory(IServiceProviderTokenManager tokenManager) {
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
this.tokenManager = tokenManager;
}
@@ -50,9 +51,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// AccessProtectedResourceRequest
/// </remarks>
public virtual IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(recipient, "recipient");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
MessageBase message = null;
Protocol protocol = Protocol.V10; // default to assuming the less-secure 1.0 instead of 1.0a until we prove otherwise.
string token;
@@ -119,9 +117,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// None.
/// </remarks>
public virtual IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
Logger.OAuth.Error("Service Providers are not expected to ever receive responses.");
return null;
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
index 9f99066..22e5f20 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/PlaintextSigningBindingElement.cs
@@ -41,7 +41,12 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="message">The message that needs to be signed.</param>
/// <returns>True if this binding element can be used to sign the message. False otherwise.</returns>
protected override bool IsMessageApplicable(ITamperResistantOAuthMessage message) {
- return string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase);
+ if (string.Equals(message.Recipient.Scheme, "https", StringComparison.OrdinalIgnoreCase)) {
+ return true;
+ } else {
+ Logger.Bindings.DebugFormat("The {0} element will not sign this message because the URI scheme is not https.", this.GetType().Name);
+ return false;
+ }
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
index 4f8b5e5..f7b8370 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/RsaSha1SigningBindingElement.cs
@@ -33,8 +33,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="signingCertificate">The certificate used to sign outgoing messages.</param>
public RsaSha1SigningBindingElement(X509Certificate2 signingCertificate)
: base(HashAlgorithmName) {
- Contract.Requires(signingCertificate != null);
- ErrorUtilities.VerifyArgumentNotNull(signingCertificate, "signingCertificate");
+ Contract.Requires<ArgumentNullException>(signingCertificate != null);
this.SigningCertificate = signingCertificate;
}
@@ -46,8 +45,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="tokenManager">The token manager.</param>
public RsaSha1SigningBindingElement(IServiceProviderTokenManager tokenManager)
: base(HashAlgorithmName) {
- Contract.Requires(tokenManager != null);
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
this.tokenManager = tokenManager;
}
@@ -66,7 +64,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This method signs the message per OAuth 1.0 section 9.3.
/// </remarks>
protected override string GetSignature(ITamperResistantOAuthMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
ErrorUtilities.VerifyOperation(this.SigningCertificate != null, OAuthStrings.X509CertificateNotProvidedForSigning);
string signatureBaseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message));
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs
index 6991818..0fd9bf9 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs
@@ -148,9 +148,9 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// This method implements OAuth 1.0 section 9.1.
/// </remarks>
internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) {
- Contract.Requires(message != null);
- Contract.Requires(messageDictionary != null);
- Contract.Requires(messageDictionary.Message == message);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<ArgumentNullException>(messageDictionary != null);
+ Contract.Requires<ArgumentException>(messageDictionary.Message == message);
if (String.IsNullOrEmpty(message.HttpMethod)) {
throw new ArgumentException(
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBaseContract.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBaseContract.cs
index 7019b45..7b369c3 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBaseContract.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBaseContract.cs
@@ -40,7 +40,8 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <param name="message">The message to sign.</param>
/// <returns>The signature for the message.</returns>
protected override string GetSignature(ITamperResistantOAuthMessage message) {
- Contract.Requires(this.Channel != null);
+ Contract.Requires<ArgumentNullException>(message != null);
+ Contract.Requires<InvalidOperationException>(this.Channel != null);
throw new NotImplementedException();
}
}
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs
index 3e75e7b..f9547c6 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs
@@ -29,8 +29,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </summary>
/// <param name="tokenManager">The token manager.</param>
internal TokenHandlingBindingElement(IServiceProviderTokenManager tokenManager) {
- Contract.Requires(tokenManager != null);
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
this.tokenManager = tokenManager;
}
@@ -68,11 +67,11 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
-
var userAuthResponse = message as UserAuthorizationResponse;
if (userAuthResponse != null && userAuthResponse.Version >= Protocol.V10a.Version) {
- this.tokenManager.GetRequestToken(userAuthResponse.RequestToken).VerificationCode = userAuthResponse.VerificationCode;
+ var requestToken = this.tokenManager.GetRequestToken(userAuthResponse.RequestToken);
+ requestToken.VerificationCode = userAuthResponse.VerificationCode;
+ this.tokenManager.UpdateToken(requestToken);
return MessageProtections.None;
}
@@ -80,10 +79,14 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
var grantRequestTokenResponse = message as UnauthorizedTokenResponse;
if (grantRequestTokenResponse != null) {
this.tokenManager.StoreNewRequestToken(grantRequestTokenResponse.RequestMessage, grantRequestTokenResponse);
- this.tokenManager.GetRequestToken(grantRequestTokenResponse.RequestToken).ConsumerVersion = grantRequestTokenResponse.Version;
+
+ // The host may have already set these properties, but just to make sure...
+ var requestToken = this.tokenManager.GetRequestToken(grantRequestTokenResponse.RequestToken);
+ requestToken.ConsumerVersion = grantRequestTokenResponse.Version;
if (grantRequestTokenResponse.RequestMessage.Callback != null) {
- this.tokenManager.GetRequestToken(grantRequestTokenResponse.RequestToken).Callback = grantRequestTokenResponse.RequestMessage.Callback;
+ requestToken.Callback = grantRequestTokenResponse.RequestMessage.Callback;
}
+ this.tokenManager.UpdateToken(requestToken);
return MessageProtections.None;
}
@@ -109,8 +112,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
-
var authorizedTokenRequest = message as AuthorizedTokenRequest;
if (authorizedTokenRequest != null) {
if (authorizedTokenRequest.Version >= Protocol.V10a.Version) {
@@ -142,7 +143,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// </summary>
/// <param name="message">The incoming message carrying the access token.</param>
private void VerifyThrowTokenNotExpired(AccessProtectedResourceRequest message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
try {
IServiceProviderAccessToken token = this.tokenManager.GetAccessToken(message.AccessToken);
diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/UriOrOobEncoding.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/UriOrOobEncoding.cs
index 5aedc9d..287ef01 100644
--- a/src/DotNetOpenAuth/OAuth/ChannelElements/UriOrOobEncoding.cs
+++ b/src/DotNetOpenAuth/OAuth/ChannelElements/UriOrOobEncoding.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OAuth.ChannelElements {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -51,8 +52,6 @@ namespace DotNetOpenAuth.OAuth.ChannelElements {
/// The <paramref name="value"/> in string form, ready for message transport.
/// </returns>
public string Encode(object value) {
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
-
Uri uriValue = (Uri)value;
return uriValue.AbsoluteUri;
}
diff --git a/src/DotNetOpenAuth/OAuth/ConsumerBase.cs b/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
index 55b40ac..b9d4718 100644
--- a/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
+++ b/src/DotNetOpenAuth/OAuth/ConsumerBase.cs
@@ -26,11 +26,11 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="serviceDescription">The endpoints and behavior of the Service Provider.</param>
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
protected ConsumerBase(ServiceProviderDescription serviceDescription, IConsumerTokenManager tokenManager) {
- ErrorUtilities.VerifyArgumentNotNull(serviceDescription, "serviceDescription");
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
+ Contract.Requires<ArgumentNullException>(serviceDescription != null);
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
ITamperProtectionChannelBindingElement signingElement = serviceDescription.CreateTamperProtectionElement();
- INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge);
+ INonceStore store = new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge);
this.OAuthChannel = new OAuthChannel(signingElement, store, tokenManager);
this.ServiceProvider = serviceDescription;
this.SecuritySettings = DotNetOpenAuthSection.Configuration.OAuth.Consumer.SecuritySettings.CreateSecuritySettings();
@@ -80,10 +80,8 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="accessToken">The access token that permits access to the protected resource.</param>
/// <returns>The initialized WebRequest object.</returns>
public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken) {
- Contract.Requires(endpoint != null);
- Contract.Requires(!String.IsNullOrEmpty(accessToken));
- ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint");
- ErrorUtilities.VerifyNonZeroLength(accessToken, "accessToken");
+ Contract.Requires<ArgumentNullException>(endpoint != null);
+ Contract.Requires<ArgumentNullException>(!String.IsNullOrEmpty(accessToken));
return this.PrepareAuthorizedRequest(endpoint, accessToken, EmptyDictionary<string, string>.Instance);
}
@@ -97,12 +95,9 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="extraData">Extra parameters to include in the message. Must not be null, but may be empty.</param>
/// <returns>The initialized WebRequest object.</returns>
public HttpWebRequest PrepareAuthorizedRequest(MessageReceivingEndpoint endpoint, string accessToken, IDictionary<string, string> extraData) {
- Contract.Requires(endpoint != null);
- Contract.Requires(!String.IsNullOrEmpty(accessToken));
- Contract.Requires(extraData != null);
- ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint");
- ErrorUtilities.VerifyNonZeroLength(accessToken, "accessToken");
- ErrorUtilities.VerifyArgumentNotNull(extraData, "extraData");
+ Contract.Requires<ArgumentNullException>(endpoint != null);
+ Contract.Requires<ArgumentNullException>(!String.IsNullOrEmpty(accessToken));
+ Contract.Requires<ArgumentNullException>(extraData != null);
IDirectedProtocolMessage message = this.CreateAuthorizingMessage(endpoint, accessToken);
foreach (var pair in extraData) {
@@ -130,8 +125,7 @@ namespace DotNetOpenAuth.OAuth {
/// </remarks>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Type of parameter forces the method to apply only to specific scenario.")]
public HttpWebRequest PrepareAuthorizedRequest(AccessProtectedResourceRequest message) {
- Contract.Requires(message != null);
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return this.OAuthChannel.InitializeRequest(message);
}
@@ -169,10 +163,8 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="accessToken">The access token that permits access to the protected resource.</param>
/// <returns>The initialized WebRequest object.</returns>
protected internal AccessProtectedResourceRequest CreateAuthorizingMessage(MessageReceivingEndpoint endpoint, string accessToken) {
- Contract.Requires(endpoint != null);
- Contract.Requires(!String.IsNullOrEmpty(accessToken));
- ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint");
- ErrorUtilities.VerifyNonZeroLength(accessToken, "accessToken");
+ Contract.Requires<ArgumentNullException>(endpoint != null);
+ Contract.Requires<ArgumentNullException>(!String.IsNullOrEmpty(accessToken));
AccessProtectedResourceRequest message = new AccessProtectedResourceRequest(endpoint, this.ServiceProvider.Version) {
AccessToken = accessToken,
@@ -233,9 +225,8 @@ namespace DotNetOpenAuth.OAuth {
/// The access token assigned by the Service Provider.
/// </returns>
protected AuthorizedTokenResponse ProcessUserAuthorization(string requestToken, string verifier) {
- Contract.Requires(!String.IsNullOrEmpty(requestToken));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(requestToken));
Contract.Ensures(Contract.Result<AuthorizedTokenResponse>() != null);
- ErrorUtilities.VerifyNonZeroLength(requestToken, "requestToken");
var requestAccess = new AuthorizedTokenRequest(this.ServiceProvider.AccessTokenEndpoint, this.ServiceProvider.Version) {
RequestToken = requestToken,
diff --git a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs
index 944bc5c..1a0ba23 100644
--- a/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs
+++ b/src/DotNetOpenAuth/OAuth/Messages/MessageBase.cs
@@ -65,8 +65,8 @@ namespace DotNetOpenAuth.OAuth.Messages {
/// <param name="originatingRequest">The request that asked for this direct response.</param>
/// <param name="version">The OAuth version.</param>
protected MessageBase(MessageProtections protectionRequired, IDirectedProtocolMessage originatingRequest, Version version) {
- ErrorUtilities.VerifyArgumentNotNull(originatingRequest, "originatingRequest");
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
+ Contract.Requires<ArgumentNullException>(originatingRequest != null);
+ Contract.Requires<ArgumentNullException>(version != null);
this.protectionRequired = protectionRequired;
this.transport = MessageTransport.Direct;
@@ -82,8 +82,8 @@ namespace DotNetOpenAuth.OAuth.Messages {
/// <param name="recipient">The URI that a directed message will be delivered to.</param>
/// <param name="version">The OAuth version.</param>
protected MessageBase(MessageProtections protectionRequired, MessageTransport transport, MessageReceivingEndpoint recipient, Version version) {
- ErrorUtilities.VerifyArgumentNotNull(recipient, "recipient");
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
+ Contract.Requires<ArgumentNullException>(recipient != null);
+ Contract.Requires<ArgumentNullException>(version != null);
this.protectionRequired = protectionRequired;
this.transport = transport;
@@ -242,8 +242,7 @@ namespace DotNetOpenAuth.OAuth.Messages {
/// The string representation of this object.
/// </returns>
internal virtual string ToString(Channel channel) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
StringBuilder builder = new StringBuilder();
builder.AppendFormat(CultureInfo.InvariantCulture, "{0} message", GetType().Name);
diff --git a/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs b/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs
index 1d8ca21..57ce470 100644
--- a/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs
+++ b/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs
@@ -36,7 +36,7 @@ namespace DotNetOpenAuth.OAuth.Messages {
: base(MessageProtections.All, transport, recipient, version) {
ITamperResistantOAuthMessage self = (ITamperResistantOAuthMessage)this;
HttpDeliveryMethods methods = ((IDirectedProtocolMessage)this).HttpMethods;
- self.HttpMethod = (methods & HttpDeliveryMethods.PostRequest) != 0 ? "POST" : "GET";
+ self.HttpMethod = MessagingUtilities.GetHttpVerb(methods);
}
#region ITamperResistantOAuthMessage Members
diff --git a/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs b/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs
index ce09213..0be9f63 100644
--- a/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs
+++ b/src/DotNetOpenAuth/OAuth/Messages/UnauthorizedTokenResponse.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth.Messages {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -26,8 +27,8 @@ namespace DotNetOpenAuth.OAuth.Messages {
/// </remarks>
protected internal UnauthorizedTokenResponse(UnauthorizedTokenRequest requestMessage, string requestToken, string tokenSecret)
: this(requestMessage, requestMessage.Version) {
- ErrorUtilities.VerifyArgumentNotNull(requestToken, "requestToken");
- ErrorUtilities.VerifyArgumentNotNull(tokenSecret, "tokenSecret");
+ Contract.Requires<ArgumentNullException>(requestToken != null);
+ Contract.Requires<ArgumentNullException>(tokenSecret != null);
this.RequestToken = requestToken;
this.TokenSecret = tokenSecret;
diff --git a/src/DotNetOpenAuth/OAuth/OAuthStrings.sr.resx b/src/DotNetOpenAuth/OAuth/OAuthStrings.sr.resx
new file mode 100644
index 0000000..ef9ce60
--- /dev/null
+++ b/src/DotNetOpenAuth/OAuth/OAuthStrings.sr.resx
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="AccessTokenNotAuthorized" xml:space="preserve">
+ <value>Ne može se poslati pristupni token za Consumera za token zahteva '{0}' pre nego što bude autorizovan.</value>
+ </data>
+ <data name="BadAccessTokenInProtectedResourceRequest" xml:space="preserve">
+ <value>Pristupni token '{0}' je neispravan ili je mu je istekao rok važenja.</value>
+ </data>
+ <data name="ConsumerOrTokenSecretNotFound" xml:space="preserve">
+ <value>Greška u traženju šifre za korisnika ili za token.</value>
+ </data>
+ <data name="IncorrectVerifier" xml:space="preserve">
+ <value>oauth_verifier argument je neispravan.</value>
+ </data>
+ <data name="InvalidIncomingMessage" xml:space="preserve">
+ <value>Neispravna OAuth poruka je primljena i odbaÄena.</value>
+ </data>
+ <data name="MessageNotAllowedExtraParameters" xml:space="preserve">
+ <value>Poruka {0} je sadržala višak podataka koji nije dozvoljen.</value>
+ </data>
+ <data name="MinimumConsumerVersionRequirementNotMet" xml:space="preserve">
+ <value>Ovaj provajder OAuth usluge zahteva od OAuth korisnika da da implementira OAuth {0}, ali izgleda da korisnika podržava jedino {1}.</value>
+ </data>
+ <data name="OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface" xml:space="preserve">
+ <value>Korišćenje OpenID+OAuth ekstenzije zahteva da token menadžer koji se koristi implementira {0} interfejs.</value>
+ </data>
+ <data name="OpenIdOAuthRealmConsumerKeyDoNotMatch" xml:space="preserve">
+ <value>OpenID Relying Party domen nije prepoznat kao da pripada OAuth Consumeru identifikovanom po datom korisniÄkom tokenu.</value>
+ </data>
+ <data name="RequestUrlMustNotHaveOAuthParameters" xml:space="preserve">
+ <value>URL upit zahteva NE SME sadržati bilo kakve OAuth Protocol Parametre.</value>
+ </data>
+ <data name="SigningElementAlreadyAssociatedWithChannel" xml:space="preserve">
+ <value>Potpisujući element je već asociran sa kanalom.</value>
+ </data>
+ <data name="SigningElementsMustShareSameProtection" xml:space="preserve">
+ <value>Svi elementi za potpisivanje moraju nuditi istu zaštitu poruke.</value>
+ </data>
+ <data name="TokenNotFound" xml:space="preserve">
+ <value>Token u poruci nije prepoznat od strane provajdera usluge.</value>
+ </data>
+ <data name="X509CertificateNotProvidedForSigning" xml:space="preserve">
+ <value>RSA-SHA1 potpisujući povezujući element nije podešen sa sertifikatom za potpisivanje.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OAuth/Protocol.cs b/src/DotNetOpenAuth/OAuth/Protocol.cs
index cd4e486..a524ba7 100644
--- a/src/DotNetOpenAuth/OAuth/Protocol.cs
+++ b/src/DotNetOpenAuth/OAuth/Protocol.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OAuth {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -139,10 +140,9 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="version">The OAuth version to get.</param>
/// <returns>A matching <see cref="Protocol"/> instance.</returns>
internal static Protocol Lookup(Version version) {
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
- Protocol protocol = AllVersions.FirstOrDefault(p => p.Version == version);
- ErrorUtilities.VerifyArgumentInRange(protocol != null, "version");
- return protocol;
+ Contract.Requires<ArgumentNullException>(version != null);
+ Contract.Requires<ArgumentOutOfRangeException>(AllVersions.Any(p => p.Version == version));
+ return AllVersions.First(p => p.Version == version);
}
}
}
diff --git a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
index fe65ed7..5883273 100644
--- a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
+++ b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs
@@ -61,7 +61,10 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="tokenManager">The host's method of storing and recalling tokens and secrets.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, OAuthServiceProviderMessageFactory messageTypeProvider)
- : this(serviceDescription, tokenManager, new NonceMemoryStore(StandardExpirationBindingElement.DefaultMaximumMessageAge), messageTypeProvider) {
+ : this(serviceDescription, tokenManager, new NonceMemoryStore(StandardExpirationBindingElement.MaximumMessageAge), messageTypeProvider) {
+ Contract.Requires<ArgumentNullException>(serviceDescription != null);
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
}
/// <summary>
@@ -82,10 +85,10 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="nonceStore">The nonce store.</param>
/// <param name="messageTypeProvider">An object that can figure out what type of message is being received for deserialization.</param>
public ServiceProvider(ServiceProviderDescription serviceDescription, IServiceProviderTokenManager tokenManager, INonceStore nonceStore, OAuthServiceProviderMessageFactory messageTypeProvider) {
- ErrorUtilities.VerifyArgumentNotNull(serviceDescription, "serviceDescription");
- ErrorUtilities.VerifyArgumentNotNull(tokenManager, "tokenManager");
- ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
- ErrorUtilities.VerifyArgumentNotNull(messageTypeProvider, "messageTypeProvider");
+ Contract.Requires<ArgumentNullException>(serviceDescription != null);
+ Contract.Requires<ArgumentNullException>(tokenManager != null);
+ Contract.Requires<ArgumentNullException>(nonceStore != null);
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
var signingElement = serviceDescription.CreateTamperProtectionElement();
this.ServiceDescription = serviceDescription;
@@ -132,8 +135,7 @@ namespace DotNetOpenAuth.OAuth {
}
set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.channel = value;
}
}
@@ -148,8 +150,7 @@ namespace DotNetOpenAuth.OAuth {
/// length of the final string.</param>
/// <returns>The verification code.</returns>
public static string CreateVerificationCode(VerificationCodeFormat format, int length) {
- Contract.Requires(length >= 0);
- ErrorUtilities.VerifyArgumentInRange(length >= 0, "length");
+ Contract.Requires<ArgumentOutOfRangeException>(length >= 0);
switch (format) {
case VerificationCodeFormat.IncludedInCallback:
@@ -220,7 +221,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="request">The token request message the Consumer sent that the Service Provider is now responding to.</param>
/// <returns>The response message to send using the <see cref="Channel"/>, after optionally adding extra data to it.</returns>
public UnauthorizedTokenResponse PrepareUnauthorizedTokenMessage(UnauthorizedTokenRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
string token = this.TokenGenerator.GenerateRequestToken(request.ConsumerKey);
string secret = this.TokenGenerator.GenerateSecret();
@@ -257,11 +258,12 @@ namespace DotNetOpenAuth.OAuth {
/// <summary>
/// Gets the OAuth authorization request included with an OpenID authentication
- /// request.
+ /// request, if there is one.
/// </summary>
/// <param name="openIdRequest">The OpenID authentication request.</param>
/// <returns>
- /// The scope of access the relying party is requesting.
+ /// The scope of access the relying party is requesting, or null if no OAuth request
+ /// is present.
/// </returns>
/// <remarks>
/// <para>Call this method rather than simply extracting the OAuth extension
@@ -269,9 +271,8 @@ namespace DotNetOpenAuth.OAuth {
/// security measures that are required are taken.</para>
/// </remarks>
public AuthorizationRequest ReadAuthorizationRequest(IHostProcessedRequest openIdRequest) {
- Contract.Requires(openIdRequest != null);
- Contract.Requires(this.TokenManager is ICombinedOpenIdProviderTokenManager);
- ErrorUtilities.VerifyArgumentNotNull(openIdRequest, "openIdAuthenticationRequest");
+ Contract.Requires<ArgumentNullException>(openIdRequest != null);
+ Contract.Requires<InvalidOperationException>(this.TokenManager is ICombinedOpenIdProviderTokenManager);
var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager;
ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName);
@@ -291,24 +292,39 @@ namespace DotNetOpenAuth.OAuth {
return authzRequest;
}
+ /// <summary>
+ /// Attaches the authorization response to an OpenID authentication response.
+ /// </summary>
+ /// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param>
+ /// <param name="consumerKey">The consumer key. Must be <c>null</c> if and only if <paramref name="scope"/> is null.</param>
+ /// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param>
+ [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")]
+ [Obsolete("Call the overload that doesn't take a consumerKey instead.")]
+ public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string consumerKey, string scope) {
+ Contract.Requires<ArgumentNullException>(openIdAuthenticationRequest != null);
+ Contract.Requires<ArgumentException>((consumerKey == null) == (scope == null));
+ Contract.Requires<InvalidOperationException>(this.TokenManager is ICombinedOpenIdProviderTokenManager);
+ var openidTokenManager = (ICombinedOpenIdProviderTokenManager)this.TokenManager;
+ ErrorUtilities.VerifyArgument(consumerKey == null || consumerKey == openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm), "The consumer key and the realm did not match according to the token manager.");
+
+ this.AttachAuthorizationResponse(openIdAuthenticationRequest, scope);
+ }
+
/// <summary>
/// Attaches the authorization response to an OpenID authentication response.
/// </summary>
/// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param>
- /// <param name="consumerKey">The consumer key. May and should be <c>null</c> if and only if <paramref name="scope"/> is null.</param>
/// <param name="scope">The approved access scope. Use <c>null</c> to indicate no access was granted. The empty string will be interpreted as some default level of access is granted.</param>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "We want to take IAuthenticationRequest because that's the only supported use case.")]
- public void AttachAuthorizationResponse(IAuthenticationRequest openIdAuthenticationRequest, string consumerKey, string scope) {
- Contract.Requires(openIdAuthenticationRequest != null);
- Contract.Requires((consumerKey == null) == (scope == null));
- Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager);
- ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest");
- var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager;
- ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName);
+ public void AttachAuthorizationResponse(IHostProcessedRequest openIdAuthenticationRequest, string scope) {
+ Contract.Requires<ArgumentNullException>(openIdAuthenticationRequest != null);
+ Contract.Requires<InvalidOperationException>(this.TokenManager is ICombinedOpenIdProviderTokenManager);
+ var openidTokenManager = this.TokenManager as ICombinedOpenIdProviderTokenManager;
IOpenIdMessageExtension response;
if (scope != null) {
// Generate an authorized request token to return to the relying party.
+ string consumerKey = openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm);
var approvedResponse = new AuthorizationApprovedResponse {
RequestToken = this.TokenGenerator.GenerateRequestToken(consumerKey),
Scope = scope,
@@ -333,8 +349,7 @@ namespace DotNetOpenAuth.OAuth {
/// </returns>
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Consistent user experience with instance.")]
public UserAuthorizationResponse PrepareAuthorizationResponse(UserAuthorizationRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
// It is very important for us to ignore the oauth_callback argument in the
// UserAuthorizationRequest if the Consumer is a 1.0a consumer or else we
@@ -371,10 +386,8 @@ namespace DotNetOpenAuth.OAuth {
/// </returns>
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Consistent user experience with instance.")]
public UserAuthorizationResponse PrepareAuthorizationResponse(UserAuthorizationRequest request, Uri callback) {
- Contract.Requires(request != null);
- Contract.Requires(callback != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(callback, "callback");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(callback != null);
var authorization = new UserAuthorizationResponse(callback, request.Version) {
RequestToken = request.RequestToken,
@@ -417,8 +430,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="request">The Consumer's message requesting an access token.</param>
/// <returns>The HTTP response to actually send to the Consumer.</returns>
public AuthorizedTokenResponse PrepareAccessTokenMessage(AuthorizedTokenRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
ErrorUtilities.VerifyProtocol(this.TokenManager.IsRequestTokenAuthorized(request.RequestToken), OAuthStrings.AccessTokenNotAuthorized, request.RequestToken);
@@ -475,7 +487,7 @@ namespace DotNetOpenAuth.OAuth {
/// </remarks>
/// <exception cref="ProtocolException">Thrown if an unexpected message is attached to the request.</exception>
public AccessProtectedResourceRequest ReadProtectedResourceAuthorization(HttpRequestInfo request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
AccessProtectedResourceRequest accessMessage;
if (this.Channel.TryReadFromRequest<AccessProtectedResourceRequest>(request, out accessMessage)) {
@@ -497,8 +509,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="request">The request.</param>
/// <returns>The <see cref="IPrincipal"/> instance that can be used for access control of resources.</returns>
public OAuthPrincipal CreatePrincipal(AccessProtectedResourceRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
IServiceProviderAccessToken accessToken = this.TokenManager.GetAccessToken(request.AccessToken);
return new OAuthPrincipal(accessToken);
diff --git a/src/DotNetOpenAuth/OAuth/WebConsumer.cs b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
index d86444d..de37b80 100644
--- a/src/DotNetOpenAuth/OAuth/WebConsumer.cs
+++ b/src/DotNetOpenAuth/OAuth/WebConsumer.cs
@@ -79,8 +79,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="openIdAuthenticationRequest">The OpenID authentication request.</param>
/// <param name="scope">The scope of access that is requested of the service provider.</param>
public void AttachAuthorizationRequest(IAuthenticationRequest openIdAuthenticationRequest, string scope) {
- Contract.Requires(openIdAuthenticationRequest != null);
- ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationRequest, "openIdAuthenticationRequest");
+ Contract.Requires<ArgumentNullException>(openIdAuthenticationRequest != null);
var authorizationRequest = new AuthorizationRequest {
Consumer = this.ConsumerKey,
@@ -102,9 +101,8 @@ namespace DotNetOpenAuth.OAuth {
/// The token manager instance must implement <see cref="IOpenIdOAuthTokenManager"/>.
/// </remarks>
public AuthorizedTokenResponse ProcessUserAuthorization(IAuthenticationResponse openIdAuthenticationResponse) {
- Contract.Requires(openIdAuthenticationResponse != null);
- Contract.Requires(this.TokenManager is IOpenIdOAuthTokenManager);
- ErrorUtilities.VerifyArgumentNotNull(openIdAuthenticationResponse, "openIdAuthenticationResponse");
+ Contract.Requires<ArgumentNullException>(openIdAuthenticationResponse != null);
+ Contract.Requires<InvalidOperationException>(this.TokenManager is IOpenIdOAuthTokenManager);
var openidTokenManager = this.TokenManager as IOpenIdOAuthTokenManager;
ErrorUtilities.VerifyOperation(openidTokenManager != null, OAuthStrings.OpenIdOAuthExtensionRequiresSpecialTokenManagerInterface, typeof(IOpenIdOAuthTokenManager).FullName);
@@ -142,8 +140,7 @@ namespace DotNetOpenAuth.OAuth {
/// <param name="request">The incoming HTTP request.</param>
/// <returns>The access token, or null if no incoming authorization message was recognized.</returns>
public AuthorizedTokenResponse ProcessUserAuthorization(HttpRequestInfo request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
UserAuthorizationResponse authorizationMessage;
if (this.Channel.TryReadFromRequest<UserAuthorizationResponse>(request, out authorizationMessage)) {
diff --git a/src/DotNetOpenAuth/OpenId/Association.cs b/src/DotNetOpenAuth/OpenId/Association.cs
index ce129bb..d2c84cb 100644
--- a/src/DotNetOpenAuth/OpenId/Association.cs
+++ b/src/DotNetOpenAuth/OpenId/Association.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId {
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Security.Cryptography;
using System.Text;
@@ -23,6 +24,8 @@ namespace DotNetOpenAuth.OpenId {
/// (dumb associations).
/// </remarks>
[DebuggerDisplay("Handle = {Handle}, Expires = {Expires}")]
+ [ContractVerification(true)]
+ [ContractClass(typeof(AssociationContract))]
public abstract class Association {
/// <summary>
/// Initializes a new instance of the <see cref="Association"/> class.
@@ -30,10 +33,14 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="handle">The handle.</param>
/// <param name="secret">The secret.</param>
/// <param name="totalLifeLength">How long the association will be useful.</param>
- /// <param name="issued">When this association was originally issued by the Provider.</param>
+ /// <param name="issued">The UTC time of when this association was originally issued by the Provider.</param>
protected Association(string handle, byte[] secret, TimeSpan totalLifeLength, DateTime issued) {
- ErrorUtilities.VerifyNonZeroLength(handle, "handle");
- ErrorUtilities.VerifyArgumentNotNull(secret, "secret");
+ Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(handle));
+ Contract.Requires<ArgumentNullException>(secret != null);
+ Contract.Requires<ArgumentOutOfRangeException>(totalLifeLength > TimeSpan.Zero);
+ Contract.Requires<ArgumentException>(issued.Kind == DateTimeKind.Utc);
+ Contract.Requires<ArgumentOutOfRangeException>(issued <= DateTime.UtcNow);
+ Contract.Ensures(this.TotalLifeLength == totalLifeLength);
this.Handle = handle;
this.SecretKey = secret;
@@ -85,7 +92,10 @@ namespace DotNetOpenAuth.OpenId {
/// Never negative (counter runs to zero).
/// </summary>
protected internal long SecondsTillExpiration {
- get { return Math.Max(0, (long)this.TimeTillExpiration.TotalSeconds); }
+ get {
+ Contract.Ensures(Contract.Result<long>() >= 0);
+ return Math.Max(0, (long)this.TimeTillExpiration.TotalSeconds);
+ }
}
/// <summary>
@@ -98,7 +108,10 @@ namespace DotNetOpenAuth.OpenId {
/// Gets the duration a secret key used for signing dumb client requests will be good for.
/// </summary>
protected static TimeSpan DumbSecretLifetime {
- get { return DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime; }
+ get {
+ Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero);
+ return DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime;
+ }
}
/// <summary>
@@ -113,7 +126,10 @@ namespace DotNetOpenAuth.OpenId {
/// Associations that are not likely to last the duration of a user login are not worth using at all.
/// </remarks>
private static TimeSpan MinimumUsefulAssociationLifetime {
- get { return DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime; }
+ get {
+ Contract.Ensures(Contract.Result<TimeSpan>() > TimeSpan.Zero);
+ return DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime;
+ }
}
/// <summary>
@@ -143,12 +159,10 @@ namespace DotNetOpenAuth.OpenId {
/// <see cref="IAssociationStore&lt;TKey&gt;.GetAssociation(TKey, SecuritySettings)"/> method.
/// </returns>
public static Association Deserialize(string handle, DateTime expires, byte[] privateData) {
- if (string.IsNullOrEmpty(handle)) {
- throw new ArgumentNullException("handle");
- }
- if (privateData == null) {
- throw new ArgumentNullException("privateData");
- }
+ Contract.Requires<ArgumentNullException>(!String.IsNullOrEmpty(handle));
+ Contract.Requires<ArgumentNullException>(privateData != null);
+ Contract.Ensures(Contract.Result<Association>() != null);
+
expires = expires.ToUniversalTimeSafe();
TimeSpan remainingLifeLength = expires - DateTime.UtcNow;
byte[] secret = privateData; // the whole of privateData is the secret key for now.
@@ -174,12 +188,16 @@ namespace DotNetOpenAuth.OpenId {
/// in this byte array, as they are useful for fast database lookup and are persisted separately.
/// </remarks>
public byte[] SerializePrivateData() {
+ Contract.Ensures(Contract.Result<byte[]>() != null);
+
// We may want to encrypt this secret using the machine.config private key,
// and add data regarding which Association derivative will need to be
// re-instantiated on deserialization.
// For now, we just send out the secret key. We can derive the type from the length later.
byte[] secretKeyCopy = new byte[this.SecretKey.Length];
- this.SecretKey.CopyTo(secretKeyCopy, 0);
+ if (this.SecretKey.Length > 0) {
+ this.SecretKey.CopyTo(secretKeyCopy, 0);
+ }
return secretKeyCopy;
}
@@ -253,6 +271,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="data">The data to sign. This data will not be changed (the signature is the return value).</param>
/// <returns>The calculated signature of the data.</returns>
protected internal byte[] Sign(byte[] data) {
+ Contract.Requires<ArgumentNullException>(data != null);
using (HashAlgorithm hasher = this.CreateHasher()) {
return hasher.ComputeHash(data);
}
@@ -263,5 +282,19 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
/// <returns>The hash algorithm used for message signing.</returns>
protected abstract HashAlgorithm CreateHasher();
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(!string.IsNullOrEmpty(this.Handle));
+ Contract.Invariant(this.TotalLifeLength > TimeSpan.Zero);
+ Contract.Invariant(this.SecretKey != null);
+ }
+#endif
}
}
diff --git a/src/DotNetOpenAuth/OpenId/AssociationContract.cs b/src/DotNetOpenAuth/OpenId/AssociationContract.cs
new file mode 100644
index 0000000..57f4fd9
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/AssociationContract.cs
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------
+// <copyright file="AssociationContract.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId {
+ using System;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
+ using System.IO;
+ using System.Security.Cryptography;
+ using System.Text;
+ using DotNetOpenAuth.Configuration;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// Code contract for the <see cref="Association"/> class.
+ /// </summary>
+ [ContractClassFor(typeof(Association))]
+ internal abstract class AssociationContract : Association {
+ /// <summary>
+ /// Prevents a default instance of the <see cref="AssociationContract"/> class from being created.
+ /// </summary>
+ private AssociationContract()
+ : base(null, null, TimeSpan.Zero, DateTime.Now) {
+ }
+
+ /// <summary>
+ /// Gets the length (in bits) of the hash this association creates when signing.
+ /// </summary>
+ public override int HashBitLength {
+ get {
+ Contract.Ensures(Contract.Result<int>() > 0);
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// The string to pass as the assoc_type value in the OpenID protocol.
+ /// </summary>
+ /// <param name="protocol">The protocol version of the message that the assoc_type value will be included in.</param>
+ /// <returns>
+ /// The value that should be used for the openid.assoc_type parameter.
+ /// </returns>
+ [Pure]
+ internal override string GetAssociationType(Protocol protocol) {
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Returns the specific hash algorithm used for message signing.
+ /// </summary>
+ /// <returns>
+ /// The hash algorithm used for message signing.
+ /// </returns>
+ [Pure]
+ protected override HashAlgorithm CreateHasher() {
+ Contract.Ensures(Contract.Result<HashAlgorithm>() != null);
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/Associations.cs b/src/DotNetOpenAuth/OpenId/Associations.cs
index fe2be42..4fd89c4 100644
--- a/src/DotNetOpenAuth/OpenId/Associations.cs
+++ b/src/DotNetOpenAuth/OpenId/Associations.cs
@@ -9,6 +9,8 @@ namespace DotNetOpenAuth.OpenId {
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
@@ -21,6 +23,7 @@ namespace DotNetOpenAuth.OpenId {
/// can break if the collection is changed by another thread during enumeration.
/// </remarks>
[DebuggerDisplay("Count = {assocs.Count}")]
+ [ContractVerification(true)]
internal class Associations {
/// <summary>
/// The lookup table where keys are the association handles and values are the associations themselves.
@@ -44,6 +47,8 @@ namespace DotNetOpenAuth.OpenId {
/// </remarks>
public IEnumerable<Association> Best {
get {
+ Contract.Ensures(Contract.Result<IEnumerable<Association>>() != null);
+
lock (this.associations) {
return this.associations.OrderByDescending(assoc => assoc.Issued);
}
@@ -55,11 +60,14 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
/// <param name="association">The association to add to the collection.</param>
public void Set(Association association) {
- ErrorUtilities.VerifyArgumentNotNull(association, "association");
+ Contract.Requires<ArgumentNullException>(association != null);
+ Contract.Ensures(this.Get(association.Handle) == association);
lock (this.associations) {
this.associations.Remove(association.Handle); // just in case one already exists.
this.associations.Add(association);
}
+
+ Contract.Assume(this.Get(association.Handle) == association);
}
/// <summary>
@@ -67,7 +75,10 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
/// <param name="handle">The handle to the required association.</param>
/// <returns>The desired association, or null if none with the given handle could be found.</returns>
+ [Pure]
public Association Get(string handle) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(handle));
+
lock (this.associations) {
if (this.associations.Contains(handle)) {
return this.associations[handle];
@@ -83,6 +94,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="handle">The handle to the required association.</param>
/// <returns>Whether an <see cref="Association"/> with the given handle was in the collection for removal.</returns>
public bool Remove(string handle) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(handle));
lock (this.associations) {
return this.associations.Remove(handle);
}
@@ -99,5 +111,17 @@ namespace DotNetOpenAuth.OpenId {
}
}
}
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(this.associations != null);
+ }
+#endif
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Behaviors/BehaviorStrings.sr.resx b/src/DotNetOpenAuth/OpenId/Behaviors/BehaviorStrings.sr.resx
new file mode 100644
index 0000000..2b1b911
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/Behaviors/BehaviorStrings.sr.resx
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="PpidProviderNotGiven" xml:space="preserve">
+ <value>Nijedan PPID provajder nije konfigurisan.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs b/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs
index 8f3b78f..23377c8 100644
--- a/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs
+++ b/src/DotNetOpenAuth/OpenId/Behaviors/GsaIcamProfile.cs
@@ -71,8 +71,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// incompatible with each other.
/// </remarks>
void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
-
if (securitySettings.MaximumHashBitLength < 256) {
securitySettings.MaximumHashBitLength = 256;
}
@@ -90,8 +88,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// </summary>
/// <param name="request">The request.</param>
void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(RelyingParty.IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
RelyingParty.AuthenticationRequest requestInternal = (RelyingParty.AuthenticationRequest)request;
ErrorUtilities.VerifyProtocol(string.Equals(request.Realm.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal) || DisableSslRequirement, BehaviorStrings.RealmMustBeHttps);
@@ -125,8 +121,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// </summary>
/// <param name="assertion">The positive assertion.</param>
void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) {
- ErrorUtilities.VerifyArgumentNotNull(assertion, "assertion");
-
PolicyResponse pape = assertion.GetExtension<PolicyResponse>();
ErrorUtilities.VerifyProtocol(
pape != null &&
@@ -175,8 +169,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// itself as that instance may be shared across many requests.
/// </remarks>
bool IProviderBehavior.OnIncomingRequest(IRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
var hostProcessedRequest = request as IHostProcessedRequest;
if (hostProcessedRequest != null) {
// Only apply our special policies if the RP requested it.
@@ -206,8 +198,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// from handling it; <c>false</c> to allow other behaviors to process this request.
/// </returns>
bool IProviderBehavior.OnOutgoingResponse(Provider.IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
bool result = false;
// Nothing to do for negative assertions.
diff --git a/src/DotNetOpenAuth/OpenId/Behaviors/PpidGeneration.cs b/src/DotNetOpenAuth/OpenId/Behaviors/PpidGeneration.cs
index f09e886..baef943 100644
--- a/src/DotNetOpenAuth/OpenId/Behaviors/PpidGeneration.cs
+++ b/src/DotNetOpenAuth/OpenId/Behaviors/PpidGeneration.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Behaviors {
using System;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
@@ -73,8 +74,6 @@ namespace DotNetOpenAuth.OpenId.Behaviors {
/// from handling it; <c>false</c> to allow other behaviors to process this request.
/// </returns>
bool IProviderBehavior.OnOutgoingResponse(IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
// Nothing to do for negative assertions.
if (!request.IsAuthenticated.Value) {
return false;
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/ExtensionsBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/ExtensionsBindingElement.cs
index fa6bfa4..6a0c0cf 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/ExtensionsBindingElement.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/ExtensionsBindingElement.cs
@@ -33,8 +33,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="extensionFactory">The extension factory.</param>
/// <param name="securitySettings">The security settings.</param>
internal ExtensionsBindingElement(IOpenIdExtensionFactory extensionFactory, SecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(extensionFactory, "extensionFactory");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(extensionFactory != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.ExtensionFactory = extensionFactory;
this.relyingPartySecuritySettings = securitySettings as RelyingPartySecuritySettings;
@@ -77,9 +77,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
/// </remarks>
public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
- ErrorUtilities.VerifyOperation(this.Channel != null, "Channel property has not been set.");
-
var extendableMessage = message as IProtocolMessageWithExtensions;
if (extendableMessage != null) {
Protocol protocol = Protocol.Lookup(message.Version);
@@ -226,8 +223,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// A dictionary of message parts, including only signed parts when appropriate.
/// </returns>
private IDictionary<string, string> GetExtensionsDictionary(IProtocolMessage message, bool ignoreUnsigned) {
- Contract.Requires(this.Channel != null);
- ErrorUtilities.VerifyOperation(this.Channel != null, "Channel property has not been set.");
+ Contract.Requires<InvalidOperationException>(this.Channel != null);
IndirectSignedResponse signedResponse = message as IndirectSignedResponse;
if (signedResponse != null && ignoreUnsigned) {
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs
index 03ba0f2..c363c11 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Text;
@@ -99,7 +100,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// be used.
/// </remarks>
public static byte[] GetBytes(IEnumerable<KeyValuePair<string, string>> keysAndValues) {
- ErrorUtilities.VerifyArgumentNotNull(keysAndValues, "keysAndValues");
+ Contract.Requires<ArgumentNullException>(keysAndValues != null);
MemoryStream ms = new MemoryStream();
using (StreamWriter sw = new StreamWriter(ms, textEncoding)) {
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
index 0f71ebc..aff535c 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
@@ -51,7 +51,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="securitySettings">The security settings to apply.</param>
internal OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings)
: this(associationStore, nonceStore, new OpenIdMessageFactory(), securitySettings, false) {
- Contract.Requires(securitySettings != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
}
/// <summary>
@@ -63,7 +63,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="securitySettings">The security settings.</param>
internal OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore, ProviderSecuritySettings securitySettings)
: this(associationStore, nonceStore, new OpenIdMessageFactory(), securitySettings) {
- Contract.Requires(securitySettings != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
}
/// <summary>
@@ -77,8 +77,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param>
private OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings, bool nonVerifying) :
this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings, nonVerifying)) {
- Contract.Requires(messageTypeProvider != null);
- Contract.Requires(securitySettings != null);
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ Contract.Requires<ArgumentException>(!nonVerifying || securitySettings is RelyingPartySecuritySettings);
}
/// <summary>
@@ -91,8 +92,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="securitySettings">The security settings.</param>
private OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) :
this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings, false)) {
- Contract.Requires(messageTypeProvider != null);
- Contract.Requires(securitySettings != null);
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
}
/// <summary>
@@ -103,7 +104,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="bindingElements">The binding elements to use in sending and receiving messages.</param>
private OpenIdChannel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements)
: base(messageTypeProvider, bindingElements) {
- Contract.Requires(messageTypeProvider != null);
+ Contract.Requires<ArgumentNullException>(messageTypeProvider != null);
// Customize the binding element order, since we play some tricks for higher
// security and backward compatibility with older OpenID versions.
@@ -253,8 +254,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// This method implements spec V1.0 section 5.3.
/// </remarks>
protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
-
var messageAccessor = this.MessageDescriptions.GetAccessor(response);
var fields = messageAccessor.Serialize();
byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields);
@@ -317,9 +316,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// </returns>
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Needed for code contracts.")]
private static IChannelBindingElement[] InitializeBindingElements<T>(IAssociationStore<T> associationStore, INonceStore nonceStore, SecuritySettings securitySettings, bool nonVerifying) {
- Contract.Requires(securitySettings != null);
- Contract.Requires(!nonVerifying || securitySettings is RelyingPartySecuritySettings);
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ Contract.Requires<ArgumentException>(!nonVerifying || securitySettings is RelyingPartySecuritySettings);
var rpSecuritySettings = securitySettings as RelyingPartySecuritySettings;
var opSecuritySettings = securitySettings as ProviderSecuritySettings;
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
index 31a2da5..1e5ea4c 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdMessageFactory.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.ChannelElements {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -30,9 +31,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// deserialize to. Null if the request isn't recognized as a valid protocol message.
/// </returns>
public IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(recipient, "recipient");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
RequestBase message = null;
// Discern the OpenID version of the message.
@@ -97,9 +95,6 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// deserialize to. Null if the request isn't recognized as a valid protocol message.
/// </returns>
public IDirectResponseProtocolMessage GetNewResponseMessage(IDirectedProtocolMessage request, IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
-
DirectResponseBase message = null;
// Discern the OpenID version of the message.
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToNonceBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToNonceBindingElement.cs
index 9c4c46d..9040404 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToNonceBindingElement.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToNonceBindingElement.cs
@@ -78,10 +78,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="nonceStore">The nonce store to use.</param>
/// <param name="securitySettings">The security settings of the RP.</param>
internal ReturnToNonceBindingElement(INonceStore nonceStore, RelyingPartySecuritySettings securitySettings) {
- Contract.Requires(nonceStore != null);
- Contract.Requires(securitySettings != null);
- ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(nonceStore != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.nonceStore = nonceStore;
this.securitySettings = securitySettings;
@@ -144,6 +142,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
SignedResponseRequest request = message as SignedResponseRequest;
if (this.UseRequestNonce(request)) {
request.AddReturnToArguments(NonceParameter, CustomNonce.NewNonce().Serialize());
+ request.SignReturnTo = true; // a nonce without a signature is completely pointless
return MessageProtections.ReplayProtection;
}
@@ -171,9 +170,13 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
IndirectSignedResponse response = message as IndirectSignedResponse;
if (this.UseRequestNonce(response)) {
+ if (!response.ReturnToParametersSignatureValidated) {
+ Logger.OpenId.Error("Incoming message is expected to have a nonce, but the return_to parameter is not signed.");
+ }
+
string nonceValue = response.GetReturnToArgument(NonceParameter);
ErrorUtilities.VerifyProtocol(
- nonceValue != null,
+ nonceValue != null && response.ReturnToParametersSignatureValidated,
this.securitySettings.RejectUnsolicitedAssertions ? OpenIdStrings.UnsolicitedAssertionsNotAllowed : OpenIdStrings.UnsolicitedAssertionsNotAllowedFrom1xOPs);
CustomNonce nonce = CustomNonce.Deserialize(nonceValue);
@@ -254,7 +257,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="value">The base64-encoded value of the nonce.</param>
/// <returns>The instantiated and initialized nonce.</returns>
internal static CustomNonce Deserialize(string value) {
- ErrorUtilities.VerifyNonZeroLength(value, "value");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
byte[] nonce = Convert.FromBase64String(value);
Contract.Assume(nonce != null);
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs
index a760c0d..438c496 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/ReturnToSignatureBindingElement.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+ using System.Diagnostics.Contracts;
using System.Security.Cryptography;
using System.Web;
using DotNetOpenAuth.Messaging;
@@ -52,7 +53,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="secretStore">The secret store from which to retrieve the secret used for signing.</param>
/// <param name="securitySettings">The security settings.</param>
internal ReturnToSignatureBindingElement(IAssociationStore<Uri> secretStore, RelyingPartySecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(secretStore, "secretStore");
+ Contract.Requires<ArgumentNullException>(secretStore != null);
this.secretManager = new PrivateSecretManager(securitySettings, secretStore);
}
@@ -94,7 +95,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// </remarks>
public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
SignedResponseRequest request = message as SignedResponseRequest;
- if (request != null && request.ReturnTo != null) {
+ if (request != null && request.ReturnTo != null && request.SignReturnTo) {
request.AddReturnToArguments(ReturnToSignatureHandleParameterName, this.secretManager.CurrentHandle);
request.AddReturnToArguments(ReturnToSignatureParameterName, this.GetReturnToSignature(request.ReturnTo));
@@ -161,7 +162,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// or other minor changes do not invalidate the signature.
/// </remarks>
private string GetReturnToSignature(Uri returnTo) {
- ErrorUtilities.VerifyArgumentNotNull(returnTo, "returnTo");
+ Contract.Requires<ArgumentNullException>(returnTo != null);
// Assemble the dictionary to sign, taking care to remove the signature itself
// in order to accurately reproduce the original signature (which of course didn't include
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs
index 6544d49..3f4a998 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/SigningBindingElement.cs
@@ -55,8 +55,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="associationStore">The association store used to look up the secrets needed for signing.</param>
/// <param name="securitySettings">The security settings.</param>
internal SigningBindingElement(IAssociationStore<AssociationRelyingPartyType> associationStore, ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(associationStore != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.opAssociations = associationStore;
this.opSecuritySettings = securitySettings;
@@ -190,7 +190,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <c>true</c> if the relying party is vulnerable; otherwise, <c>false</c>.
/// </returns>
private static bool IsRelyingPartyVulnerableToReplays(SignedResponseRequest request, IndirectSignedResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
// OpenID 2.0 includes replay protection as part of the protocol.
if (response.Version.Major >= 2) {
@@ -250,9 +250,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="association">The association to use to sign the message.</param>
/// <returns>The calculated signature of the method.</returns>
private string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association) {
- ErrorUtilities.VerifyArgumentNotNull(signedMessage, "signedMessage");
- ErrorUtilities.VerifyNonZeroLength(signedMessage.SignedParameterOrder, "signedMessage.SignedParameterOrder");
- ErrorUtilities.VerifyArgumentNotNull(association, "association");
+ Contract.Requires<ArgumentNullException>(signedMessage != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(signedMessage.SignedParameterOrder));
+ Contract.Requires<ArgumentNullException>(association != null);
// Prepare the parts to sign, taking care to replace an openid.mode value
// of check_authentication with its original id_res so the signature matches.
@@ -285,9 +285,8 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// the inclusion and order of message parts that will be signed.
/// </returns>
private string GetSignedParameterOrder(ITamperResistantOpenIdMessage signedMessage) {
- Contract.Requires(this.Channel != null);
- ErrorUtilities.VerifyArgumentNotNull(signedMessage, "signedMessage");
- ErrorUtilities.VerifyOperation(this.Channel != null, "Channel property has not been set.");
+ Contract.Requires<InvalidOperationException>(this.Channel != null);
+ Contract.Requires<ArgumentNullException>(signedMessage != null);
Protocol protocol = Protocol.Lookup(signedMessage.Version);
@@ -323,7 +322,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="signedMessage">The message to sign or verify.</param>
/// <returns>The association to use to sign or verify the message.</returns>
private Association GetAssociation(ITamperResistantOpenIdMessage signedMessage) {
- Contract.Requires(signedMessage != null);
+ Contract.Requires<ArgumentNullException>(signedMessage != null);
if (this.IsOnProvider) {
// We're on a Provider to either sign (smart/dumb) or verify a dumb signature.
diff --git a/src/DotNetOpenAuth/OpenId/DiffieHellmanUtilities.cs b/src/DotNetOpenAuth/OpenId/DiffieHellmanUtilities.cs
index e4fea46..249f1f3 100644
--- a/src/DotNetOpenAuth/OpenId/DiffieHellmanUtilities.cs
+++ b/src/DotNetOpenAuth/OpenId/DiffieHellmanUtilities.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
@@ -36,8 +37,8 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>The hashing algorithm to use.</returns>
/// <exception cref="ProtocolException">Thrown if no match could be found for the given <paramref name="sessionType"/>.</exception>
public static HashAlgorithm Lookup(Protocol protocol, string sessionType) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
- ErrorUtilities.VerifyArgumentNotNull(sessionType, "sessionType");
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ Contract.Requires<ArgumentNullException>(sessionType != null);
// We COULD use just First instead of FirstOrDefault, but we want to throw ProtocolException instead of InvalidOperationException.
DHSha match = diffieHellmanSessionTypes.FirstOrDefault(dhsha => String.Equals(dhsha.GetName(protocol), sessionType, StringComparison.Ordinal));
@@ -52,7 +53,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="hashSizeInBits">The hash size (in bits) that the DH session must have.</param>
/// <returns>The value to be used for the openid.session_type parameter, or null if no match was found.</returns>
internal static string GetNameForSize(Protocol protocol, int hashSizeInBits) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
+ Contract.Requires<ArgumentNullException>(protocol != null);
DHSha match = diffieHellmanSessionTypes.FirstOrDefault(dhsha => dhsha.Algorithm.HashSize == hashSizeInBits);
return match != null ? match.GetName(protocol) : null;
}
@@ -72,10 +73,10 @@ namespace DotNetOpenAuth.OpenId {
/// The secret itself if the encrypted version of the secret was given in <paramref name="remotePublicKey"/>.
/// </returns>
internal static byte[] SHAHashXorSecret(HashAlgorithm hasher, DiffieHellman dh, byte[] remotePublicKey, byte[] plainOrEncryptedSecret) {
- ErrorUtilities.VerifyArgumentNotNull(hasher, "hasher");
- ErrorUtilities.VerifyArgumentNotNull(dh, "dh");
- ErrorUtilities.VerifyArgumentNotNull(remotePublicKey, "remotePublicKey");
- ErrorUtilities.VerifyArgumentNotNull(plainOrEncryptedSecret, "plainOrEncryptedSecret");
+ Contract.Requires<ArgumentNullException>(hasher != null);
+ Contract.Requires<ArgumentNullException>(dh != null);
+ Contract.Requires<ArgumentNullException>(remotePublicKey != null);
+ Contract.Requires<ArgumentNullException>(plainOrEncryptedSecret != null);
byte[] sharedBlock = dh.DecryptKeyExchange(remotePublicKey);
byte[] sharedBlockHash = hasher.ComputeHash(EnsurePositive(sharedBlock));
@@ -101,7 +102,7 @@ namespace DotNetOpenAuth.OpenId {
/// This is to be consistent with OpenID spec section 4.2.
/// </remarks>
internal static byte[] EnsurePositive(byte[] inputBytes) {
- ErrorUtilities.VerifyArgumentNotNull(inputBytes, "inputBytes");
+ Contract.Requires<ArgumentNullException>(inputBytes != null);
if (inputBytes.Length == 0) {
throw new ArgumentException(MessagingStrings.UnexpectedEmptyArray, "inputBytes");
}
@@ -127,8 +128,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="algorithm">The hashing algorithm used in this particular Diffie-Hellman session type.</param>
/// <param name="getName">A function that will return the value of the openid.session_type parameter for a given version of OpenID.</param>
public DHSha(HashAlgorithm algorithm, Func<Protocol, string> getName) {
- ErrorUtilities.VerifyArgumentNotNull(algorithm, "algorithm");
- ErrorUtilities.VerifyArgumentNotNull(getName, "getName");
+ Contract.Requires<ArgumentNullException>(algorithm != null);
+ Contract.Requires<ArgumentNullException>(getName != null);
this.GetName = getName;
this.Algorithm = algorithm;
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs b/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
index e16f9a4..13f9907 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AliasManager.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -44,7 +45,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="typeUri">The type URI.</param>
/// <returns>The alias assigned to this type URI. Never null.</returns>
public string GetAlias(string typeUri) {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
string alias;
return this.typeUriToAliasMap.TryGetValue(typeUri, out alias) ? alias : this.AssignNewAlias(typeUri);
}
@@ -55,8 +56,8 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="alias">The alias.</param>
/// <param name="typeUri">The type URI.</param>
public void SetAlias(string alias, string typeUri) {
- ErrorUtilities.VerifyNonZeroLength(alias, "alias");
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(alias));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
this.aliasToTypeUriMap.Add(alias, typeUri);
this.typeUriToAliasMap.Add(typeUri, alias);
}
@@ -100,7 +101,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// </summary>
/// <param name="preferredTypeUriToAliases">A dictionary of type URI keys and alias values.</param>
public void SetPreferredAliasesWhereNotSet(IDictionary<string, string> preferredTypeUriToAliases) {
- ErrorUtilities.VerifyArgumentNotNull(preferredTypeUriToAliases, "preferredTypeUriToAliases");
+ Contract.Requires<ArgumentNullException>(preferredTypeUriToAliases != null);
foreach (var pair in preferredTypeUriToAliases) {
if (this.typeUriToAliasMap.ContainsKey(pair.Key)) {
@@ -138,7 +139,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="alias">The alias.</param>
/// <returns>The Type URI for the given alias, or null if none for that alias exist.</returns>
public string TryResolveAlias(string alias) {
- ErrorUtilities.VerifyNonZeroLength(alias, "alias");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(alias));
string typeUri = null;
this.aliasToTypeUriMap.TryGetValue(alias, out typeUri);
return typeUri;
@@ -150,7 +151,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="alias">The alias in question.</param>
/// <returns>True if the alias has already been assigned. False otherwise.</returns>
public bool IsAliasUsed(string alias) {
- ErrorUtilities.VerifyNonZeroLength(alias, "alias");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(alias));
return this.aliasToTypeUriMap.ContainsKey(alias);
}
@@ -162,7 +163,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <c>true</c> if the given type URI already has an alias assigned; <c>false</c> otherwise.
/// </returns>
public bool IsAliasAssignedTo(string typeUri) {
- ErrorUtilities.VerifyArgumentNotNull(typeUri, "typeUri");
+ Contract.Requires<ArgumentNullException>(typeUri != null);
return this.typeUriToAliasMap.ContainsKey(typeUri);
}
@@ -172,7 +173,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="typeUri">The type URI to assign a new alias to.</param>
/// <returns>The newly generated alias.</returns>
private string AssignNewAlias(string typeUri) {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
ErrorUtilities.VerifyInternal(!this.typeUriToAliasMap.ContainsKey(typeUri), "Oops! This type URI already has an alias!");
string alias = string.Format(CultureInfo.InvariantCulture, this.aliasFormat, this.typeUriToAliasMap.Count + 1);
this.typeUriToAliasMap.Add(typeUri, alias);
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs
index a3f64ab..2b947f7 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AXUtilities.cs
@@ -21,7 +21,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="collection">The attribute request collection.</param>
/// <param name="typeUri">The type URI of the required attribute.</param>
public static void AddRequired(this ICollection<AttributeRequest> collection, string typeUri) {
- ErrorUtilities.VerifyArgumentNotNull(collection, "collection");
+ Contract.Requires<ArgumentNullException>(collection != null);
collection.Add(new AttributeRequest(typeUri, true));
}
@@ -31,7 +31,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="collection">The attribute request collection.</param>
/// <param name="typeUri">The type URI of the requested attribute.</param>
public static void AddOptional(this ICollection<AttributeRequest> collection, string typeUri) {
- ErrorUtilities.VerifyArgumentNotNull(collection, "collection");
+ Contract.Requires<ArgumentNullException>(collection != null);
collection.Add(new AttributeRequest(typeUri, false));
}
@@ -43,8 +43,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="typeUri">The type URI of the attribute.</param>
/// <param name="values">The attribute values.</param>
public static void Add(this ICollection<AttributeValues> collection, string typeUri, params string[] values) {
- Contract.Requires(collection != null);
- ErrorUtilities.VerifyArgumentNotNull(collection, "collection");
+ Contract.Requires<ArgumentNullException>(collection != null);
collection.Add(new AttributeValues(typeUri, values));
}
@@ -54,8 +53,8 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="fields">The dictionary to fill with serialized attributes.</param>
/// <param name="attributes">The attributes.</param>
internal static void SerializeAttributes(IDictionary<string, string> fields, IEnumerable<AttributeValues> attributes) {
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
- ErrorUtilities.VerifyArgumentNotNull(attributes, "attributes");
+ Contract.Requires<ArgumentNullException>(fields != null);
+ Contract.Requires<ArgumentNullException>(attributes != null);
AliasManager aliasManager = new AliasManager();
foreach (var att in attributes) {
@@ -124,7 +123,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="fields">The data included in the extension message.</param>
/// <returns>The alias manager that provides lookup between aliases and type URIs.</returns>
private static AliasManager ParseAliases(IDictionary<string, string> fields) {
- ErrorUtilities.VerifyArgumentNotNull(fields, "fields");
+ Contract.Requires<ArgumentNullException>(fields != null);
AliasManager aliasManager = new AliasManager();
const string TypePrefix = "type.";
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
index e508233..358db9b 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeRequest.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
using System;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -34,7 +35,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// </summary>
/// <param name="typeUri">The unique TypeURI for that describes the attribute being sought.</param>
public AttributeRequest(string typeUri) {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
this.TypeUri = typeUri;
}
@@ -82,7 +83,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value > 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value > 0);
this.count = value;
}
}
@@ -97,8 +98,8 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// the <see cref="FetchResponse"/> object.
/// </returns>
public AttributeValues Respond(params string[] values) {
- ErrorUtilities.VerifyArgumentNotNull(values, "values");
- ErrorUtilities.VerifyArgument(values.Length <= this.Count, OpenIdStrings.AttributeTooManyValues, this.Count, this.TypeUri, values.Length);
+ Contract.Requires<ArgumentNullException>(values != null);
+ Contract.Requires<ArgumentException>(values.Length <= this.Count);
return new AttributeValues(this.TypeUri, values);
}
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
index e87e188..6466cda 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/AttributeExchange/AttributeValues.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -22,7 +23,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// <param name="typeUri">The TypeURI that uniquely identifies the attribute.</param>
/// <param name="values">The values for the attribute.</param>
public AttributeValues(string typeUri, params string[] values) {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
this.TypeUri = typeUri;
this.Values = (IList<string>)values ?? EmptyList<string>.Instance;
@@ -44,7 +45,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.AttributeExchange {
/// </summary>
/// <param name="typeUri">The TypeURI of the attribute whose values are being provided.</param>
internal AttributeValues(string typeUri) {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
this.TypeUri = typeUri;
this.Values = new List<string>(1);
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionArgumentsManager.cs b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionArgumentsManager.cs
index 5c4e978..27099e0 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionArgumentsManager.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionArgumentsManager.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -51,12 +52,19 @@ namespace DotNetOpenAuth.OpenId.Extensions {
private ExtensionArgumentsManager() { }
/// <summary>
+ /// Gets a value indicating whether the extensions are being read (as opposed to written).
+ /// </summary>
+ internal bool ReadMode {
+ get { return this.isReadMode; }
+ }
+
+ /// <summary>
/// Creates a <see cref="ExtensionArgumentsManager"/> instance to process incoming extensions.
/// </summary>
/// <param name="query">The parameters in the OpenID message.</param>
/// <returns>The newly created instance of <see cref="ExtensionArgumentsManager"/>.</returns>
public static ExtensionArgumentsManager CreateIncomingExtensions(IDictionary<string, string> query) {
- ErrorUtilities.VerifyArgumentNotNull(query, "query");
+ Contract.Requires<ArgumentNullException>(query != null);
var mgr = new ExtensionArgumentsManager();
mgr.protocol = Protocol.Detect(query);
mgr.isReadMode = true;
@@ -118,6 +126,31 @@ namespace DotNetOpenAuth.OpenId.Extensions {
}
/// <summary>
+ /// Adds query parameters for OpenID extensions to the request directed
+ /// at the OpenID provider.
+ /// </summary>
+ /// <param name="extensionTypeUri">The extension type URI.</param>
+ /// <param name="arguments">The arguments for this extension to add to the message.</param>
+ public void AddExtensionArguments(string extensionTypeUri, IDictionary<string, string> arguments) {
+ Contract.Requires<InvalidOperationException>(!this.ReadMode);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(extensionTypeUri));
+ Contract.Requires<ArgumentNullException>(arguments != null);
+ if (arguments.Count == 0) {
+ return;
+ }
+
+ IDictionary<string, string> extensionArgs;
+ if (!this.extensions.TryGetValue(extensionTypeUri, out extensionArgs)) {
+ this.extensions.Add(extensionTypeUri, extensionArgs = new Dictionary<string, string>(arguments.Count));
+ }
+
+ ErrorUtilities.VerifyProtocol(extensionArgs.Count == 0, OpenIdStrings.ExtensionAlreadyAddedWithSameTypeURI, extensionTypeUri);
+ foreach (var pair in arguments) {
+ extensionArgs.Add(pair.Key, pair.Value);
+ }
+ }
+
+ /// <summary>
/// Gets the actual arguments to add to a querystring or other response,
/// where type URI, alias, and actual key/values are all defined.
/// </summary>
@@ -126,10 +159,8 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// This should be <c>true</c> for all but direct response messages.
/// </param>
/// <returns>A dictionary of key=value pairs to add to the message to carry the extension.</returns>
- public IDictionary<string, string> GetArgumentsToSend(bool includeOpenIdPrefix) {
- if (this.isReadMode) {
- throw new InvalidOperationException();
- }
+ internal IDictionary<string, string> GetArgumentsToSend(bool includeOpenIdPrefix) {
+ Contract.Requires<InvalidOperationException>(!this.ReadMode);
Dictionary<string, string> args = new Dictionary<string, string>();
foreach (var typeUriAndExtension in this.extensions) {
string typeUri = typeUriAndExtension.Key;
@@ -155,44 +186,15 @@ namespace DotNetOpenAuth.OpenId.Extensions {
}
/// <summary>
- /// Adds query parameters for OpenID extensions to the request directed
- /// at the OpenID provider.
- /// </summary>
- /// <param name="extensionTypeUri">The extension type URI.</param>
- /// <param name="arguments">The arguments for this extension to add to the message.</param>
- public void AddExtensionArguments(string extensionTypeUri, IDictionary<string, string> arguments) {
- if (this.isReadMode) {
- throw new InvalidOperationException();
- }
- ErrorUtilities.VerifyNonZeroLength(extensionTypeUri, "extensionTypeUri");
- ErrorUtilities.VerifyArgumentNotNull(arguments, "arguments");
- if (arguments.Count == 0) {
- return;
- }
-
- IDictionary<string, string> extensionArgs;
- if (!this.extensions.TryGetValue(extensionTypeUri, out extensionArgs)) {
- this.extensions.Add(extensionTypeUri, extensionArgs = new Dictionary<string, string>(arguments.Count));
- }
-
- ErrorUtilities.VerifyProtocol(extensionArgs.Count == 0, OpenIdStrings.ExtensionAlreadyAddedWithSameTypeURI, extensionTypeUri);
- foreach (var pair in arguments) {
- extensionArgs.Add(pair.Key, pair.Value);
- }
- }
-
- /// <summary>
/// Gets the fields carried by a given OpenId extension.
/// </summary>
/// <param name="extensionTypeUri">The type URI of the extension whose fields are being queried for.</param>
/// <returns>
/// The fields included in the given extension, or null if the extension is not present.
/// </returns>
- public IDictionary<string, string> GetExtensionArguments(string extensionTypeUri) {
- ErrorUtilities.VerifyNonZeroLength(extensionTypeUri, "extensionTypeUri");
- if (!this.isReadMode) {
- throw new InvalidOperationException();
- }
+ internal IDictionary<string, string> GetExtensionArguments(string extensionTypeUri) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(extensionTypeUri));
+ Contract.Requires<InvalidOperationException>(this.ReadMode);
IDictionary<string, string> extensionArgs;
this.extensions.TryGetValue(extensionTypeUri, out extensionArgs);
@@ -204,7 +206,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// </summary>
/// <param name="extensionTypeUri">The extension Type URI in question.</param>
/// <returns><c>true</c> if this extension is present; <c>false</c> otherwise.</returns>
- public bool ContainsExtension(string extensionTypeUri) {
+ internal bool ContainsExtension(string extensionTypeUri) {
return this.extensions.ContainsKey(extensionTypeUri);
}
@@ -212,7 +214,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// Gets the type URIs of all discovered extensions in the message.
/// </summary>
/// <returns>A sequence of the type URIs.</returns>
- public IEnumerable<string> GetExtensionTypeUris() {
+ internal IEnumerable<string> GetExtensionTypeUris() {
return this.extensions.Keys;
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs
index 36358a7..cd7575e 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/ExtensionsInteropHelper.cs
@@ -42,8 +42,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// </remarks>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")]
public static void SpreadSregToAX(this RelyingParty.IAuthenticationRequest request, AXAttributeFormats attributeFormats) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
var req = (RelyingParty.AuthenticationRequest)request;
var sreg = req.AppliedExtensions.OfType<ClaimsRequest>().SingleOrDefault();
@@ -99,8 +98,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// Never <c>null</c>.</returns>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sreg", Justification = "Abbreviation")]
public static ClaimsResponse UnifyExtensionsAsSreg(this RelyingParty.IAuthenticationResponse response, bool allowUnsigned) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
var resp = (RelyingParty.IAuthenticationResponse)response;
var sreg = allowUnsigned ? resp.GetUntrustedExtension<ClaimsResponse>() : resp.GetExtension<ClaimsResponse>();
@@ -140,8 +138,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// or a fabricated one based on the Attribute Exchange extension if found,
/// or <c>null</c> if no attribute extension request is found.</returns>
internal static ClaimsRequest UnifyExtensionsAsSreg(this Provider.IHostProcessedRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
var req = (Provider.AuthenticationRequest)request;
var sreg = req.GetExtension<ClaimsRequest>();
@@ -258,8 +255,8 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="typeUri">The type URI of the attribute in axschema.org format.</param>
/// <returns>The demand level for the attribute.</returns>
private static DemandLevel GetDemandLevelFor(FetchRequest ax, string typeUri) {
- Contract.Requires(ax != null);
- Contract.Requires(!String.IsNullOrEmpty(typeUri));
+ Contract.Requires<ArgumentNullException>(ax != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
foreach (AXAttributeFormats format in ForEachFormat(AXAttributeFormats.All)) {
string typeUriInFormat = TransformAXFormat(typeUri, format);
@@ -278,7 +275,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="attributeFormat">The attribute formats the RP will try if this discovery fails.</param>
/// <returns>The AX format(s) to use based on the Provider's advertised AX support.</returns>
private static bool TryDetectOPAttributeFormat(RelyingParty.IAuthenticationRequest request, out AXAttributeFormats attributeFormat) {
- Contract.Requires(request != null);
+ Contract.Requires<ArgumentNullException>(request != null);
var provider = (RelyingParty.ServiceEndpoint)request.Provider;
attributeFormat = DetectAXFormat(provider.ProviderDescription.Capabilities);
return attributeFormat != AXAttributeFormats.None;
@@ -290,7 +287,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="typeURIs">The type URIs to scan for recognized formats.</param>
/// <returns>The first AX type URI format recognized in the list.</returns>
private static AXAttributeFormats DetectAXFormat(IEnumerable<string> typeURIs) {
- Contract.Requires(typeURIs != null);
+ Contract.Requires<ArgumentNullException>(typeURIs != null);
if (typeURIs.Any(uri => uri.StartsWith("http://axschema.org/", StringComparison.Ordinal))) {
return AXAttributeFormats.AXSchemaOrg;
@@ -314,7 +311,7 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="targetFormat">The target format. Only one flag should be set.</param>
/// <returns>The AX attribute type URI in the target format.</returns>
private static string TransformAXFormat(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) {
- Contract.Requires(!String.IsNullOrEmpty(axSchemaOrgFormatTypeUri));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(axSchemaOrgFormatTypeUri));
switch (targetFormat) {
case AXAttributeFormats.AXSchemaOrg:
@@ -355,8 +352,8 @@ namespace DotNetOpenAuth.OpenId.Extensions {
/// <param name="axSchemaOrgFormatAttribute">The attribute in axschema.org format.</param>
/// <param name="demandLevel">The demand level.</param>
private static void FetchAttribute(FetchRequest ax, AXAttributeFormats format, string axSchemaOrgFormatAttribute, DemandLevel demandLevel) {
- Contract.Requires(ax != null);
- Contract.Requires(!String.IsNullOrEmpty(axSchemaOrgFormatAttribute));
+ Contract.Requires<ArgumentNullException>(ax != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(axSchemaOrgFormatAttribute));
string typeUri = TransformAXFormat(axSchemaOrgFormatAttribute, format);
if (!ax.Attributes.Contains(typeUri)) {
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PapeUtilities.cs b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PapeUtilities.cs
index 0f365ac..eeaea31 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PapeUtilities.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/ProviderAuthenticationPolicy/PapeUtilities.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Text;
@@ -45,7 +46,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy {
/// <returns>The concatenated string of elements.</returns>
/// <exception cref="FormatException">Thrown if any element in the sequence includes a space.</exception>
internal static string ConcatenateListOfElements(IEnumerable<string> values) {
- ErrorUtilities.VerifyArgumentNotNull(values, "values");
+ Contract.Requires<ArgumentNullException>(values != null);
StringBuilder valuesList = new StringBuilder();
foreach (string value in values.Distinct()) {
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
index 10622bf..f775492 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsRequest.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -58,7 +59,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
/// <param name="typeUri">The type URI this extension was recognized by in the OpenID message.</param>
internal ClaimsRequest(string typeUri)
: this() {
- ErrorUtilities.VerifyNonZeroLength(typeUri, "typeUri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUri));
this.typeUriDeserializedFrom = typeUri;
}
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
index a58c754..ed99243 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/SimpleRegistration/ClaimsResponse.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Net.Mail;
using System.Text;
@@ -69,7 +70,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
/// </param>
internal ClaimsResponse(string typeUriToUse)
: base(new Version(1, 0), typeUriToUse, EmptyList<string>.Instance) {
- ErrorUtilities.VerifyNonZeroLength(typeUriToUse, "typeUriToUse");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(typeUriToUse));
}
/// <summary>
@@ -316,7 +317,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.SimpleRegistration {
sreg[Constants.language] = this.Language;
sreg[Constants.timezone] = this.TimeZone;
- return MessagingUtilities.CreateJsonObject(sreg);
+ return MessagingUtilities.CreateJsonObject(sreg, false);
}
#endregion
diff --git a/src/DotNetOpenAuth/OpenId/Extensions/UI/UIUtilities.cs b/src/DotNetOpenAuth/OpenId/Extensions/UI/UIUtilities.cs
index 088404b..cee6882 100644
--- a/src/DotNetOpenAuth/OpenId/Extensions/UI/UIUtilities.cs
+++ b/src/DotNetOpenAuth/OpenId/Extensions/UI/UIUtilities.cs
@@ -18,7 +18,7 @@ namespace DotNetOpenAuth.OpenId.Extensions.UI {
/// <summary>
/// The required width of the popup window the relying party creates for the provider.
/// </summary>
- public const int PopupWidth = 450;
+ public const int PopupWidth = 500; // UI extension calls for 450px, but Yahoo needs 500px
/// <summary>
/// The required height of the popup window the relying party creates for the provider.
@@ -34,9 +34,9 @@ namespace DotNetOpenAuth.OpenId.Extensions.UI {
/// <param name="windowName">The name to assign to the popup window.</param>
/// <returns>A string starting with 'window.open' and forming just that one method call.</returns>
internal static string GetWindowPopupScript(OpenIdRelyingParty relyingParty, IAuthenticationRequest request, string windowName) {
- Contract.Requires(relyingParty != null);
- Contract.Requires(request != null);
- Contract.Requires(!string.IsNullOrEmpty(windowName));
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(windowName));
Uri popupUrl = request.RedirectingResponse.GetDirectUriRequest(relyingParty.Channel);
diff --git a/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs b/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs
index 4c31100..e0317db 100644
--- a/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs
+++ b/src/DotNetOpenAuth/OpenId/HmacShaAssociation.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
@@ -19,6 +20,7 @@ namespace DotNetOpenAuth.OpenId {
/// <summary>
/// An association that uses the HMAC-SHA family of algorithms for message signing.
/// </summary>
+ [ContractVerification(true)]
internal class HmacShaAssociation : Association {
/// <summary>
/// The default lifetime of a shared association when no lifetime is given
@@ -66,9 +68,11 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="totalLifeLength">The time duration the association will be good for.</param>
private HmacShaAssociation(HmacSha typeIdentity, string handle, byte[] secret, TimeSpan totalLifeLength)
: base(handle, secret, totalLifeLength, DateTime.UtcNow) {
- ErrorUtilities.VerifyArgumentNotNull(typeIdentity, "typeIdentity");
- ErrorUtilities.VerifyNonZeroLength(handle, "handle");
- ErrorUtilities.VerifyArgumentNotNull(secret, "secret");
+ Contract.Requires<ArgumentNullException>(typeIdentity != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle));
+ Contract.Requires<ArgumentNullException>(secret != null);
+ Contract.Requires<ArgumentOutOfRangeException>(totalLifeLength > TimeSpan.Zero);
+ Contract.Ensures(this.TotalLifeLength == totalLifeLength);
ErrorUtilities.VerifyProtocol(secret.Length == typeIdentity.SecretLength, OpenIdStrings.AssociationSecretAndTypeLengthMismatch, secret.Length, typeIdentity.GetAssociationType(Protocol.Default));
this.typeIdentity = typeIdentity;
@@ -94,9 +98,10 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="totalLifeLength">How long the association will be good for.</param>
/// <returns>The newly created association.</returns>
public static HmacShaAssociation Create(Protocol protocol, string associationType, string handle, byte[] secret, TimeSpan totalLifeLength) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
- ErrorUtilities.VerifyNonZeroLength(associationType, "associationType");
- ErrorUtilities.VerifyArgumentNotNull(secret, "secret");
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType));
+ Contract.Requires<ArgumentNullException>(secret != null);
+ Contract.Ensures(Contract.Result<HmacShaAssociation>() != null);
HmacSha match = hmacShaAssociationTypes.FirstOrDefault(sha => String.Equals(sha.GetAssociationType(protocol), associationType, StringComparison.Ordinal));
ErrorUtilities.VerifyProtocol(match != null, OpenIdStrings.NoAssociationTypeFoundByName, associationType);
@@ -111,8 +116,9 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="totalLifeLength">Total lifetime.</param>
/// <returns>The newly created association.</returns>
public static HmacShaAssociation Create(string handle, byte[] secret, TimeSpan totalLifeLength) {
- ErrorUtilities.VerifyNonZeroLength(handle, "handle");
- ErrorUtilities.VerifyArgumentNotNull(secret, "secret");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle));
+ Contract.Requires<ArgumentNullException>(secret != null);
+ Contract.Ensures(Contract.Result<HmacShaAssociation>() != null);
HmacSha shaType = hmacShaAssociationTypes.FirstOrDefault(sha => sha.SecretLength == secret.Length);
ErrorUtilities.VerifyProtocol(shaType != null, OpenIdStrings.NoAssociationTypeFoundByLength, secret.Length);
@@ -145,9 +151,10 @@ namespace DotNetOpenAuth.OpenId {
/// The new association is NOT automatically put into an association store. This must be done by the caller.
/// </remarks>
internal static HmacShaAssociation Create(Protocol protocol, string associationType, AssociationRelyingPartyType associationUse, ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
- ErrorUtilities.VerifyNonZeroLength(associationType, "associationType");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType));
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ Contract.Ensures(Contract.Result<HmacShaAssociation>() != null);
int secretLength = GetSecretLength(protocol, associationType);
@@ -173,6 +180,9 @@ namespace DotNetOpenAuth.OpenId {
lifetime = DumbSecretLifetime;
}
+ Contract.Assert(protocol != null); // All the way up to the method call, the condition holds, yet we get a Requires failure next
+ Contract.Assert(secret != null);
+ Contract.Assert(!String.IsNullOrEmpty(associationType));
return Create(protocol, associationType, handle, secret, lifetime);
}
@@ -191,8 +201,8 @@ namespace DotNetOpenAuth.OpenId {
/// True if a qualifying association could be found; false otherwise.
/// </returns>
internal static bool TryFindBestAssociation(Protocol protocol, bool highSecurityIsBetter, SecuritySettings securityRequirements, bool requireMatchingDHSessionType, out string associationType, out string sessionType) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
- ErrorUtilities.VerifyArgumentNotNull(securityRequirements, "securityRequirements");
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ Contract.Requires<ArgumentNullException>(securityRequirements != null);
associationType = null;
sessionType = null;
@@ -232,9 +242,9 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the named association and session types are compatible; otherwise, <c>false</c>.
/// </returns>
internal static bool IsDHSessionCompatible(Protocol protocol, string associationType, string sessionType) {
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
- ErrorUtilities.VerifyNonZeroLength(associationType, "associationType");
- ErrorUtilities.VerifyArgumentNotNull(sessionType, "sessionType");
+ Contract.Requires<ArgumentNullException>(protocol != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType));
+ Contract.Requires<ArgumentNullException>(sessionType != null);
// All association types can work when no DH session is used at all.
if (string.Equals(sessionType, protocol.Args.SessionType.NoEncryption, StringComparison.Ordinal)) {
@@ -254,6 +264,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>
/// The value that should be used for the openid.assoc_type parameter.
/// </returns>
+ [Pure]
internal override string GetAssociationType(Protocol protocol) {
return this.typeIdentity.GetAssociationType(protocol);
}
@@ -264,8 +275,11 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>
/// The hash algorithm used for message signing.
/// </returns>
+ [Pure]
protected override HashAlgorithm CreateHasher() {
- return this.typeIdentity.CreateHasher(SecretKey);
+ var result = this.typeIdentity.CreateHasher(SecretKey);
+ Contract.Assume(result != null);
+ return result;
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/IAssociationStore.cs b/src/DotNetOpenAuth/OpenId/IAssociationStore.cs
index 2376b0d..71d8652 100644
--- a/src/DotNetOpenAuth/OpenId/IAssociationStore.cs
+++ b/src/DotNetOpenAuth/OpenId/IAssociationStore.cs
@@ -5,6 +5,9 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId {
+ using System;
+ using System.Diagnostics.Contracts;
+
/// <summary>
/// An enumeration that can specify how a given <see cref="Association"/> is used.
/// </summary>
@@ -33,6 +36,7 @@ namespace DotNetOpenAuth.OpenId {
/// <see cref="System.Uri"/> for consumers (to distinguish associations across servers) or
/// <see cref="AssociationRelyingPartyType"/> for providers (to distinguish dumb and smart client associations).
/// </typeparam>
+ ////[ContractClass(typeof(IAssociationStoreContract<>))]
public interface IAssociationStore<TKey> {
/// <summary>
/// Saves an <see cref="Association"/> for later recall.
@@ -92,4 +96,99 @@ namespace DotNetOpenAuth.OpenId {
/// </remarks>
void ClearExpiredAssociations();
}
+
+ // For some odd reason, having this next class causes our test project to fail to build with this error:
+ // Error 42 Method 'StoreAssociation' in type 'DotNetOpenAuth.OpenId.IAssociationStoreContract_Accessor`1' from assembly 'DotNetOpenAuth_Accessor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation. DotNetOpenAuth.Test
+ /////// <summary>
+ /////// Code Contract for the <see cref="IAssociationStore&lt;TKey&gt;"/> class.
+ /////// </summary>
+ /////// <typeparam name="TKey">The type of the key.</typeparam>
+ ////[ContractClassFor(typeof(IAssociationStore<>))]
+ ////internal abstract class IAssociationStoreContract<TKey> : IAssociationStore<TKey> {
+ //// #region IAssociationStore<TKey> Members
+
+ //// /// <summary>
+ //// /// Saves an <see cref="Association"/> for later recall.
+ //// /// </summary>
+ //// /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for providers).</param>
+ //// /// <param name="association">The association to store.</param>
+ //// /// <remarks>
+ //// /// TODO: what should implementations do on association handle conflict?
+ //// /// </remarks>
+ //// void IAssociationStore<TKey>.StoreAssociation(TKey distinguishingFactor, Association association) {
+ //// Contract.Requires<ArgumentNullException>(distinguishingFactor != null);
+ //// Contract.Requires<ArgumentNullException>(association != null);
+ //// throw new NotImplementedException();
+ //// }
+
+ //// /// <summary>
+ //// /// Gets the best association (the one with the longest remaining life) for a given key.
+ //// /// </summary>
+ //// /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
+ //// /// <param name="securityRequirements">The security requirements that the returned association must meet.</param>
+ //// /// <returns>
+ //// /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key.
+ //// /// </returns>
+ //// /// <remarks>
+ //// /// In the event that multiple associations exist for the given
+ //// /// <paramref name="distinguishingFactor"/>, it is important for the
+ //// /// implementation for this method to use the <paramref name="securityRequirements"/>
+ //// /// to pick the best (highest grade or longest living as the host's policy may dictate)
+ //// /// association that fits the security requirements.
+ //// /// Associations that are returned that do not meet the security requirements will be
+ //// /// ignored and a new association created.
+ //// /// </remarks>
+ //// Association IAssociationStore<TKey>.GetAssociation(TKey distinguishingFactor, SecuritySettings securityRequirements) {
+ //// Contract.Requires<ArgumentNullException>(distinguishingFactor != null);
+ //// Contract.Requires<ArgumentNullException>(securityRequirements != null);
+ //// throw new NotImplementedException();
+ //// }
+
+ //// /// <summary>
+ //// /// Gets the association for a given key and handle.
+ //// /// </summary>
+ //// /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
+ //// /// <param name="handle">The handle of the specific association that must be recalled.</param>
+ //// /// <returns>
+ //// /// The requested association, or null if no unexpired <see cref="Association"/>s exist for the given key and handle.
+ //// /// </returns>
+ //// Association IAssociationStore<TKey>.GetAssociation(TKey distinguishingFactor, string handle) {
+ //// Contract.Requires<ArgumentNullException>(distinguishingFactor != null);
+ //// Contract.Requires(!String.IsNullOrEmpty(handle));
+ //// throw new NotImplementedException();
+ //// }
+
+ //// /// <summary>
+ //// /// Removes a specified handle that may exist in the store.
+ //// /// </summary>
+ //// /// <param name="distinguishingFactor">The Uri (for relying parties) or Smart/Dumb (for Providers).</param>
+ //// /// <param name="handle">The handle of the specific association that must be deleted.</param>
+ //// /// <returns>
+ //// /// True if the association existed in this store previous to this call.
+ //// /// </returns>
+ //// /// <remarks>
+ //// /// No exception should be thrown if the association does not exist in the store
+ //// /// before this call.
+ //// /// </remarks>
+ //// bool IAssociationStore<TKey>.RemoveAssociation(TKey distinguishingFactor, string handle) {
+ //// Contract.Requires<ArgumentNullException>(distinguishingFactor != null);
+ //// Contract.Requires(!String.IsNullOrEmpty(handle));
+ //// throw new NotImplementedException();
+ //// }
+
+ //// /// <summary>
+ //// /// Clears all expired associations from the store.
+ //// /// </summary>
+ //// /// <remarks>
+ //// /// If another algorithm is in place to periodically clear out expired associations,
+ //// /// this method call may be ignored.
+ //// /// This should be done frequently enough to avoid a memory leak, but sparingly enough
+ //// /// to not be a performance drain.
+ //// /// </remarks>
+ //// void IAssociationStore<TKey>.ClearExpiredAssociations() {
+ //// throw new NotImplementedException();
+ //// }
+
+ //// #endregion
+ ////}
}
diff --git a/src/DotNetOpenAuth/OpenId/Identifier.cs b/src/DotNetOpenAuth/OpenId/Identifier.cs
index 6e71b0a..e32251b 100644
--- a/src/DotNetOpenAuth/OpenId/Identifier.cs
+++ b/src/DotNetOpenAuth/OpenId/Identifier.cs
@@ -24,15 +24,21 @@ namespace DotNetOpenAuth.OpenId {
/// <summary>
/// Initializes a new instance of the <see cref="Identifier"/> class.
/// </summary>
- /// <param name="isDiscoverySecureEndToEnd">
- /// Whether the derived class is prepared to guarantee end-to-end discovery
- /// and initial redirect for authentication is performed using SSL.
- /// </param>
- protected Identifier(bool isDiscoverySecureEndToEnd) {
+ /// <param name="originalString">The original string before any normalization.</param>
+ /// <param name="isDiscoverySecureEndToEnd">Whether the derived class is prepared to guarantee end-to-end discovery
+ /// and initial redirect for authentication is performed using SSL.</param>
+ [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "string", Justification = "Emphasis on string instead of the strong-typed Identifier.")]
+ protected Identifier(string originalString, bool isDiscoverySecureEndToEnd) {
+ this.OriginalString = originalString;
this.IsDiscoverySecureEndToEnd = isDiscoverySecureEndToEnd;
}
/// <summary>
+ /// Gets the original string that was normalized to create this Identifier.
+ /// </summary>
+ public string OriginalString { get; private set; }
+
+ /// <summary>
/// Gets or sets a value indicating whether <see cref="Identifier"/> instances are considered equal
/// based solely on their string reprsentations.
/// </summary>
@@ -61,7 +67,7 @@ namespace DotNetOpenAuth.OpenId {
[SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Our named alternate is Parse.")]
[DebuggerStepThrough]
public static implicit operator Identifier(string identifier) {
- Contract.Requires(identifier == null || identifier.Length > 0);
+ Contract.Requires<ArgumentException>(identifier == null || identifier.Length > 0);
if (identifier == null) {
return null;
}
@@ -106,8 +112,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>An <see cref="Identifier"/> instance for the given value.</returns>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")]
public static Identifier Parse(string identifier) {
- Contract.Requires((identifier != null && identifier.Length > 0) || !string.IsNullOrEmpty(identifier));
- ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(identifier));
if (XriIdentifier.IsValidXri(identifier)) {
return new XriIdentifier(identifier);
} else {
@@ -147,7 +152,7 @@ namespace DotNetOpenAuth.OpenId {
/// </returns>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Some of these identifiers are not properly formatted to be Uris at this stage.")]
public static bool IsValid(string identifier) {
- Contract.Requires(!string.IsNullOrEmpty(identifier));
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(identifier));
return XriIdentifier.IsValidXri(identifier) || UriIdentifier.IsValidUri(identifier);
}
@@ -208,6 +213,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>
/// An initialized structure containing the discovered provider endpoint information.
/// </returns>
+ [Pure]
internal abstract IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler);
/// <summary>
@@ -217,6 +223,7 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
/// <returns>A new <see cref="Identifier"/> instance if there was a
/// fragment to remove, otherwise this same instance..</returns>
+ [Pure]
internal abstract Identifier TrimFragment();
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/IdentifierContract.cs b/src/DotNetOpenAuth/OpenId/IdentifierContract.cs
index 1758f06..498ae45 100644
--- a/src/DotNetOpenAuth/OpenId/IdentifierContract.cs
+++ b/src/DotNetOpenAuth/OpenId/IdentifierContract.cs
@@ -20,7 +20,7 @@ namespace DotNetOpenAuth.OpenId {
/// Prevents a default instance of the IdentifierContract class from being created.
/// </summary>
private IdentifierContract()
- : base(false) {
+ : base(null, false) {
}
/// <summary>
@@ -31,7 +31,7 @@ namespace DotNetOpenAuth.OpenId {
/// An initialized structure containing the discovered provider endpoint information.
/// </returns>
internal override IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler) {
- Contract.Requires(requestHandler != null);
+ Contract.Requires<ArgumentNullException>(requestHandler != null);
Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
index a5926d9..6319c02 100644
--- a/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
+++ b/src/DotNetOpenAuth/OpenId/Interop/AuthenticationResponseShim.cs
@@ -30,8 +30,7 @@ namespace DotNetOpenAuth.OpenId.Interop {
/// </summary>
/// <param name="response">The response.</param>
internal AuthenticationResponseShim(IAuthenticationResponse response) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
var claimsResponse = this.response.GetExtension<ClaimsResponse>();
diff --git a/src/DotNetOpenAuth/OpenId/Interop/ClaimsResponseShim.cs b/src/DotNetOpenAuth/OpenId/Interop/ClaimsResponseShim.cs
index ef5e79d..689777b 100644
--- a/src/DotNetOpenAuth/OpenId/Interop/ClaimsResponseShim.cs
+++ b/src/DotNetOpenAuth/OpenId/Interop/ClaimsResponseShim.cs
@@ -31,8 +31,7 @@ namespace DotNetOpenAuth.OpenId.Interop {
/// <param name="response">The Simple Registration response to wrap.</param>
internal ClaimsResponseShim(ClaimsResponse response)
{
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs
index 99e413d..ccfb1b8 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.OpenId.Messages {
using System;
+ using System.Diagnostics.Contracts;
using System.Security.Cryptography;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Reflection;
@@ -51,7 +52,6 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// The resulting association is <i>not</i> added to the association store and must be done by the caller.
/// </remarks>
protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
var diffieHellmanRequest = request as AssociateDiffieHellmanRequest;
ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, "request");
@@ -73,10 +73,8 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// but the resulting association is <i>not</i> added to the association store and must be done by the caller.
/// </remarks>
protected override Association CreateAssociationAtProvider(AssociateRequest request, ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
var diffieHellmanRequest = request as AssociateDiffieHellmanRequest;
- ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, "request");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ ErrorUtilities.VerifyInternal(diffieHellmanRequest != null, "Expected a DH request type.");
this.SessionType = this.SessionType ?? request.SessionType;
diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs
index 6a5c0a8..5215022 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateRequest.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -76,8 +77,8 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// and the provider OpenID version.
/// </returns>
internal static AssociateRequest Create(SecuritySettings securityRequirements, ProviderEndpointDescription provider) {
- ErrorUtilities.VerifyArgumentNotNull(securityRequirements, "securityRequirements");
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(securityRequirements != null);
+ Contract.Requires<ArgumentNullException>(provider != null);
// Apply our knowledge of the endpoint's transport, OpenID version, and
// security requirements to decide the best association.
@@ -106,10 +107,10 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// and the provider OpenID version.
/// </returns>
internal static AssociateRequest Create(SecuritySettings securityRequirements, ProviderEndpointDescription provider, string associationType, string sessionType) {
- ErrorUtilities.VerifyArgumentNotNull(securityRequirements, "securityRequirements");
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
- ErrorUtilities.VerifyNonZeroLength(associationType, "associationType");
- ErrorUtilities.VerifyArgumentNotNull(sessionType, "sessionType");
+ Contract.Requires<ArgumentNullException>(securityRequirements != null);
+ Contract.Requires<ArgumentNullException>(provider != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(associationType));
+ Contract.Requires<ArgumentNullException>(sessionType != null);
bool unencryptedAllowed = provider.Endpoint.IsTransportSecure();
if (unencryptedAllowed) {
@@ -140,8 +141,8 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// Failed association response messages will derive from <see cref="AssociateUnsuccessfulResponse"/>.</para>
/// </remarks>
internal IProtocolMessage CreateResponse(IAssociationStore<AssociationRelyingPartyType> associationStore, ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(associationStore != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
IProtocolMessage response;
if (securitySettings.IsAssociationInPermittedRange(Protocol, this.AssociationType) &&
@@ -184,7 +185,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="securitySettings">The security settings that apply to this Provider.</param>
/// <returns>The response to send to the Relying Party.</returns>
private AssociateUnsuccessfulResponse CreateUnsuccessfulResponse(ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
var unsuccessfulResponse = new AssociateUnsuccessfulResponse(this.Version, this);
diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs
index d2ca70a..137cd60 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponse.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -20,6 +21,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// Association response messages are described in OpenID 2.0 section 8.2. This type covers section 8.2.1.
/// </remarks>
[DebuggerDisplay("OpenID {Version} associate response {AssociationHandle} {AssociationType} {SessionType}")]
+ [ContractClass(typeof(AssociateSuccessfulResponseContract))]
internal abstract class AssociateSuccessfulResponse : DirectResponseBase {
/// <summary>
/// A flag indicating whether an association has already been created.
@@ -106,7 +108,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// quite different operations in either scenario.</para>
/// </remarks>
internal Association CreateAssociation(AssociateRequest request, ProviderSecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
ErrorUtilities.VerifyInternal(!this.associationCreated, "The association has already been created.");
Association association;
diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs
new file mode 100644
index 0000000..dd37da6
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateSuccessfulResponseContract.cs
@@ -0,0 +1,29 @@
+// <auto-generated />
+
+namespace DotNetOpenAuth.OpenId.Messages {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ [ContractClassFor(typeof(AssociateSuccessfulResponse))]
+ internal abstract class AssociateSuccessfulResponseContract : AssociateSuccessfulResponse {
+ protected AssociateSuccessfulResponseContract() : base(null, null) {
+ }
+
+ protected override Association CreateAssociationAtProvider(AssociateRequest request, ProviderSecuritySettings securitySettings) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ throw new NotImplementedException();
+ }
+
+ protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationRequest.cs
index a10f073..5306c54 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationRequest.cs
@@ -41,8 +41,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="channel">The channel. This is used only within the constructor and is not stored in a field.</param>
internal CheckAuthenticationRequest(IndirectSignedResponse message, Channel channel)
: base(message.Version, message.ProviderEndpoint, GetProtocolConstant(message.Version, p => p.Args.Mode.check_authentication), MessageTransport.Direct) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
// Copy all message parts from the id_res message into this one,
// except for the openid.mode parameter.
diff --git a/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationResponse.cs
index c34d2b4..61825e8 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/CheckAuthenticationResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -36,7 +37,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="provider">The OpenID Provider that is preparing to send this response.</param>
internal CheckAuthenticationResponse(CheckAuthenticationRequest request, OpenIdProvider provider)
: base(request.Version, request) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(provider != null);
// The channel's binding elements have already set the request's IsValid property
// appropriately. We just copy it into the response message.
diff --git a/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs b/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs
index dd9c927..e7619bc 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/DirectResponseBase.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -53,7 +54,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="responseVersion">The OpenID version of the response message.</param>
/// <param name="originatingRequest">The originating request. May be null in case the request is unrecognizable and this is an error response.</param>
protected DirectResponseBase(Version responseVersion, IDirectedProtocolMessage originatingRequest) {
- ErrorUtilities.VerifyArgumentNotNull(responseVersion, "responseVersion");
+ Contract.Requires<ArgumentNullException>(responseVersion != null);
this.Version = responseVersion;
this.originatingRequest = originatingRequest;
diff --git a/src/DotNetOpenAuth/OpenId/Messages/IndirectResponseBase.cs b/src/DotNetOpenAuth/OpenId/Messages/IndirectResponseBase.cs
index 1147790..d53b9d0 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/IndirectResponseBase.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/IndirectResponseBase.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -23,7 +24,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="mode">The value of the openid.mode parameter.</param>
protected IndirectResponseBase(SignedResponseRequest request, string mode)
: base(GetVersion(request), GetReturnTo(request), mode, MessageTransport.Indirect) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
this.OriginatingRequest = request;
}
@@ -56,7 +57,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// instead of a <see cref="NullReferenceException"/>.
/// </remarks>
internal static Version GetVersion(IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return message.Version;
}
@@ -70,7 +71,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// instead of a <see cref="NullReferenceException"/>.
/// </remarks>
private static Uri GetReturnTo(SignedResponseRequest message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
ErrorUtilities.VerifyProtocol(message.ReturnTo != null, OpenIdStrings.ReturnToRequiredForResponse);
return message.ReturnTo;
}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs
index 9462d21..2f02974 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs
@@ -62,7 +62,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// </param>
internal IndirectSignedResponse(SignedResponseRequest request)
: base(request, Protocol.Lookup(GetVersion(request)).Args.Mode.id_res) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
this.ReturnTo = request.ReturnTo;
this.ProviderEndpoint = request.Recipient.StripQueryArgumentsWithPrefix(Protocol.openid.Prefix);
@@ -77,8 +77,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="channel">The channel. This is used only within the constructor and is not stored in a field.</param>
internal IndirectSignedResponse(CheckAuthenticationRequest previouslySignedMessage, Channel channel)
: base(GetVersion(previouslySignedMessage), previouslySignedMessage.ReturnTo, Protocol.Lookup(GetVersion(previouslySignedMessage)).Args.Mode.id_res) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
// Copy all message parts from the check_authentication message into this one,
// except for the openid.mode parameter.
@@ -332,7 +331,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// cannot verify the private signature made by the relying party.
/// </remarks>
internal string GetReturnToArgument(string key) {
- ErrorUtilities.VerifyNonZeroLength(key, "key");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(key));
ErrorUtilities.VerifyInternal(this.ReturnTo != null, "ReturnTo was expected to be required but is null.");
string value;
@@ -358,8 +357,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// A dictionary of the signed message parts.
/// </returns>
internal IDictionary<string, string> GetSignedMessageParts(Channel channel) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
ITamperResistantOpenIdMessage signedSelf = this;
if (signedSelf.SignedParameterOrder == null) {
diff --git a/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs
index 99a7c5a..52ff884 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -114,8 +115,8 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="channel">The channel to use to simulate construction of the message.</param>
/// <returns>The value to use for the user_setup_url parameter.</returns>
private static Uri ConstructUserSetupUrl(CheckIdRequest immediateRequest, Channel channel) {
- ErrorUtilities.VerifyArgumentNotNull(immediateRequest, "immediateRequest");
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(immediateRequest != null);
+ Contract.Requires<ArgumentNullException>(channel != null);
ErrorUtilities.VerifyInternal(immediateRequest.Immediate, "Only immediate requests should be sent here.");
var setupRequest = new CheckIdRequest(immediateRequest.Version, immediateRequest.Recipient, AuthenticationRequestMode.Setup);
@@ -132,7 +133,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// <param name="request">The request that we're responding to.</param>
/// <returns>The value of the openid.mode parameter to use.</returns>
private static string GetMode(SignedResponseRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
Protocol protocol = Protocol.Lookup(request.Version);
return request.Immediate ? protocol.Args.Mode.setup_needed : protocol.Args.Mode.cancel;
diff --git a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs
index 7189583..8a4a2a6 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/RequestBase.cs
@@ -9,6 +9,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -181,7 +182,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// instead of a <see cref="NullReferenceException"/>.
/// </remarks>
protected static string GetProtocolConstant(Version protocolVersion, Func<Protocol, string> mode) {
- ErrorUtilities.VerifyArgumentNotNull(protocolVersion, "protocolVersion");
+ Contract.Requires<ArgumentNullException>(protocolVersion != null);
return mode(Protocol.Lookup(protocolVersion));
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs b/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
index 1096468..7eb5407 100644
--- a/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Messages/SignedResponseRequest.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -107,6 +108,11 @@ namespace DotNetOpenAuth.OpenId.Messages {
internal Realm Realm { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether the return_to value should be signed.
+ /// </summary>
+ internal bool SignReturnTo { get; set; }
+
+ /// <summary>
/// Checks the message state for conformity to the protocol specification
/// and throws an exception if the message is invalid.
/// </summary>
@@ -139,7 +145,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// when and if a positive assertion comes back from the Provider.
/// </remarks>
internal void AddReturnToArguments(IEnumerable<KeyValuePair<string, string>> keysValues) {
- ErrorUtilities.VerifyArgumentNotNull(keysValues, "keysValues");
+ Contract.Requires<ArgumentNullException>(keysValues != null);
ErrorUtilities.VerifyOperation(this.ReturnTo != null, OpenIdStrings.ReturnToRequiredForOperation);
UriBuilder returnToBuilder = new UriBuilder(this.ReturnTo);
returnToBuilder.AppendAndReplaceQueryArgs(keysValues);
@@ -170,7 +176,7 @@ namespace DotNetOpenAuth.OpenId.Messages {
/// </param>
/// <returns>checkid_immediate or checkid_setup</returns>
private static string GetMode(Version version, AuthenticationRequestMode mode) {
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
+ Contract.Requires<ArgumentNullException>(version != null);
Protocol protocol = Protocol.Lookup(version);
return mode == AuthenticationRequestMode.Immediate ? protocol.Args.Mode.checkid_immediate : protocol.Args.Mode.checkid_setup;
diff --git a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
index 2c8e865..636df67 100644
--- a/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/NoDiscoveryIdentifier.cs
@@ -5,6 +5,7 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId {
+ using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
@@ -28,9 +29,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="wrappedIdentifier">The ordinary Identifier whose discovery is being masked.</param>
/// <param name="claimSsl">Whether this Identifier should claim to be SSL-secure, although no discovery will never generate service endpoints anyway.</param>
internal NoDiscoveryIdentifier(Identifier wrappedIdentifier, bool claimSsl)
- : base(claimSsl) {
- Contract.Requires(wrappedIdentifier != null);
- ErrorUtilities.VerifyArgumentNotNull(wrappedIdentifier, "wrappedIdentifier");
+ : base(wrappedIdentifier.OriginalString, claimSsl) {
+ Contract.Requires<ArgumentNullException>(wrappedIdentifier != null);
this.wrappedIdentifier = wrappedIdentifier;
}
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
index d03ced5..05daed0 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs
@@ -286,6 +286,15 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
+ /// Looks up a localized string similar to The HTML head tag must include runat=&quot;server&quot;..
+ /// </summary>
+ internal static string HeadTagMustIncludeRunatServer {
+ get {
+ return ResourceManager.GetString("HeadTagMustIncludeRunatServer", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to ClaimedIdentifier and LocalIdentifier must be the same when IsIdentifierSelect is true..
/// </summary>
internal static string IdentifierSelectRequiresMatchingIdentifiers {
@@ -358,7 +367,7 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
- /// Looks up a localized string similar to Not a recognized XRI format: &apos;{0}&apos;..
+ /// Looks up a localized string similar to Not a recognized XRI format..
/// </summary>
internal static string InvalidXri {
get {
@@ -515,6 +524,15 @@ namespace DotNetOpenAuth.OpenId {
}
/// <summary>
+ /// Looks up a localized string similar to The {0} property must be set first..
+ /// </summary>
+ internal static string PropertyNotSet {
+ get {
+ return ResourceManager.GetString("PropertyNotSet", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to This property value is not supported by this control..
/// </summary>
internal static string PropertyValueNotSupported {
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
index dd17fb8..919d873 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx
@@ -178,7 +178,7 @@
<value>The value '{0}' is not a valid URI.</value>
</data>
<data name="InvalidXri" xml:space="preserve">
- <value>Not a recognized XRI format: '{0}'.</value>
+ <value>Not a recognized XRI format.</value>
</data>
<data name="IssuedAssertionFailsIdentifierDiscovery" xml:space="preserve">
<value>The OpenID Provider issued an assertion for an Identifier whose discovery information did not match.
@@ -343,4 +343,10 @@ Discovered endpoint info:
<data name="PositiveAssertionFromNonWhitelistedProvider" xml:space="preserve">
<value>An positive OpenID assertion was received from OP endpoint {0} that is not on this relying party's whitelist.</value>
</data>
-</root>
+ <data name="HeadTagMustIncludeRunatServer" xml:space="preserve">
+ <value>The HTML head tag must include runat="server".</value>
+ </data>
+ <data name="PropertyNotSet" xml:space="preserve">
+ <value>The {0} property must be set first.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.sr.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.sr.resx
new file mode 100644
index 0000000..0df62c0
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.sr.resx
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="AssociationSecretAndTypeLengthMismatch" xml:space="preserve">
+ <value>Dužina deljene tajne ({0}) ne slaže se sa dužinom zahtevanom od povezujućeg tipa ('{1}').</value>
+ </data>
+ <data name="AssociationSecretHashLengthMismatch" xml:space="preserve">
+ <value>Dužina šifrovane deljene tajne ({0}) ne slaže se sa dužinom hashing algoritma ({1}).</value>
+ </data>
+ <data name="AssociationStoreRequiresNonceStore" xml:space="preserve">
+ <value>Ako je dato povezujuće skladište, jedinstveni identifikator skladišta takođe mora biti prisutan.</value>
+ </data>
+ <data name="BadAssociationPrivateData" xml:space="preserve">
+ <value>Dostavljeni privatni podaci ne slažu se ni sa jednim poznatim Association tipom. Dužina im je možda prekratka ili su podaci neispravni.</value>
+ </data>
+ <data name="CallbackArgumentsRequireSecretStore" xml:space="preserve">
+ <value>Callback argumenti su podržani jedino kada je {0} dustupan za {1}.</value>
+ </data>
+ <data name="CallDeserializeBeforeCreateResponse" xml:space="preserve">
+ <value>Simple Registration zahtev može generisati odgovor jedino na prijemnoj strani.</value>
+ </data>
+ <data name="ClaimedIdAndLocalIdMustBothPresentOrAbsent" xml:space="preserve">
+ <value>openid.claimed_id i openid.identity parametri moraju istovremeno biti prisutni ili nedostajati.</value>
+ </data>
+ <data name="ClaimedIdentifierCannotBeSetOnDelegatedAuthentication" xml:space="preserve">
+ <value>ClaimedIdentifier svojstvo ne može se podesiti kada IsDelegatedIdentifier ima vrednost true da bi se izbeglo narušavanje OpenID URL delegiranja.</value>
+ </data>
+ <data name="ClaimedIdentifierMustBeSetFirst" xml:space="preserve">
+ <value>ClaimedIdentifier svojstvo se najpre mora podesiti.</value>
+ </data>
+ <data name="DiffieHellmanRequiredPropertiesNotSet" xml:space="preserve">
+ <value>Sledeća svojstva moraju biti podeÅ¡ena pre nego Å¡to Diffie-Hellmanov algoritam može generisati javni kljuÄ: {0}</value>
+ </data>
+ <data name="ExplicitHttpUriSuppliedWithSslRequirement" xml:space="preserve">
+ <value>URI nije SSL a svojstvo requireSslDiscovery je podešeno na true.</value>
+ </data>
+ <data name="ExtensionAlreadyAddedWithSameTypeURI" xml:space="preserve">
+ <value>Prostor deljenja proširenja '{0}' je već dodat. Samo jedno proširenje po prostoru je dozvoljeno u datom zahtevu.</value>
+ </data>
+ <data name="ExtensionLookupSupportUnavailable" xml:space="preserve">
+ <value>Ne može se tražiti podrška za proširenja na rehidriranom ServiceEndpoint.</value>
+ </data>
+ <data name="FragmentNotAllowedOnXRIs" xml:space="preserve">
+ <value>Segmenti fragmenta se ne primenjuju na XRI identifikatore.</value>
+ </data>
+ <data name="IdentifierSelectRequiresMatchingIdentifiers" xml:space="preserve">
+ <value>ClaimedIdentifier i LocalIdentifier moraju biti isti kada IsIdentifierSelect ima vrednost true.</value>
+ </data>
+ <data name="IndirectErrorFormattedMessage" xml:space="preserve">
+ <value>{0} (Kontakt: {1}, Referenca: {2})</value>
+ </data>
+ <data name="InvalidCharacterInKeyValueFormInput" xml:space="preserve">
+ <value>Ne može se enkodovati '{0}' jer sadrži nevalidan znak za Key-Value Form enkodiranje. (linija {1}: '{2}')</value>
+ </data>
+ <data name="InvalidKeyValueFormCharacterMissing" xml:space="preserve">
+ <value>Ne može se dekodovati Key-Value Form jer je pronađena linija bez '{0}' znaka. (linija {1}: '{2}')</value>
+ </data>
+ <data name="InvalidScheme" xml:space="preserve">
+ <value>Å ema mora biti http ili https a bila je '{0}'.</value>
+ </data>
+ <data name="InvalidUri" xml:space="preserve">
+ <value>Vrednost '{0}' nije validan URI.</value>
+ </data>
+ <data name="InvalidXri" xml:space="preserve">
+ <value>Nije prepoznat XRI format: '{0}'.</value>
+ </data>
+ <data name="IssuedAssertionFailsIdentifierDiscovery" xml:space="preserve">
+ <value>OpenID Provider dao je iskaz za Identifier Äije se informacije o pronalaženju ne slažu.
+Informacije o krajnoj taÄki iskaza:
+{0}
+Informacije o otkrivenoj krajnjoj taÄki:
+{1}</value>
+ </data>
+ <data name="KeysListAndDictionaryDoNotMatch" xml:space="preserve">
+ <value>Lista kljuÄeva se ne slaže sa ponuÄ‘enim reÄnikom.</value>
+ </data>
+ <data name="MatchingArgumentsExpected" xml:space="preserve">
+ <value>Parametri '{0}' i '{1}' moraju oba biti ili ne smeju oba biti '{2}'.</value>
+ </data>
+ <data name="NoAssociationTypeFoundByLength" xml:space="preserve">
+ <value>Ni jedan prepoznati tip asociranja se ne uklapa sa zahtevanom dužinom {0}.</value>
+ </data>
+ <data name="NoAssociationTypeFoundByName" xml:space="preserve">
+ <value>Ni jedan prepoznati tip asociranja se ne uklapa sa zahtevanim imenom '{0}'.</value>
+ </data>
+ <data name="NoEncryptionSessionRequiresHttps" xml:space="preserve">
+ <value>Osim ako se ne koristi enkripcija transportnog sloja, "no-encryption" NE SME biti korišćen.</value>
+ </data>
+ <data name="NoSessionTypeFound" xml:space="preserve">
+ <value>Diffie-Hellman sesija tipa '{0}' nije pronađena za OpenID {1}.</value>
+ </data>
+ <data name="OpenIdEndpointNotFound" xml:space="preserve">
+ <value>Nijedna OpenID krajnja taÄka nije pronaÄ‘ena.</value>
+ </data>
+ <data name="OperationOnlyValidForSetupRequiredState" xml:space="preserve">
+ <value>Ova operacija je jedino dozvoljena kada je IAuthenticationResponse.State == AuthenticationStatus.SetupRequired.</value>
+ </data>
+ <data name="ProviderVersionUnrecognized" xml:space="preserve">
+ <value>Nije moguće utvrditi verziju OpenID protokola implementiranog od strane Provider-a na krajnjoj taÄki '{0}'.</value>
+ </data>
+ <data name="RealmCausedRedirectUponDiscovery" xml:space="preserve">
+ <value>HTTP zahtev ka URL-u domena ({0}) rezultovao je redirekcijom, koja nije dozvoljena u togu pronalaženja Relying Party.</value>
+ </data>
+ <data name="ReturnToNotUnderRealm" xml:space="preserve">
+ <value>return_to '{0}' nije unutar domena '{1}'.</value>
+ </data>
+ <data name="ReturnToParamDoesNotMatchRequestUrl" xml:space="preserve">
+ <value>{0} parametar ({1}) se ne slaže sa trenutnim URL ({2}) sa kojim je zahtev napravljen.</value>
+ </data>
+ <data name="ReturnToRequiredForResponse" xml:space="preserve">
+ <value>openid.return_to parametar je neophodan u poruci zahteva da bi se konstruisao odgovor, ali ovaj parametar nedostaje.</value>
+ </data>
+ <data name="SignatureDoesNotIncludeMandatoryParts" xml:space="preserve">
+ <value>Sledeći parametri nisu ukljuÄeni u potpis a moraju da budu: {0}</value>
+ </data>
+ <data name="SregInvalidBirthdate" xml:space="preserve">
+ <value>Neispravna vrednost za datum rođenja. Mora biti u formi gggg-MM-dd.</value>
+ </data>
+ <data name="TypeMustImplementX" xml:space="preserve">
+ <value>Tip mora implementirati {0}.</value>
+ </data>
+ <data name="UnsolicitedAssertionsNotAllowedFrom1xOPs" xml:space="preserve">
+ <value>Nezahtevani iskazi nisu dozvoljeni od strane 1.0 OpenID Providers.</value>
+ </data>
+ <data name="UserSetupUrlRequiredInImmediateNegativeResponse" xml:space="preserve">
+ <value>openid.user_setup_url parametar je neophodan prilikom slanja negativnih poruka sa iskazima prilikom odgovaranja na zahteve u trenutnom modu.</value>
+ </data>
+ <data name="XriResolutionFailed" xml:space="preserve">
+ <value>XRI razrešivanje neuspešno.</value>
+ </data>
+ <data name="StoreRequiredWhenNoHttpContextAvailable" xml:space="preserve">
+ <value>Tekući HttpContext nije detektovan, tako da {0} instanca mora biti eksplicitno postavljena ili specificirana u .config fajlu. Pozvati preklopljeni konstruktor koji uzima parametar {0}.</value>
+ </data>
+ <data name="AttributeAlreadyAdded" xml:space="preserve">
+ <value>Atribut sa URI tipom '{0}' je već dodat.</value>
+ </data>
+ <data name="AttributeTooManyValues" xml:space="preserve">
+ <value>Samo {0} vrednosti za atribut '{1}' su zahtevane, ali {2} su ponuđene.</value>
+ </data>
+ <data name="UnspecifiedDateTimeKindNotAllowed" xml:space="preserve">
+ <value>ProsleÄ‘ivanje objekta tipa DateTime Äije svojstvo Kind ima vrednost Unspecified nije dozvoljeno.</value>
+ </data>
+ <data name="AssociationOrSessionTypeUnrecognizedOrNotSupported" xml:space="preserve">
+ <value>Zahtevani tip asocijacije '{0}' sa sesijom tipa '{1}' nije prepoznat ili nije podržan od strane ovog Provider-a zbog bezbedonosnih zahteva.</value>
+ </data>
+ <data name="IncompatibleAssociationAndSessionTypes" xml:space="preserve">
+ <value>Provider je zahtevao asocijaciju tipa '{0}' i sesiju tipa '{1}', koje nisu međusobno kompatibilne.</value>
+ </data>
+ <data name="CreateRequestAlreadyCalled" xml:space="preserve">
+ <value>Zahtev za autentifikacijom je već kreiran korišćenjem CreateRequest().</value>
+ </data>
+ <data name="OpenIdTextBoxEmpty" xml:space="preserve">
+ <value>Nijedan OpenID url nije ponuđen.</value>
+ </data>
+ <data name="ClientScriptExtensionPropertyNameCollision" xml:space="preserve">
+ <value>Ekstenzija sa svojstvom ovog imena ('{0}') je već registrovana.</value>
+ </data>
+ <data name="ClientScriptExtensionTypeCollision" xml:space="preserve">
+ <value>Ekstenzija '{0}' je već registrovana.</value>
+ </data>
+ <data name="UnexpectedHttpStatusCode" xml:space="preserve">
+ <value>NeoÄekivani HTTP statusni kod {0} {1} primljen u direktnom odgovoru.</value>
+ </data>
+ <data name="NotSupportedByAuthenticationSnapshot" xml:space="preserve">
+ <value>Ova operacija nije podržana od strane serijalizovanih odgovora za autentifikaciju. Pokušati ovu operaciju iz LoggedIn handler-a događaja.</value>
+ </data>
+ <data name="NoRelyingPartyEndpointDiscovered" xml:space="preserve">
+ <value>Nijedan XRDS dokument koji sadrži informaciju o OpenID Relying Party krajnjoj taÄki nije pronadjen u {0}.</value>
+ </data>
+ <data name="AbsoluteUriRequired" xml:space="preserve">
+ <value>Absolutni URI je zahtevan za ovu vrednost.</value>
+ </data>
+ <data name="UnsolicitedAssertionForUnrelatedClaimedIdentifier" xml:space="preserve">
+ <value>Nezahtevani iskaz ne može biti poslat za navedeni identifikator {0} jer ovo nije autorizovani Provider za taj identifikator.</value>
+ </data>
+ <data name="MaximumAuthenticationTimeExpired" xml:space="preserve">
+ <value>Maksimalno dozvoljeno vreme za kompletiranje autentifikacije je isteklo. Molimo pokušajte ponovo.</value>
+ </data>
+ <data name="PrivateRPSecretNotFound" xml:space="preserve">
+ <value>Ne može se pronaći tajna za potpisivanje od strane handle-a '{0}'.</value>
+ </data>
+ <data name="ResponseNotReady" xml:space="preserve">
+ <value>Odgovor nije spreman. Koristiti najpre IsResponseReady za proveru da li je odgovor spreman.</value>
+ </data>
+ <data name="UnsupportedChannelConfiguration" xml:space="preserve">
+ <value>Ovo svojstvo nije dostupno zbog nepoznate konfiguracije kanala.</value>
+ </data>
+ <data name="IdentityAndClaimedIdentifierMustBeBothPresentOrAbsent" xml:space="preserve">
+ <value>openid.identity i openid.claimed_id parametri moraju istovremeno biti prisutna ili istovremeno odsutna u poruci.</value>
+ </data>
+ <data name="ReturnToRequiredForOperation" xml:space="preserve">
+ <value>Svojstvo ReturnTo ne sme biti null da bi se podržala ova operacija.</value>
+ </data>
+ <data name="UnsolicitedAssertionRejectionRequiresNonceStore" xml:space="preserve">
+ <value>Odbijanje nezahtevanih iskaza zahteva skladište jedinstvenih identifikatora i skladište asocijacija.</value>
+ </data>
+ <data name="UnsolicitedAssertionsNotAllowed" xml:space="preserve">
+ <value>Nezahtevani iskazi nisu dozvoljeni od strane ovog Relying Party.</value>
+ </data>
+ <data name="DelegatingIdentifiersNotAllowed" xml:space="preserve">
+ <value>Samo OpenID-jevi izdati direktno od strane njihovog OpenID Provider-a su ovde dozvoljeni.</value>
+ </data>
+ <data name="XriResolutionDisabled" xml:space="preserve">
+ <value>XRI podrška je onemogućena na ovom sajtu.</value>
+ </data>
+ <data name="AssociationStoreRequired" xml:space="preserve">
+ <value>Skladište asocijacija nije dato a zahtevano je za trenutnu konfiguraciju.</value>
+ </data>
+ <data name="UnexpectedEnumPropertyValue" xml:space="preserve">
+ <value>Svojstvo {0} je imalo neoÄekivanu vrednost {1}.</value>
+ </data>
+ <data name="NoIdentifierSet" xml:space="preserve">
+ <value>Ni jedan identifikator nije podešen.</value>
+ </data>
+ <data name="PropertyValueNotSupported" xml:space="preserve">
+ <value>Ova vrednost svojstva nije podržana od strane ove kontrole.</value>
+ </data>
+ <data name="ArgumentIsPpidIdentifier" xml:space="preserve">
+ <value>Ovo je već PPID Identifier.</value>
+ </data>
+ <data name="RequireSslNotSatisfiedByAssertedClaimedId" xml:space="preserve">
+ <value>Žao nam je. Ovaj sajt jedino prihvata OpenID-jeve koji su HTTPS-bezbedni, a {0} nije bezbedni Identifier.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs
index 3cee968..3e75e61 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs
+++ b/src/DotNetOpenAuth/OpenId/OpenIdUtilities.cs
@@ -34,7 +34,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="message">The message.</param>
/// <returns>The OpenID protocol instance.</returns>
internal static Protocol GetProtocol(this IProtocolMessage message) {
- ErrorUtilities.VerifyArgumentNotNull(message, "message");
+ Contract.Requires<ArgumentNullException>(message != null);
return Protocol.Lookup(message.Version);
}
@@ -103,10 +103,8 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>The fully-qualified realm.</returns>
[SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId.Realm", Justification = "Using ctor for validation.")]
internal static UriBuilder GetResolvedRealm(Page page, string realm, HttpRequestInfo requestContext) {
- Contract.Requires(page != null);
- Contract.Requires(requestContext != null);
- ErrorUtilities.VerifyArgumentNotNull(page, "page");
- ErrorUtilities.VerifyArgumentNotNull(requestContext, "requestContext");
+ Contract.Requires<ArgumentNullException>(page != null);
+ Contract.Requires<ArgumentNullException>(requestContext != null);
// Allow for *. realm notation, as well as ASP.NET ~/ shortcuts.
@@ -148,8 +146,7 @@ namespace DotNetOpenAuth.OpenId {
/// can plug in.
/// </remarks>
internal static IList<IOpenIdExtensionFactory> GetExtensionFactories(this Channel channel) {
- Contract.Requires(channel != null);
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
+ Contract.Requires<ArgumentNullException>(channel != null);
var extensionsBindingElement = channel.BindingElements.OfType<ExtensionsBindingElement>().SingleOrDefault();
ErrorUtilities.VerifyOperation(extensionsBindingElement != null, OpenIdStrings.UnsupportedChannelConfiguration);
diff --git a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs
index fd83061..664a127 100644
--- a/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs
+++ b/src/DotNetOpenAuth/OpenId/OpenIdXrdsHelper.cs
@@ -57,7 +57,7 @@ namespace DotNetOpenAuth.OpenId {
/// </returns>
internal static IEnumerable<ServiceEndpoint> CreateServiceEndpoints(this XrdsDocument xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier) {
var endpoints = new List<ServiceEndpoint>();
- endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(claimedIdentifier));
+ endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier));
// If any OP Identifier service elements were found, we must not proceed
// to return any Claimed Identifier services.
@@ -77,8 +77,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="userSuppliedIdentifier">The user-supplied i-name that was used to discover this XRDS document.</param>
/// <returns>A sequence of OpenID Providers that can assert ownership of the canonical ID given in this document.</returns>
internal static IEnumerable<ServiceEndpoint> CreateServiceEndpoints(this XrdsDocument xrds, XriIdentifier userSuppliedIdentifier) {
- Contract.Requires(xrds != null);
- Contract.Requires(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(xrds != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null);
var endpoints = new List<ServiceEndpoint>();
endpoints.AddRange(xrds.GenerateOPIdentifierServiceEndpoints(userSuppliedIdentifier));
@@ -97,11 +97,11 @@ namespace DotNetOpenAuth.OpenId {
/// Generates OpenID Providers that can authenticate using directed identity.
/// </summary>
/// <param name="xrds">The XrdsDocument instance to use in this process.</param>
- /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user.</param>
+ /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user. Essentially the user-supplied identifier.</param>
/// <returns>A sequence of the providers that can offer directed identity services.</returns>
private static IEnumerable<ServiceEndpoint> GenerateOPIdentifierServiceEndpoints(this XrdsDocument xrds, Identifier opIdentifier) {
- Contract.Requires(xrds != null);
- Contract.Requires(opIdentifier != null);
+ Contract.Requires<ArgumentNullException>(xrds != null);
+ Contract.Requires<ArgumentNullException>(opIdentifier != null);
Contract.Ensures(Contract.Result<IEnumerable<ServiceEndpoint>>() != null);
return from service in xrds.FindOPIdentifierServices()
from uri in service.UriElements
diff --git a/src/DotNetOpenAuth/OpenId/Protocol.cs b/src/DotNetOpenAuth/OpenId/Protocol.cs
index 7b8a2f1..d84a923 100644
--- a/src/DotNetOpenAuth/OpenId/Protocol.cs
+++ b/src/DotNetOpenAuth/OpenId/Protocol.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth.OpenId {
using DotNetOpenAuth.Messaging;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Diagnostics;
/// <summary>
@@ -36,7 +37,7 @@ namespace DotNetOpenAuth.OpenId {
/// constants to each version used in the protocol.
/// </summary>
[DebuggerDisplay("OpenID {Version}")]
- internal class Protocol {
+ internal sealed class Protocol {
/// <summary>
/// The value of the openid.ns parameter in the OpenID 2.0 specification.
/// </summary>
@@ -253,7 +254,7 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
public QueryArguments Args = new QueryArguments();
- internal class QueryParameters {
+ internal sealed class QueryParameters {
/// <summary>
/// The value "openid."
/// </summary>
@@ -319,18 +320,31 @@ namespace DotNetOpenAuth.OpenId {
public string dh_server_public = "dh_server_public";
public string enc_mac_key = "enc_mac_key";
public string mac_key = "mac_key";
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ private void ObjectInvariant() {
+ Contract.Invariant(!string.IsNullOrEmpty(this.Prefix));
+ }
+#endif
}
- internal class QueryArguments {
+
+ internal sealed class QueryArguments {
public ErrorCodes ErrorCode = new ErrorCodes();
public SessionTypes SessionType = new SessionTypes();
public SignatureAlgorithms SignatureAlgorithm = new SignatureAlgorithms();
public Modes Mode = new Modes();
public IsValidValues IsValid = new IsValidValues();
- internal class ErrorCodes {
+ internal sealed class ErrorCodes {
public string UnsupportedType = "unsupported-type";
}
- internal class SessionTypes {
+ internal sealed class SessionTypes {
/// <summary>
/// A preference order list of all supported session types.
/// </summary>
@@ -352,7 +366,7 @@ namespace DotNetOpenAuth.OpenId {
}
}
}
- internal class SignatureAlgorithms {
+ internal sealed class SignatureAlgorithms {
/// <summary>
/// A preference order list of signature algorithms we support.
/// </summary>
@@ -372,7 +386,7 @@ namespace DotNetOpenAuth.OpenId {
}
}
}
- internal class Modes {
+ internal sealed class Modes {
public string cancel = "cancel";
public string error = "error";
public string id_res = "id_res";
@@ -382,7 +396,7 @@ namespace DotNetOpenAuth.OpenId {
public string associate = "associate";
public string setup_needed = "id_res"; // V2 overrides this
}
- internal class IsValidValues {
+ internal sealed class IsValidValues {
public string True = "true";
public string False = "false";
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs
index a500e3b..24f84d6 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs
@@ -30,9 +30,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts require it.")]
internal AnonymousRequest(OpenIdProvider provider, SignedResponseRequest request)
: base(provider, request) {
- Contract.Requires(provider != null);
- Contract.Requires(!(request is CheckIdRequest), "Instantiate " + typeof(AuthenticationRequest).Name + " to handle this kind of message.");
- ErrorUtilities.VerifyInternal(!(request is CheckIdRequest), "Instantiate {0} to handle this kind of message.", typeof(AuthenticationRequest).Name);
+ Contract.Requires<ArgumentNullException>(provider != null);
+ Contract.Requires<ArgumentException>(!(request is CheckIdRequest), "Instantiate " + typeof(AuthenticationRequest).Name + " to handle this kind of message.");
this.positiveResponse = new IndirectSignedResponse(request);
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequestEventArgs.cs b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequestEventArgs.cs
index cdd5311..9ffaa55 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequestEventArgs.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequestEventArgs.cs
@@ -18,8 +18,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <param name="request">The incoming OpenID request.</param>
internal AnonymousRequestEventArgs(IAnonymousRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
this.Request = request;
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
index a5d936b..a229488 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AuthenticationRequest.cs
@@ -29,8 +29,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="request">The incoming authentication request message.</param>
internal AuthenticationRequest(OpenIdProvider provider, CheckIdRequest request)
: base(provider, request) {
- Contract.Requires(provider != null);
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(provider != null);
this.positiveResponse = new PositiveAssertionResponse(request);
@@ -150,11 +149,9 @@ namespace DotNetOpenAuth.OpenId.Provider {
set {
// Keep LocalIdentifier and ClaimedIdentifier in sync for directed identity.
if (this.IsDirectedIdentity) {
- ErrorUtilities.VerifyOperation(!(this.LocalIdentifier != null && this.LocalIdentifier != value), OpenIdStrings.IdentifierSelectRequiresMatchingIdentifiers);
this.positiveResponse.LocalIdentifier = value;
}
- ErrorUtilities.VerifyOperation(!this.IsDelegatedIdentifier, OpenIdStrings.ClaimedIdentifierCannotBeSetOnDelegatedAuthentication);
this.positiveResponse.ClaimedIdentifier = value;
}
}
@@ -207,9 +204,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// request before the <see cref="ClaimedIdentifier"/> property is set.
/// </exception>
public void SetClaimedIdentifierFragment(string fragment) {
- ErrorUtilities.VerifyOperation(!(this.IsDirectedIdentity && this.ClaimedIdentifier == null), OpenIdStrings.ClaimedIdentifierMustBeSetFirst);
- ErrorUtilities.VerifyOperation(!(this.ClaimedIdentifier is XriIdentifier), OpenIdStrings.FragmentNotAllowedOnXRIs);
-
UriBuilder builder = new UriBuilder(this.ClaimedIdentifier);
builder.Fragment = fragment;
this.positiveResponse.ClaimedIdentifier = builder.Uri;
@@ -220,8 +214,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <param name="identifier">The value to set to the <see cref="ClaimedIdentifier"/> and <see cref="LocalIdentifier"/> properties.</param>
internal void ResetClaimedAndLocalIdentifiers(Identifier identifier) {
- Contract.Requires(identifier != null);
- ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
+ Contract.Requires<ArgumentNullException>(identifier != null);
this.positiveResponse.ClaimedIdentifier = identifier;
this.positiveResponse.LocalIdentifier = identifier;
diff --git a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
index d1d310e..e5988dd 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/AutoResponsiveRequest.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Provider {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -31,7 +32,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="securitySettings">The security settings.</param>
internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response, ProviderSecuritySettings securitySettings)
: base(request, securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
}
@@ -44,7 +45,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="securitySettings">The security settings.</param>
internal AutoResponsiveRequest(IProtocolMessage response, ProviderSecuritySettings securitySettings)
: base(IndirectResponseBase.GetVersion(response), securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs
index 90dfa2f..38d1094 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/HostProcessedRequest.cs
@@ -36,7 +36,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="request">The incoming request message.</param>
protected HostProcessedRequest(OpenIdProvider provider, SignedResponseRequest request)
: base(request, provider.SecuritySettings) {
- Contract.Requires(provider != null);
+ Contract.Requires<ArgumentNullException>(provider != null);
this.negativeResponse = new NegativeAssertionResponse(request, provider.Channel);
}
@@ -113,8 +113,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// See OpenID Authentication 2.0 spec section 9.2.1.
/// </remarks>
public RelyingPartyDiscoveryResult IsReturnUrlDiscoverable(OpenIdProvider provider) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
-
if (!this.realmDiscoveryResult.HasValue) {
this.realmDiscoveryResult = this.IsReturnUrlDiscoverableCore(provider);
}
@@ -129,9 +127,10 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="provider">The OpenIdProvider that is performing the RP discovery.</param>
/// <returns>Result of realm discovery.</returns>
private RelyingPartyDiscoveryResult IsReturnUrlDiscoverableCore(OpenIdProvider provider) {
- Contract.Requires(provider != null);
+ Contract.Requires<ArgumentNullException>(provider != null);
ErrorUtilities.VerifyInternal(this.Realm != null, "Realm should have been read or derived by now.");
+
try {
if (this.SecuritySettings.RequireSsl && this.Realm.Scheme != Uri.UriSchemeHttps) {
Logger.OpenId.WarnFormat("RP discovery failed because RequireSsl is true and RP discovery would begin at insecure URL {0}.", this.Realm);
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
index bb837b5..077dcf1 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IAuthenticationRequest.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.Provider {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -15,6 +16,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// This interface provides the details of the request and allows setting
/// the response.
/// </summary>
+ [ContractClass(typeof(IAuthenticationRequestContract))]
public interface IAuthenticationRequest : IHostProcessedRequest {
/// <summary>
/// Gets a value indicating whether the Provider should help the user
@@ -93,4 +95,263 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </exception>
void SetClaimedIdentifierFragment(string fragment);
}
+
+ /// <summary>
+ /// Code contract class for the <see cref="IAuthenticationRequest"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IAuthenticationRequest))]
+ internal abstract class IAuthenticationRequestContract : IAuthenticationRequest {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IAuthenticationRequestContract"/> class.
+ /// </summary>
+ protected IAuthenticationRequestContract() {
+ }
+
+ #region IAuthenticationRequest Properties
+
+ /// <summary>
+ /// Gets a value indicating whether the Provider should help the user
+ /// select a Claimed Identifier to send back to the relying party.
+ /// </summary>
+ bool IAuthenticationRequest.IsDirectedIdentity {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the requesting Relying Party is using a delegated URL.
+ /// </summary>
+ /// <remarks>
+ /// When delegated identifiers are used, the <see cref="IAuthenticationRequest.ClaimedIdentifier"/> should not
+ /// be changed at the Provider during authentication.
+ /// Delegation is only detectable on requests originating from OpenID 2.0 relying parties.
+ /// A relying party implementing only OpenID 1.x may use delegation and this property will
+ /// return false anyway.
+ /// </remarks>
+ bool IAuthenticationRequest.IsDelegatedIdentifier {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the Local Identifier to this OpenID Provider of the user attempting
+ /// to authenticate. Check <see cref="IAuthenticationRequest.IsDirectedIdentity"/> to see if
+ /// this value is valid.
+ /// </summary>
+ /// <remarks>
+ /// This may or may not be the same as the Claimed Identifier that the user agent
+ /// originally supplied to the relying party. The Claimed Identifier
+ /// endpoint may be delegating authentication to this provider using
+ /// this provider's local id, which is what this property contains.
+ /// Use this identifier when looking up this user in the provider's user account
+ /// list.
+ /// </remarks>
+ Identifier IAuthenticationRequest.LocalIdentifier {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the identifier that the user agent is claiming at the relying party site.
+ /// Check <see cref="IAuthenticationRequest.IsDirectedIdentity"/> to see if this value is valid.
+ /// </summary>
+ /// <remarks>
+ /// <para>This property can only be set if <see cref="IAuthenticationRequest.IsDelegatedIdentifier"/> is
+ /// false, to prevent breaking URL delegation.</para>
+ /// <para>This will not be the same as this provider's local identifier for the user
+ /// if the user has set up his/her own identity page that points to this
+ /// provider for authentication.</para>
+ /// <para>The provider may use this identifier for displaying to the user when
+ /// asking for the user's permission to authenticate to the relying party.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">Thrown from the setter
+ /// if <see cref="IAuthenticationRequest.IsDelegatedIdentifier"/> is true.</exception>
+ Identifier IAuthenticationRequest.ClaimedIdentifier {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ IAuthenticationRequest req = this;
+ Contract.Requires<InvalidOperationException>(!req.IsDelegatedIdentifier, OpenIdStrings.ClaimedIdentifierCannotBeSetOnDelegatedAuthentication);
+ Contract.Requires<InvalidOperationException>(!req.IsDirectedIdentity || !(req.LocalIdentifier != null && req.LocalIdentifier != value), OpenIdStrings.IdentifierSelectRequiresMatchingIdentifiers);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the provider has determined that the
+ /// <see cref="IAuthenticationRequest.ClaimedIdentifier"/> belongs to the currently logged in user
+ /// and wishes to share this information with the consumer.
+ /// </summary>
+ bool? IAuthenticationRequest.IsAuthenticated {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ #endregion
+
+ #region IHostProcessedRequest Properties
+
+ /// <summary>
+ /// Gets the version of OpenID being used by the relying party that sent the request.
+ /// </summary>
+ ProtocolVersion IHostProcessedRequest.RelyingPartyVersion {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the URL the consumer site claims to use as its 'base' address.
+ /// </summary>
+ Realm IHostProcessedRequest.Realm {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the consumer demands an immediate response.
+ /// If false, the consumer is willing to wait for the identity provider
+ /// to authenticate the user.
+ /// </summary>
+ bool IHostProcessedRequest.Immediate {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the provider endpoint claimed in the positive assertion.
+ /// </summary>
+ /// <value>
+ /// The default value is the URL that the request came in on from the relying party.
+ /// This value MUST match the value for the OP Endpoint in the discovery results for the
+ /// claimed identifier being asserted in a positive response.
+ /// </value>
+ Uri IHostProcessedRequest.ProviderEndpoint {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ #endregion
+
+ #region IRequest Properties
+
+ /// <summary>
+ /// Gets a value indicating whether the response is ready to be sent to the user agent.
+ /// </summary>
+ /// <remarks>
+ /// This property returns false if there are properties that must be set on this
+ /// request instance before the response can be sent.
+ /// </remarks>
+ bool IRequest.IsResponseReady {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets or sets the security settings that apply to this request.
+ /// </summary>
+ /// <value>
+ /// Defaults to the <see cref="OpenIdProvider.SecuritySettings"/> on the <see cref="OpenIdProvider"/>.
+ /// </value>
+ ProviderSecuritySettings IRequest.SecuritySettings {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ #endregion
+
+ #region IAuthenticationRequest Methods
+
+ /// <summary>
+ /// Adds an optional fragment (#fragment) portion to the ClaimedIdentifier.
+ /// Useful for identifier recycling.
+ /// </summary>
+ /// <param name="fragment">Should not include the # prefix character as that will be added internally.
+ /// May be null or the empty string to clear a previously set fragment.</param>
+ /// <remarks>
+ /// <para>Unlike the <see cref="IAuthenticationRequest.ClaimedIdentifier"/> property, which can only be set if
+ /// using directed identity, this method can be called on any URI claimed identifier.</para>
+ /// <para>Because XRI claimed identifiers (the canonical IDs) are never recycled,
+ /// this method should<i>not</i> be called for XRIs.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when this method is called on an XRI, or on a directed identity
+ /// request before the <see cref="IAuthenticationRequest.ClaimedIdentifier"/> property is set.
+ /// </exception>
+ void IAuthenticationRequest.SetClaimedIdentifierFragment(string fragment) {
+ Contract.Requires<InvalidOperationException>(!(((IAuthenticationRequest)this).IsDirectedIdentity && ((IAuthenticationRequest)this).ClaimedIdentifier == null), OpenIdStrings.ClaimedIdentifierMustBeSetFirst);
+ Contract.Requires<InvalidOperationException>(!(((IAuthenticationRequest)this).ClaimedIdentifier is XriIdentifier), OpenIdStrings.FragmentNotAllowedOnXRIs);
+
+ throw new NotImplementedException();
+ }
+
+ #endregion
+
+ #region IHostProcessedRequest Methods
+
+ /// <summary>
+ /// Attempts to perform relying party discovery of the return URL claimed by the Relying Party.
+ /// </summary>
+ /// <param name="provider">The OpenIdProvider that is performing the RP discovery.</param>
+ /// <returns>
+ /// The details of how successful the relying party discovery was.
+ /// </returns>
+ /// <remarks>
+ /// <para>Return URL verification is only attempted if this method is called.</para>
+ /// <para>See OpenID Authentication 2.0 spec section 9.2.1.</para>
+ /// </remarks>
+ RelyingPartyDiscoveryResult IHostProcessedRequest.IsReturnUrlDiscoverable(OpenIdProvider provider) {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+
+ #region IRequest Methods
+
+ /// <summary>
+ /// Adds an extension to the response to send to the relying party.
+ /// </summary>
+ /// <param name="extension">The extension to add to the response message.</param>
+ void IRequest.AddResponseExtension(DotNetOpenAuth.OpenId.Messages.IOpenIdMessageExtension extension) {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets an extension sent from the relying party.
+ /// </summary>
+ /// <typeparam name="T">The type of the extension.</typeparam>
+ /// <returns>
+ /// An instance of the extension initialized with values passed in with the request.
+ /// </returns>
+ T IRequest.GetExtension<T>() {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets an extension sent from the relying party.
+ /// </summary>
+ /// <param name="extensionType">The type of the extension.</param>
+ /// <returns>
+ /// An instance of the extension initialized with values passed in with the request.
+ /// </returns>
+ DotNetOpenAuth.OpenId.Messages.IOpenIdMessageExtension IRequest.GetExtension(Type extensionType) {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs
index 00a3267..985bb54 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IDirectedIdentityIdentifierProvider.cs
@@ -37,6 +37,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <returns>
/// <c>true</c> if the given identifier is the valid, unique identifier for some uesr (and NOT a PPID); otherwise, <c>false</c>.
/// </returns>
+ [Pure]
bool IsUserLocalIdentifier(Identifier identifier);
}
@@ -58,9 +59,9 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// openid.claimed_id and openid.local_id parameters. Must not be null.
/// </returns>
Uri IDirectedIdentityIdentifierProvider.GetIdentifier(Identifier localIdentifier, Realm relyingPartyRealm) {
- Contract.Requires(localIdentifier != null);
- Contract.Requires(relyingPartyRealm != null);
-
+ Contract.Requires<ArgumentNullException>(localIdentifier != null);
+ Contract.Requires<ArgumentNullException>(relyingPartyRealm != null);
+ Contract.Requires<ArgumentException>(((IDirectedIdentityIdentifierProvider)this).IsUserLocalIdentifier(localIdentifier), OpenIdStrings.ArgumentIsPpidIdentifier);
throw new NotImplementedException();
}
@@ -72,7 +73,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <c>true</c> if the given identifier is the valid, unique identifier for some uesr (and NOT a PPID); otherwise, <c>false</c>.
/// </returns>
bool IDirectedIdentityIdentifierProvider.IsUserLocalIdentifier(Identifier identifier) {
- Contract.Requires(identifier != null);
+ Contract.Requires<ArgumentNullException>(identifier != null);
+
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IHostProcessedRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/IHostProcessedRequest.cs
index 345ba52..be809bd 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IHostProcessedRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IHostProcessedRequest.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
using System;
using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.Messages;
/// <summary>
/// Interface exposing incoming messages to the OpenID Provider that
@@ -57,10 +58,16 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
/// <summary>
- /// Contract class for the <see cref="IHostProcessedRequest"/> type.
+ /// Code contract for the <see cref="IHostProcessedRequest"/> type.
/// </summary>
[ContractClassFor(typeof(IHostProcessedRequest))]
internal abstract class IHostProcessedRequestContract : IHostProcessedRequest {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IHostProcessedRequestContract"/> class.
+ /// </summary>
+ protected IHostProcessedRequestContract() {
+ }
+
#region IHostProcessedRequest Properties
/// <summary>
@@ -176,7 +183,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <para>See OpenID Authentication 2.0 spec section 9.2.1.</para>
/// </remarks>
RelyingPartyDiscoveryResult IHostProcessedRequest.IsReturnUrlDiscoverable(OpenIdProvider provider) {
- Contract.Requires(provider != null);
+ Contract.Requires<ArgumentNullException>(provider != null);
throw new System.NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IProviderBehavior.cs b/src/DotNetOpenAuth/OpenId/Provider/IProviderBehavior.cs
index 4e3dc99..01b4ac8 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IProviderBehavior.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IProviderBehavior.cs
@@ -5,11 +5,14 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.Provider {
+ using System;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.OpenId.ChannelElements;
/// <summary>
/// Applies a custom security policy to certain OpenID security settings and behaviors.
/// </summary>
+ [ContractClass(typeof(IProviderBehaviorContract))]
public interface IProviderBehavior {
/// <summary>
/// Applies a well known set of security requirements to a default set of security settings.
@@ -47,4 +50,65 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </returns>
bool OnOutgoingResponse(IAuthenticationRequest request);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IProviderBehavior"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IProviderBehavior))]
+ internal abstract class IProviderBehaviorContract : IProviderBehavior {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IProviderBehaviorContract"/> class.
+ /// </summary>
+ protected IProviderBehaviorContract() {
+ }
+
+ #region IProviderBehavior Members
+
+ /// <summary>
+ /// Applies a well known set of security requirements to a default set of security settings.
+ /// </summary>
+ /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param>
+ /// <remarks>
+ /// Care should be taken to never decrease security when applying a profile.
+ /// Profiles should only enhance security requirements to avoid being
+ /// incompatible with each other.
+ /// </remarks>
+ void IProviderBehavior.ApplySecuritySettings(ProviderSecuritySettings securitySettings) {
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Called when a request is received by the Provider.
+ /// </summary>
+ /// <param name="request">The incoming request.</param>
+ /// <returns>
+ /// <c>true</c> if this behavior owns this request and wants to stop other behaviors
+ /// from handling it; <c>false</c> to allow other behaviors to process this request.
+ /// </returns>
+ /// <remarks>
+ /// Implementations may set a new value to <see cref="IRequest.SecuritySettings"/> but
+ /// should not change the properties on the instance of <see cref="ProviderSecuritySettings"/>
+ /// itself as that instance may be shared across many requests.
+ /// </remarks>
+ bool IProviderBehavior.OnIncomingRequest(IRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ throw new System.NotImplementedException();
+ }
+
+ /// <summary>
+ /// Called when the Provider is preparing to send a response to an authentication request.
+ /// </summary>
+ /// <param name="request">The request that is configured to generate the outgoing response.</param>
+ /// <returns>
+ /// <c>true</c> if this behavior owns this request and wants to stop other behaviors
+ /// from handling it; <c>false</c> to allow other behaviors to process this request.
+ /// </returns>
+ bool IProviderBehavior.OnOutgoingResponse(IAuthenticationRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ throw new System.NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
index 2ca96ca..0fcdc28 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/IRequest.cs
@@ -64,7 +64,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// Code contract for the <see cref="IRequest"/> interface.
/// </summary>
[ContractClassFor(typeof(IRequest))]
- internal class IRequestContract : IRequest {
+ internal abstract class IRequestContract : IRequest {
/// <summary>
/// Prevents a default instance of the <see cref="IRequestContract"/> class from being created.
/// </summary>
@@ -87,7 +87,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <summary>
/// Gets a value indicating whether the response is ready to be sent to the user agent.
/// </summary>
- /// <value></value>
/// <remarks>
/// This property returns false if there are properties that must be set on this
/// request instance before the response can be sent.
@@ -101,7 +100,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <param name="extension">The extension to add to the response message.</param>
void IRequest.AddResponseExtension(IOpenIdMessageExtension extension) {
- Contract.Requires(extension != null);
+ Contract.Requires<ArgumentNullException>(extension != null);
throw new NotImplementedException();
}
@@ -124,7 +123,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// An instance of the extension initialized with values passed in with the request.
/// </returns>
IOpenIdMessageExtension IRequest.GetExtension(Type extensionType) {
- Contract.Requires(extensionType != null);
+ Contract.Requires<ArgumentNullException>(extensionType != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
index ae044aa..f141834 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/OpenIdProvider.cs
@@ -58,7 +58,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="applicationStore">The application store to use. Cannot be null.</param>
public OpenIdProvider(IProviderApplicationStore applicationStore)
: this(applicationStore, applicationStore) {
- Contract.Requires(applicationStore != null);
+ Contract.Requires<ArgumentNullException>(applicationStore != null);
Contract.Ensures(this.AssociationStore == applicationStore);
Contract.Ensures(this.SecuritySettings != null);
Contract.Ensures(this.Channel != null);
@@ -70,13 +70,11 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="associationStore">The association store to use. Cannot be null.</param>
/// <param name="nonceStore">The nonce store to use. Cannot be null.</param>
private OpenIdProvider(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore) {
- Contract.Requires(associationStore != null);
- Contract.Requires(nonceStore != null);
+ Contract.Requires<ArgumentNullException>(associationStore != null);
+ Contract.Requires<ArgumentNullException>(nonceStore != null);
Contract.Ensures(this.AssociationStore == associationStore);
Contract.Ensures(this.SecuritySettings != null);
Contract.Ensures(this.Channel != null);
- ErrorUtilities.VerifyArgumentNotNull(associationStore, "associationStore");
- ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
this.AssociationStore = associationStore;
this.SecuritySettings = DotNetOpenAuthSection.Configuration.OpenId.Provider.SecuritySettings.CreateSecuritySettings();
@@ -95,8 +93,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static IProviderApplicationStore HttpApplicationStore {
get {
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
Contract.Ensures(Contract.Result<IProviderApplicationStore>() != null);
- ErrorUtilities.VerifyHttpContext();
HttpContext context = HttpContext.Current;
var store = (IProviderApplicationStore)context.Application[ApplicationStoreKey];
if (store == null) {
@@ -130,8 +128,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
internal set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.securitySettings = value;
}
}
@@ -205,8 +202,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <exception cref="ProtocolException">Thrown if the incoming message is recognized
/// but deviates from the protocol specification irrecoverably.</exception>
public IRequest GetRequest(HttpRequestInfo httpRequestInfo) {
- Contract.Requires(httpRequestInfo != null);
- ErrorUtilities.VerifyArgumentNotNull(httpRequestInfo, "httpRequestInfo");
+ Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
IDirectedProtocolMessage incomingMessage = null;
try {
@@ -285,10 +281,9 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <exception cref="InvalidOperationException">Thrown if <see cref="IRequest.IsResponseReady"/> is <c>false</c>.</exception>
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code Contract requires that we cast early.")]
public void SendResponse(IRequest request) {
- Contract.Requires(HttpContext.Current != null);
- Contract.Requires(request != null);
- Contract.Requires(((Request)request).IsResponseReady);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null, MessagingStrings.CurrentHttpContextRequired);
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(((Request)request).IsResponseReady);
this.ApplyBehaviorsToResponse(request);
Request requestInternal = (Request)request;
@@ -303,9 +298,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <exception cref="InvalidOperationException">Thrown if <see cref="IRequest.IsResponseReady"/> is <c>false</c>.</exception>
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code Contract requires that we cast early.")]
public OutgoingWebResponse PrepareResponse(IRequest request) {
- Contract.Requires(request != null);
- Contract.Requires(((Request)request).IsResponseReady);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentException>(((Request)request).IsResponseReady);
this.ApplyBehaviorsToResponse(request);
Request requestInternal = (Request)request;
@@ -328,12 +322,12 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// be the same as <paramref name="claimedIdentifier"/>.</param>
/// <param name="extensions">The extensions.</param>
public void SendUnsolicitedAssertion(Uri providerEndpoint, Realm relyingParty, Identifier claimedIdentifier, Identifier localIdentifier, params IExtensionMessage[] extensions) {
- Contract.Requires(HttpContext.Current != null);
- Contract.Requires(providerEndpoint != null);
- Contract.Requires(providerEndpoint.IsAbsoluteUri);
- Contract.Requires(relyingParty != null);
- Contract.Requires(claimedIdentifier != null);
- Contract.Requires(localIdentifier != null);
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null, MessagingStrings.HttpContextRequired);
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
+ Contract.Requires<ArgumentException>(providerEndpoint.IsAbsoluteUri);
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
+ Contract.Requires<ArgumentNullException>(claimedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(localIdentifier != null);
this.PrepareUnsolicitedAssertion(providerEndpoint, relyingParty, claimedIdentifier, localIdentifier, extensions).Send();
}
@@ -358,16 +352,12 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// the user agent to allow the redirect with assertion to happen.
/// </returns>
public OutgoingWebResponse PrepareUnsolicitedAssertion(Uri providerEndpoint, Realm relyingParty, Identifier claimedIdentifier, Identifier localIdentifier, params IExtensionMessage[] extensions) {
- Contract.Requires(providerEndpoint != null);
- Contract.Requires(providerEndpoint.IsAbsoluteUri);
- Contract.Requires(relyingParty != null);
- Contract.Requires(claimedIdentifier != null);
- Contract.Requires(localIdentifier != null);
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
- ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
- ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(localIdentifier, "localIdentifier");
- ErrorUtilities.VerifyArgumentNamed(providerEndpoint.IsAbsoluteUri, "providerEndpoint", OpenIdStrings.AbsoluteUriRequired);
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
+ Contract.Requires<ArgumentException>(providerEndpoint.IsAbsoluteUri);
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
+ Contract.Requires<ArgumentNullException>(claimedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(localIdentifier != null);
+ Contract.Requires<InvalidOperationException>(this.Channel.WebRequestHandler != null);
// Although the RP should do their due diligence to make sure that this OP
// is authorized to send an assertion for the given claimed identifier,
@@ -466,10 +456,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// Either the <see cref="IRequest"/> to return to the host site or null to indicate no response could be reasonably created and that the caller should rethrow the exception.
/// </returns>
private IRequest GetErrorResponse(ProtocolException ex, HttpRequestInfo httpRequestInfo, IDirectedProtocolMessage incomingMessage) {
- Contract.Requires(ex != null);
- Contract.Requires(httpRequestInfo != null);
- ErrorUtilities.VerifyArgumentNotNull(ex, "ex");
- ErrorUtilities.VerifyArgumentNotNull(httpRequestInfo, "httpRequestInfo");
+ Contract.Requires<ArgumentNullException>(ex != null);
+ Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
Logger.OpenId.Error("An exception was generated while processing an incoming OpenID request.", ex);
IErrorMessage errorMessage;
diff --git a/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs b/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs
index 399a84f..260fc85 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/PrivatePersonalIdentifierProviderBase.cs
@@ -35,8 +35,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <param name="baseIdentifier">The base URI on which to append the anonymous part.</param>
protected PrivatePersonalIdentifierProviderBase(Uri baseIdentifier) {
- Contract.Requires(baseIdentifier != null);
- ErrorUtilities.VerifyArgumentNotNull(baseIdentifier, "baseIdentifier");
+ Contract.Requires<ArgumentNullException>(baseIdentifier != null);
this.Hasher = HashAlgorithm.Create(HashAlgorithmName);
this.Encoder = Encoding.UTF8;
@@ -103,8 +102,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
set {
- Contract.Requires(value > 0);
- ErrorUtilities.VerifyArgumentInRange(value > 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value > 0);
this.newSaltLength = value;
}
}
@@ -122,10 +120,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// openid.claimed_id and openid.local_id parameters. Must not be null.
/// </returns>
public Uri GetIdentifier(Identifier localIdentifier, Realm relyingPartyRealm) {
- ErrorUtilities.VerifyArgumentNotNull(localIdentifier, "localIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(relyingPartyRealm, "relyingPartyRealm");
- ErrorUtilities.VerifyArgumentNamed(this.IsUserLocalIdentifier(localIdentifier), "localIdentifier", OpenIdStrings.ArgumentIsPpidIdentifier);
-
byte[] salt = this.GetHashSaltForLocalIdentifier(localIdentifier);
string valueToHash = localIdentifier + "#";
switch (this.PairwiseUnique) {
@@ -187,8 +181,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <returns>The full PPID Identifier.</returns>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "NOT equivalent overload. The recommended one breaks on relative URIs.")]
protected virtual Uri AppendIdentifiers(string uriHash) {
- Contract.Requires(!String.IsNullOrEmpty(uriHash));
- ErrorUtilities.VerifyNonZeroLength(uriHash, "uriHash");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(uriHash));
if (string.IsNullOrEmpty(this.BaseIdentifier.Query)) {
// The uriHash will appear on the path itself.
diff --git a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
index 49d18e0..f778b76 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/ProviderEndpoint.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
using System;
using System.Collections.Generic;
using System.ComponentModel;
+ using System.Diagnostics.Contracts;
using System.Text;
using System.Web;
using System.Web.UI;
@@ -67,7 +68,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
}
set {
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
provider = value;
}
}
diff --git a/src/DotNetOpenAuth/OpenId/Provider/Request.cs b/src/DotNetOpenAuth/OpenId/Provider/Request.cs
index 43697b2..1c3eb86 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/Request.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/Request.cs
@@ -54,10 +54,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="request">The incoming request message.</param>
/// <param name="securitySettings">The security settings from the channel.</param>
protected Request(IDirectedProtocolMessage request, ProviderSecuritySettings securitySettings) {
- Contract.Requires(request != null);
- Contract.Requires(securitySettings != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.request = request;
this.SecuritySettings = securitySettings;
@@ -71,10 +69,8 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <param name="version">The version.</param>
/// <param name="securitySettings">The security settings.</param>
protected Request(Version version, ProviderSecuritySettings securitySettings) {
- Contract.Requires(version != null);
- Contract.Requires(securitySettings != null);
- ErrorUtilities.VerifyArgumentNotNull(version, "version");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(version != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.protocolVersion = version;
this.SecuritySettings = securitySettings;
@@ -103,10 +99,9 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// <exception cref="InvalidOperationException">Thrown if <see cref="IsResponseReady"/> is <c>false</c>.</exception>
internal IProtocolMessage Response {
get {
- Contract.Requires(this.IsResponseReady);
+ Contract.Requires<InvalidOperationException>(this.IsResponseReady, OpenIdStrings.ResponseNotReady);
Contract.Ensures(Contract.Result<IProtocolMessage>() != null);
- ErrorUtilities.VerifyOperation(this.IsResponseReady, OpenIdStrings.ResponseNotReady);
if (this.responseExtensions.Count > 0) {
var extensibleResponse = this.ResponseMessage as IProtocolMessageWithExtensions;
ErrorUtilities.VerifyOperation(extensibleResponse != null, MessagingStrings.MessageNotExtensible, this.ResponseMessage.GetType().Name);
@@ -161,8 +156,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
/// <param name="extension">The extension to add to the response message.</param>
public void AddResponseExtension(IOpenIdMessageExtension extension) {
- ErrorUtilities.VerifyArgumentNotNull(extension, "extension");
-
// Because the derived AuthenticationRequest class can swap out
// one response message for another (auth vs. no-auth), and because
// some response messages support extensions while others don't,
@@ -194,7 +187,6 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// An instance of the extension initialized with values passed in with the request.
/// </returns>
public IOpenIdMessageExtension GetExtension(Type extensionType) {
- ErrorUtilities.VerifyArgumentNotNull(extensionType, "extensionType");
if (this.extensibleMessage != null) {
return this.extensibleMessage.Extensions.OfType<IOpenIdMessageExtension>().Where(ext => extensionType.IsInstanceOfType(ext)).SingleOrDefault();
} else {
diff --git a/src/DotNetOpenAuth/OpenId/Provider/RequestContract.cs b/src/DotNetOpenAuth/OpenId/Provider/RequestContract.cs
index b94b37d..dee140e 100644
--- a/src/DotNetOpenAuth/OpenId/Provider/RequestContract.cs
+++ b/src/DotNetOpenAuth/OpenId/Provider/RequestContract.cs
@@ -39,7 +39,7 @@ namespace DotNetOpenAuth.OpenId.Provider {
/// </summary>
protected override IProtocolMessage ResponseMessage {
get {
- Contract.Requires(this.IsResponseReady);
+ Contract.Requires<InvalidOperationException>(this.IsResponseReady);
Contract.Ensures(Contract.Result<IProtocolMessage>() != null);
throw new NotImplementedException();
}
diff --git a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
index 0751f51..2014df4 100644
--- a/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
+++ b/src/DotNetOpenAuth/OpenId/ProviderEndpointDescription.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+ using System.Diagnostics.Contracts;
using System.Linq;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
@@ -27,8 +28,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="providerEndpoint">The OpenID Provider endpoint URL.</param>
/// <param name="openIdVersion">The OpenID version supported by this particular endpoint.</param>
internal ProviderEndpointDescription(Uri providerEndpoint, Version openIdVersion) {
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
- ErrorUtilities.VerifyArgumentNotNull(openIdVersion, "version");
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
+ Contract.Requires<ArgumentNullException>(openIdVersion != null);
this.Endpoint = providerEndpoint;
this.ProtocolVersion = openIdVersion;
@@ -40,8 +41,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="providerEndpoint">The URI the provider listens on for OpenID requests.</param>
/// <param name="serviceTypeURIs">The set of services offered by this endpoint.</param>
internal ProviderEndpointDescription(Uri providerEndpoint, IEnumerable<string> serviceTypeURIs) {
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
- ErrorUtilities.VerifyArgumentNotNull(serviceTypeURIs, "serviceTypeURIs");
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
+ Contract.Requires<ArgumentNullException>(serviceTypeURIs != null);
this.Endpoint = providerEndpoint;
this.Capabilities = new ReadOnlyCollection<string>(serviceTypeURIs.ToList());
@@ -130,8 +131,6 @@ namespace DotNetOpenAuth.OpenId {
/// the extension in the request and see if a response comes back for that extension.
/// </remarks>
public bool IsExtensionSupported(Type extensionType) {
- ErrorUtilities.VerifyArgumentNotNull(extensionType, "extensionType");
- ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName);
var extension = (IOpenIdMessageExtension)Activator.CreateInstance(extensionType);
return this.IsExtensionSupported(extension);
}
@@ -146,8 +145,8 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the extension is supported; otherwise, <c>false</c>.
/// </returns>
protected internal bool IsExtensionSupported(string extensionUri) {
- ErrorUtilities.VerifyNonZeroLength(extensionUri, "extensionUri");
- ErrorUtilities.VerifyOperation(this.Capabilities != null, OpenIdStrings.ExtensionLookupSupportUnavailable);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(extensionUri));
+ Contract.Requires<InvalidOperationException>(this.Capabilities != null, OpenIdStrings.ExtensionLookupSupportUnavailable);
return this.Capabilities.Contains(extensionUri);
}
@@ -159,7 +158,7 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the extension is supported by this endpoint; otherwise, <c>false</c>.
/// </returns>
protected internal bool IsExtensionSupported(IOpenIdMessageExtension extension) {
- ErrorUtilities.VerifyArgumentNotNull(extension, "extension");
+ Contract.Requires<ArgumentNullException>(extension != null);
// Consider the primary case.
if (this.IsExtensionSupported(extension.TypeUri)) {
diff --git a/src/DotNetOpenAuth/OpenId/Realm.cs b/src/DotNetOpenAuth/OpenId/Realm.cs
index 2859cf0..fb0fbfb 100644
--- a/src/DotNetOpenAuth/OpenId/Realm.cs
+++ b/src/DotNetOpenAuth/OpenId/Realm.cs
@@ -62,7 +62,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="realmUrl">The realm URL to use in the new instance.</param>
[SuppressMessage("Microsoft.Design", "CA1057:StringUriOverloadsCallSystemUriOverloads", Justification = "Not all realms are valid URLs (because of wildcards).")]
public Realm(string realmUrl) {
- ErrorUtilities.VerifyArgumentNotNull(realmUrl, "realmUrl"); // not non-zero check so we throw UriFormatException later
+ Contract.Requires<ArgumentNullException>(realmUrl != null); // not non-zero check so we throw UriFormatException later
this.DomainWildcard = Regex.IsMatch(realmUrl, WildcardDetectionPattern);
this.uri = new Uri(Regex.Replace(realmUrl, WildcardDetectionPattern, m => m.Groups[1].Value));
if (!this.uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase) &&
@@ -77,7 +77,7 @@ namespace DotNetOpenAuth.OpenId {
/// </summary>
/// <param name="realmUrl">The realm URL of the Relying Party.</param>
public Realm(Uri realmUrl) {
- ErrorUtilities.VerifyArgumentNotNull(realmUrl, "realmUrl");
+ Contract.Requires<ArgumentNullException>(realmUrl != null);
this.uri = realmUrl;
if (!this.uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase) &&
!this.uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)) {
@@ -418,6 +418,18 @@ namespace DotNetOpenAuth.OpenId {
return null;
}
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ protected void ObjectInvariant() {
+ Contract.Invariant(this.uri != null);
+ Contract.Invariant(this.uri.AbsoluteUri != null);
+ }
+#endif
+
/// <summary>
/// Calls <see cref="UriBuilder.ToString"/> if the argument is non-null.
/// Otherwise throws <see cref="ArgumentNullException"/>.
@@ -431,24 +443,12 @@ namespace DotNetOpenAuth.OpenId {
/// when we should be throwing an <see cref="ArgumentNullException"/>.
/// </remarks>
private static string SafeUriBuilderToString(UriBuilder realmUriBuilder) {
- ErrorUtilities.VerifyArgumentNotNull(realmUriBuilder, "realmUriBuilder");
+ Contract.Requires<ArgumentNullException>(realmUriBuilder != null);
// Note: we MUST use ToString. Uri property throws if wildcard is present.
// Note that Uri.ToString() should generally be avoided, but UriBuilder.ToString()
// is safe: http://blog.nerdbank.net/2008/04/uriabsoluteuri-and-uritostring-are-not.html
return realmUriBuilder.ToString();
}
-
-#if CONTRACTS_FULL
- /// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
- [ContractInvariantMethod]
- private void ObjectInvariant() {
- Contract.Invariant(this.uri != null);
- Contract.Invariant(this.uri.AbsoluteUri != null);
- }
-#endif
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs
index 85c0096..d3e0686 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AssociationManager.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Net;
using System.Text;
@@ -40,8 +41,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="associationStore">The association store. May be null for dumb mode relying parties.</param>
/// <param name="securitySettings">The security settings.</param>
internal AssociationManager(Channel channel, IAssociationStore<Uri> associationStore, RelyingPartySecuritySettings securitySettings) {
- ErrorUtilities.VerifyArgumentNotNull(channel, "channel");
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
+ Contract.Requires<ArgumentNullException>(channel != null);
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
this.channel = channel;
this.associationStore = associationStore;
@@ -58,7 +59,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.channel = value;
}
}
@@ -72,7 +73,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.securitySettings = value;
}
}
@@ -95,7 +96,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="provider">The provider to create an association with.</param>
/// <returns>The association if one exists and has useful life remaining. Otherwise <c>null</c>.</returns>
internal Association GetExistingAssociation(ProviderEndpointDescription provider) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(provider != null);
// If the RP has no application store for associations, there's no point in creating one.
if (this.associationStore == null) {
@@ -140,7 +141,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Any new association is automatically added to the <see cref="associationStore"/>.
/// </remarks>
private Association CreateNewAssociation(ProviderEndpointDescription provider) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(provider != null);
// If there is no association store, there is no point in creating an association.
if (this.associationStore == null) {
@@ -164,7 +165,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// the given Provider given the current security settings.
/// </returns>
private Association CreateNewAssociation(ProviderEndpointDescription provider, AssociateRequest associateRequest, int retriesRemaining) {
- ErrorUtilities.VerifyArgumentNotNull(provider, "provider");
+ Contract.Requires<ArgumentNullException>(provider != null);
if (associateRequest == null || retriesRemaining < 0) {
// this can happen if security requirements and protocol conflict
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
index cea7d21..f1851a0 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs
@@ -55,6 +55,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private Dictionary<string, string> returnToArgs = new Dictionary<string, string>();
/// <summary>
+ /// A value indicating whether the return_to callback arguments must be signed.
+ /// </summary>
+ /// <remarks>
+ /// This field defaults to false, but is set to true as soon as the first callback argument
+ /// is added that indicates it must be signed. At which point, all arguments are signed
+ /// even if individual ones did not need to be.
+ /// </remarks>
+ private bool returnToArgsMustBeSigned;
+
+ /// <summary>
/// Initializes a new instance of the <see cref="AuthenticationRequest"/> class.
/// </summary>
/// <param name="endpoint">The endpoint that describes the OpenID Identifier and Provider that will complete the authentication.</param>
@@ -62,10 +72,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="returnToUrl">The base return_to URL that the Provider should return the user to to complete authentication. This should not include callback parameters as these should be added using the <see cref="AddCallbackArguments(string, string)"/> method.</param>
/// <param name="relyingParty">The relying party that created this instance.</param>
private AuthenticationRequest(ServiceEndpoint endpoint, Realm realm, Uri returnToUrl, OpenIdRelyingParty relyingParty) {
- ErrorUtilities.VerifyArgumentNotNull(endpoint, "endpoint");
- ErrorUtilities.VerifyArgumentNotNull(realm, "realm");
- ErrorUtilities.VerifyArgumentNotNull(returnToUrl, "returnToUrl");
- ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
+ Contract.Requires<ArgumentNullException>(endpoint != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
+ Contract.Requires<ArgumentNullException>(returnToUrl != null);
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
this.endpoint = endpoint;
this.RelyingParty = relyingParty;
@@ -182,6 +192,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
get { return this.extensions; }
}
+ /// <summary>
+ /// Gets the service endpoint.
+ /// </summary>
+ internal ServiceEndpoint Endpoint {
+ get { return this.endpoint; }
+ }
+
#region IAuthenticationRequest methods
/// <summary>
@@ -199,8 +216,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
/// </remarks>
public void AddCallbackArguments(IDictionary<string, string> arguments) {
- ErrorUtilities.VerifyArgumentNotNull(arguments, "arguments");
+ ErrorUtilities.VerifyOperation(this.RelyingParty.CanSignCallbackArguments, OpenIdStrings.CallbackArgumentsRequireSecretStore, typeof(IAssociationStore<Uri>).Name, typeof(OpenIdRelyingParty).Name);
+ this.returnToArgsMustBeSigned = true;
foreach (var pair in arguments) {
ErrorUtilities.VerifyArgument(!string.IsNullOrEmpty(pair.Key), MessagingStrings.UnexpectedNullOrEmptyKey);
ErrorUtilities.VerifyArgument(pair.Value != null, MessagingStrings.UnexpectedNullValue, pair.Key);
@@ -225,18 +243,57 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
/// </remarks>
public void AddCallbackArguments(string key, string value) {
- ErrorUtilities.VerifyNonZeroLength(key, "key");
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ ErrorUtilities.VerifyOperation(this.RelyingParty.CanSignCallbackArguments, OpenIdStrings.CallbackArgumentsRequireSecretStore, typeof(IAssociationStore<Uri>).Name, typeof(OpenIdRelyingParty).Name);
+ this.returnToArgsMustBeSigned = true;
this.returnToArgs.Add(key, value);
}
/// <summary>
+ /// Makes a key/value pair available when the authentication is completed.
+ /// </summary>
+ /// <param name="key">The parameter name.</param>
+ /// <param name="value">The value of the argument. Must not be null.</param>
+ /// <remarks>
+ /// <para>Note that these values are NOT protected against tampering in transit. No
+ /// security-sensitive data should be stored using this method.</para>
+ /// <para>The value stored here can be retrieved using
+ /// <see cref="IAuthenticationResponse.GetCallbackArgument"/>.</para>
+ /// <para>Since the data set here is sent in the querystring of the request and some
+ /// servers place limits on the size of a request URL, this data should be kept relatively
+ /// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
+ /// </remarks>
+ public void SetCallbackArgument(string key, string value) {
+ ErrorUtilities.VerifyOperation(this.RelyingParty.CanSignCallbackArguments, OpenIdStrings.CallbackArgumentsRequireSecretStore, typeof(IAssociationStore<Uri>).Name, typeof(OpenIdRelyingParty).Name);
+
+ this.returnToArgsMustBeSigned = true;
+ this.returnToArgs[key] = value;
+ }
+
+ /// <summary>
+ /// Makes a key/value pair available when the authentication is completed without
+ /// requiring a return_to signature to protect against tampering of the callback argument.
+ /// </summary>
+ /// <param name="key">The parameter name.</param>
+ /// <param name="value">The value of the argument. Must not be null.</param>
+ /// <remarks>
+ /// <para>Note that these values are NOT protected against eavesdropping or tampering in transit. No
+ /// security-sensitive data should be stored using this method. </para>
+ /// <para>The value stored here can be retrieved using
+ /// <see cref="IAuthenticationResponse.GetCallbackArgument"/>.</para>
+ /// <para>Since the data set here is sent in the querystring of the request and some
+ /// servers place limits on the size of a request URL, this data should be kept relatively
+ /// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
+ /// </remarks>
+ public void SetUntrustedCallbackArgument(string key, string value) {
+ this.returnToArgs[key] = value;
+ }
+
+ /// <summary>
/// Adds an OpenID extension to the request directed at the OpenID provider.
/// </summary>
/// <param name="extension">The initialized extension to add to the request.</param>
public void AddExtension(IOpenIdMessageExtension extension) {
- ErrorUtilities.VerifyArgumentNotNull(extension, "extension");
this.extensions.Add(extension);
}
@@ -267,16 +324,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Never null, but may be empty.
/// </returns>
internal static IEnumerable<AuthenticationRequest> Create(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, bool createNewAssociationsAsNeeded) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(relyingParty != null);
- Contract.Requires(realm != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null);
- // We have a long data validation and preparation process
- ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
- ErrorUtilities.VerifyArgumentNotNull(realm, "realm");
-
// Normalize the portion of the return_to path that correlates to the realm for capitalization.
// (so that if a web app base path is /MyApp/, but the URL of this request happens to be
// /myapp/login.aspx, we bump up the return_to Url to use /MyApp/ so it matches the realm.
@@ -345,11 +397,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// before calling this method.
/// </remarks>
private static IEnumerable<AuthenticationRequest> CreateInternal(Identifier userSuppliedIdentifier, OpenIdRelyingParty relyingParty, Realm realm, Uri returnToUrl, IEnumerable<ServiceEndpoint> serviceEndpoints, bool createNewAssociationsAsNeeded) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(relyingParty != null);
- Contract.Requires(realm != null);
- Contract.Requires(serviceEndpoints != null);
- Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null);
+ // DO NOT USE CODE CONTRACTS IN THIS METHOD, since it uses yield return
+ ErrorUtilities.VerifyArgumentNotNull(userSuppliedIdentifier, "userSuppliedIdentifier");
+ ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
+ ErrorUtilities.VerifyArgumentNotNull(realm, "realm");
+ ErrorUtilities.VerifyArgumentNotNull(serviceEndpoints, "serviceEndpoints");
+ ////Contract.Ensures(Contract.Result<IEnumerable<AuthenticationRequest>>() != null);
// If shared associations are required, then we had better have an association store.
ErrorUtilities.VerifyOperation(!relyingParty.SecuritySettings.RequireAssociation || relyingParty.AssociationManager.HasAssociationStore, OpenIdStrings.AssociationStoreRequired);
@@ -415,8 +468,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="relyingParty">The relying party.</param>
/// <returns>A filtered and sorted list of endpoints; may be empty if the input was empty or the filter removed all endpoints.</returns>
private static List<ServiceEndpoint> FilterAndSortEndpoints(IEnumerable<ServiceEndpoint> endpoints, OpenIdRelyingParty relyingParty) {
- ErrorUtilities.VerifyArgumentNotNull(endpoints, "endpoints");
- ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
+ Contract.Requires<ArgumentNullException>(endpoints != null);
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
// Construct the endpoints filters based on criteria given by the host web site.
EndpointSelector versionFilter = ep => ((ServiceEndpoint)ep).Protocol.Version >= Protocol.Lookup(relyingParty.SecuritySettings.MinimumRequiredOpenIdVersion).Version;
@@ -475,9 +528,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
request.Realm = this.Realm;
request.ReturnTo = this.ReturnToUrl;
request.AssociationHandle = association != null ? association.Handle : null;
+ request.SignReturnTo = this.returnToArgsMustBeSigned;
request.AddReturnToArguments(this.returnToArgs);
if (this.endpoint.UserSuppliedIdentifier != null) {
- request.AddReturnToArguments(UserSuppliedIdentifierParameterName, this.endpoint.UserSuppliedIdentifier);
+ request.AddReturnToArguments(UserSuppliedIdentifierParameterName, this.endpoint.UserSuppliedIdentifier.OriginalString);
}
foreach (IOpenIdMessageExtension extension in this.extensions) {
request.Extensions.Add(extension);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/Controls.cd b/src/DotNetOpenAuth/OpenId/RelyingParty/Controls.cd
new file mode 100644
index 0000000..f96db36
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/Controls.cd
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyAjaxControlBase">
+ <Position X="0.5" Y="9.75" Width="3" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>BARAAAAAAAAAAACQAAAAAAAEAAAgAAAAAQAFAAAAAFk=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdRelyingPartyAjaxControlBase.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdMobileTextBox">
+ <Position X="8.5" Y="5.25" Width="2.5" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>AI0JADgFQRQQDAIw4lAYSEIWCAMZhMVlELAASQIAgSI=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdMobileTextBox.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdLogin">
+ <Position X="6.25" Y="1.25" Width="1.75" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <NestedTypes>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdLogin.InPlaceControl" Collapsed="true">
+ <TypeIdentifier>
+ <NewMemberFileName>OpenId\RelyingParty\OpenIdLogin.cs</NewMemberFileName>
+ </TypeIdentifier>
+ </Class>
+ </NestedTypes>
+ <TypeIdentifier>
+ <HashCode>gIMgADAIAQEQIJAYOQBSADiQBgiIECk0jQCggdAp4BQ=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdLogin.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox">
+ <Position X="3.75" Y="10" Width="2.25" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>ACBEEbABZzOzAKCYJNOEwM3uSIR5AAOkUFANCQ7DsVs=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdAjaxTextBox.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdButton">
+ <Position X="8.75" Y="1" Width="1.75" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <InheritanceLine Type="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="2.875" Y="0.5" />
+ <Point X="7.194" Y="0.5" />
+ <Point X="7.194" Y="1" />
+ <Point X="8.75" Y="1" />
+ </Path>
+ </InheritanceLine>
+ <TypeIdentifier>
+ <HashCode>BAAEQAAAAAAAAAACAAAgAAAAAIAAAACQABAECABAAAA=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdButton.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdTextBox">
+ <Position X="3.5" Y="1.25" Width="2.25" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <TypeIdentifier>
+ <HashCode>AIEVQjgBIxYITIARcAAACEc2CIAIlER1CBAQSQoEpCg=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdTextBox.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase">
+ <Position X="0.5" Y="0.5" Width="2.5" />
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <NestedTypes>
+ <Enum Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.LoginSiteNotification" Collapsed="true">
+ <TypeIdentifier>
+ <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
+ </TypeIdentifier>
+ </Enum>
+ <Enum Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.LoginPersistence" Collapsed="true">
+ <TypeIdentifier>
+ <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
+ </TypeIdentifier>
+ </Enum>
+ <Class Name="DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingPartyControlBase.DuplicateRequestedHostsComparer" Collapsed="true">
+ <TypeIdentifier>
+ <NewMemberFileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</NewMemberFileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ </NestedTypes>
+ <TypeIdentifier>
+ <HashCode>BA0AAsAAQCAwQAJAoFAWwADSAgE5EIEEEbAGSAwAgfI=</HashCode>
+ <FileName>OpenId\RelyingParty\OpenIdRelyingPartyControlBase.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/FailedAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/FailedAuthenticationResponse.cs
index 45f7f54..f899f03 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/FailedAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/FailedAuthenticationResponse.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text;
using System.Web;
@@ -27,7 +28,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="exception">The exception that resulted in the failed authentication.</param>
internal FailedAuthenticationResponse(Exception exception) {
- ErrorUtilities.VerifyArgumentNotNull(exception, "exception");
+ Contract.Requires<ArgumentNullException>(exception != null);
this.Exception = exception;
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs
index c97654a..3808c85 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequest.cs
@@ -7,6 +7,8 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
@@ -16,6 +18,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// requests that may be queried/modified in specific ways before being
/// routed to the OpenID Provider.
/// </summary>
+ [ContractClass(typeof(IAuthenticationRequestContract))]
public interface IAuthenticationRequest {
/// <summary>
/// Gets or sets the mode the Provider should use during authentication.
@@ -127,6 +130,39 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
void AddCallbackArguments(string key, string value);
/// <summary>
+ /// Makes a key/value pair available when the authentication is completed.
+ /// </summary>
+ /// <param name="key">The parameter name.</param>
+ /// <param name="value">The value of the argument. Must not be null.</param>
+ /// <remarks>
+ /// <para>Note that these values are NOT protected against eavesdropping in transit. No
+ /// security-sensitive data should be stored using this method.</para>
+ /// <para>The value stored here can be retrieved using
+ /// <see cref="IAuthenticationResponse.GetCallbackArgument"/>.</para>
+ /// <para>Since the data set here is sent in the querystring of the request and some
+ /// servers place limits on the size of a request URL, this data should be kept relatively
+ /// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
+ /// </remarks>
+ void SetCallbackArgument(string key, string value);
+
+ /// <summary>
+ /// Makes a key/value pair available when the authentication is completed without
+ /// requiring a return_to signature to protect against tampering of the callback argument.
+ /// </summary>
+ /// <param name="key">The parameter name.</param>
+ /// <param name="value">The value of the argument. Must not be null.</param>
+ /// <remarks>
+ /// <para>Note that these values are NOT protected against eavesdropping or tampering in transit. No
+ /// security-sensitive data should be stored using this method. </para>
+ /// <para>The value stored here can be retrieved using
+ /// <see cref="IAuthenticationResponse.GetCallbackArgument"/>.</para>
+ /// <para>Since the data set here is sent in the querystring of the request and some
+ /// servers place limits on the size of a request URL, this data should be kept relatively
+ /// small to ensure successful authentication. About 1.5KB is about all that should be stored.</para>
+ /// </remarks>
+ void SetUntrustedCallbackArgument(string key, string value);
+
+ /// <summary>
/// Adds an OpenID extension to the request directed at the OpenID provider.
/// </summary>
/// <param name="extension">The initialized extension to add to the request.</param>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs
new file mode 100644
index 0000000..41cc4e9
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationRequestContract.cs
@@ -0,0 +1,96 @@
+// <auto-generated />
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId.Messages;
+
+ [ContractClassFor(typeof(IAuthenticationRequest))]
+ internal abstract class IAuthenticationRequestContract : IAuthenticationRequest {
+ #region IAuthenticationRequest Members
+
+ AuthenticationRequestMode IAuthenticationRequest.Mode {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ OutgoingWebResponse IAuthenticationRequest.RedirectingResponse {
+ get { throw new NotImplementedException(); }
+ }
+
+ Uri IAuthenticationRequest.ReturnToUrl {
+ get { throw new NotImplementedException(); }
+ }
+
+ Realm IAuthenticationRequest.Realm {
+ get { throw new NotImplementedException(); }
+ }
+
+ Identifier IAuthenticationRequest.ClaimedIdentifier {
+ get { throw new NotImplementedException(); }
+ }
+
+ bool IAuthenticationRequest.IsDirectedIdentity {
+ get { throw new NotImplementedException(); }
+ }
+
+ bool IAuthenticationRequest.IsExtensionOnly {
+ get {
+ throw new NotImplementedException();
+ }
+
+ set {
+ throw new NotImplementedException();
+ }
+ }
+
+ IProviderEndpoint IAuthenticationRequest.Provider {
+ get { throw new NotImplementedException(); }
+ }
+
+ void IAuthenticationRequest.AddCallbackArguments(IDictionary<string, string> arguments) {
+ Contract.Requires<ArgumentNullException>(arguments != null);
+ Contract.Requires<ArgumentException>(arguments.Keys.All(k => !String.IsNullOrEmpty(k)));
+ Contract.Requires<ArgumentException>(arguments.Values.All(v => v != null));
+ throw new NotImplementedException();
+ }
+
+ void IAuthenticationRequest.AddCallbackArguments(string key, string value) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(key));
+ Contract.Requires<ArgumentNullException>(value != null);
+ throw new NotImplementedException();
+ }
+
+ void IAuthenticationRequest.SetCallbackArgument(string key, string value) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(key));
+ Contract.Requires<ArgumentNullException>(value != null);
+ throw new NotImplementedException();
+ }
+
+ void IAuthenticationRequest.AddExtension(IOpenIdMessageExtension extension) {
+ Contract.Requires<ArgumentNullException>(extension != null);
+ throw new NotImplementedException();
+ }
+
+ void IAuthenticationRequest.RedirectToProvider() {
+ throw new NotImplementedException();
+ }
+
+ void IAuthenticationRequest.SetUntrustedCallbackArgument(string key, string value) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(key));
+ Contract.Requires<ArgumentNullException>(value != null);
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationResponse.cs
index fd35a6b..a24220f 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IAuthenticationResponse.cs
@@ -8,6 +8,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
using System.Text;
using System.Web;
using DotNetOpenAuth.OpenId.Extensions;
@@ -24,6 +26,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// assertions. This interface does not offer a way to discern between
/// solicited and unsolicited assertions as they should be treated equally.
/// </remarks>
+ [ContractClass(typeof(IAuthenticationResponseContract))]
public interface IAuthenticationResponse {
/// <summary>
/// Gets the Identifier that the end user claims to own. For use with user database storage and lookup.
@@ -251,4 +254,279 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
IOpenIdMessageExtension GetUntrustedExtension(Type extensionType);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IAuthenticationResponse"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IAuthenticationResponse))]
+ internal abstract class IAuthenticationResponseContract : IAuthenticationResponse {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IAuthenticationResponseContract"/> class.
+ /// </summary>
+ protected IAuthenticationResponseContract() {
+ }
+
+ #region IAuthenticationResponse Members
+
+ /// <summary>
+ /// Gets the Identifier that the end user claims to own. For use with user database storage and lookup.
+ /// May be null for some failed authentications (i.e. failed directed identity authentications).
+ /// </summary>
+ /// <value></value>
+ /// <remarks>
+ /// <para>
+ /// This is the secure identifier that should be used for database storage and lookup.
+ /// It is not always friendly (i.e. =Arnott becomes =!9B72.7DD1.50A9.5CCD), but it protects
+ /// user identities against spoofing and other attacks.
+ /// </para>
+ /// <para>
+ /// For user-friendly identifiers to display, use the
+ /// <see cref="IAuthenticationResponse.FriendlyIdentifierForDisplay"/> property.
+ /// </para>
+ /// </remarks>
+ Identifier IAuthenticationResponse.ClaimedIdentifier {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets a user-friendly OpenID Identifier for display purposes ONLY.
+ /// </summary>
+ /// <value></value>
+ /// <remarks>
+ /// <para>
+ /// This <i>should</i> be put through <see cref="HttpUtility.HtmlEncode(string)"/> before
+ /// sending to a browser to secure against javascript injection attacks.
+ /// </para>
+ /// <para>
+ /// This property retains some aspects of the user-supplied identifier that get lost
+ /// in the <see cref="IAuthenticationResponse.ClaimedIdentifier"/>. For example, XRIs used as user-supplied
+ /// identifiers (i.e. =Arnott) become unfriendly unique strings (i.e. =!9B72.7DD1.50A9.5CCD).
+ /// For display purposes, such as text on a web page that says "You're logged in as ...",
+ /// this property serves to provide the =Arnott string, or whatever else is the most friendly
+ /// string close to what the user originally typed in.
+ /// </para>
+ /// <para>
+ /// If the user-supplied identifier is a URI, this property will be the URI after all
+ /// redirects, and with the protocol and fragment trimmed off.
+ /// If the user-supplied identifier is an XRI, this property will be the original XRI.
+ /// If the user-supplied identifier is an OpenID Provider identifier (i.e. yahoo.com),
+ /// this property will be the Claimed Identifier, with the protocol stripped if it is a URI.
+ /// </para>
+ /// <para>
+ /// It is <b>very</b> important that this property <i>never</i> be used for database storage
+ /// or lookup to avoid identity spoofing and other security risks. For database storage
+ /// and lookup please use the <see cref="IAuthenticationResponse.ClaimedIdentifier"/> property.
+ /// </para>
+ /// </remarks>
+ string IAuthenticationResponse.FriendlyIdentifierForDisplay {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the detailed success or failure status of the authentication attempt.
+ /// </summary>
+ /// <value></value>
+ AuthenticationStatus IAuthenticationResponse.Status {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets information about the OpenId Provider, as advertised by the
+ /// OpenID discovery documents found at the <see cref="IAuthenticationResponse.ClaimedIdentifier"/>
+ /// location, if available.
+ /// </summary>
+ /// <value>
+ /// The Provider endpoint that issued the positive assertion;
+ /// or <c>null</c> if information about the Provider is unavailable.
+ /// </value>
+ IProviderEndpoint IAuthenticationResponse.Provider {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the details regarding a failed authentication attempt, if available.
+ /// This will be set if and only if <see cref="IAuthenticationResponse.Status"/> is <see cref="AuthenticationStatus.Failed"/>.
+ /// </summary>
+ /// <value></value>
+ Exception IAuthenticationResponse.Exception {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets a callback argument's value that was previously added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/>.
+ /// </summary>
+ /// <param name="key">The name of the parameter whose value is sought.</param>
+ /// <returns>
+ /// The value of the argument, or null if the named parameter could not be found.
+ /// </returns>
+ /// <remarks>
+ /// <para>This may return any argument on the querystring that came with the authentication response,
+ /// which may include parameters not explicitly added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/>.</para>
+ /// <para>Note that these values are NOT protected against tampering in transit.</para>
+ /// </remarks>
+ string IAuthenticationResponse.GetCallbackArgument(string key) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(key));
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets all the callback arguments that were previously added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/> or as a natural part
+ /// of the return_to URL.
+ /// </summary>
+ /// <returns>A name-value dictionary. Never null.</returns>
+ /// <remarks>
+ /// <para>This MAY return any argument on the querystring that came with the authentication response,
+ /// which may include parameters not explicitly added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/>.</para>
+ /// <para>Note that these values are NOT protected against tampering in transit.</para>
+ /// </remarks>
+ IDictionary<string, string> IAuthenticationResponse.GetCallbackArguments() {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Tries to get an OpenID extension that may be present in the response.
+ /// </summary>
+ /// <typeparam name="T">The type of extension to look for in the response message.</typeparam>
+ /// <returns>
+ /// The extension, if it is found. Null otherwise.
+ /// </returns>
+ /// <remarks>
+ /// <para>Extensions are returned only if the Provider signed them.
+ /// Relying parties that do not care if the values were modified in
+ /// transit should use the <see cref="IAuthenticationResponse.GetUntrustedExtension&lt;T&gt;"/> method
+ /// in order to allow the Provider to not sign the extension. </para>
+ /// <para>Unsigned extensions are completely unreliable and should be
+ /// used only to prefill user forms since the user or any other third
+ /// party may have tampered with the data carried by the extension.</para>
+ /// <para>Signed extensions are only reliable if the relying party
+ /// trusts the OpenID Provider that signed them. Signing does not mean
+ /// the relying party can trust the values -- it only means that the values
+ /// have not been tampered with since the Provider sent the message.</para>
+ /// </remarks>
+ T IAuthenticationResponse.GetExtension<T>() {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Tries to get an OpenID extension that may be present in the response.
+ /// </summary>
+ /// <param name="extensionType">Type of the extension to look for in the response.</param>
+ /// <returns>
+ /// The extension, if it is found. Null otherwise.
+ /// </returns>
+ /// <remarks>
+ /// <para>Extensions are returned only if the Provider signed them.
+ /// Relying parties that do not care if the values were modified in
+ /// transit should use the <see cref="IAuthenticationResponse.GetUntrustedExtension"/> method
+ /// in order to allow the Provider to not sign the extension. </para>
+ /// <para>Unsigned extensions are completely unreliable and should be
+ /// used only to prefill user forms since the user or any other third
+ /// party may have tampered with the data carried by the extension.</para>
+ /// <para>Signed extensions are only reliable if the relying party
+ /// trusts the OpenID Provider that signed them. Signing does not mean
+ /// the relying party can trust the values -- it only means that the values
+ /// have not been tampered with since the Provider sent the message.</para>
+ /// </remarks>
+ IOpenIdMessageExtension IAuthenticationResponse.GetExtension(Type extensionType) {
+ Contract.Requires<ArgumentNullException>(extensionType != null);
+ Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType));
+ ////ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), string.Format(CultureInfo.CurrentCulture, OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName));
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Tries to get an OpenID extension that may be present in the response, without
+ /// requiring it to be signed by the Provider.
+ /// </summary>
+ /// <typeparam name="T">The type of extension to look for in the response message.</typeparam>
+ /// <returns>
+ /// The extension, if it is found. Null otherwise.
+ /// </returns>
+ /// <remarks>
+ /// <para>Extensions are returned whether they are signed or not.
+ /// Use the <see cref="IAuthenticationResponse.GetExtension&lt;T&gt;"/> method to retrieve
+ /// extension responses only if they are signed by the Provider to
+ /// protect against tampering. </para>
+ /// <para>Unsigned extensions are completely unreliable and should be
+ /// used only to prefill user forms since the user or any other third
+ /// party may have tampered with the data carried by the extension.</para>
+ /// <para>Signed extensions are only reliable if the relying party
+ /// trusts the OpenID Provider that signed them. Signing does not mean
+ /// the relying party can trust the values -- it only means that the values
+ /// have not been tampered with since the Provider sent the message.</para>
+ /// </remarks>
+ T IAuthenticationResponse.GetUntrustedExtension<T>() {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Tries to get an OpenID extension that may be present in the response, without
+ /// requiring it to be signed by the Provider.
+ /// </summary>
+ /// <param name="extensionType">Type of the extension to look for in the response.</param>
+ /// <returns>
+ /// The extension, if it is found. Null otherwise.
+ /// </returns>
+ /// <remarks>
+ /// <para>Extensions are returned whether they are signed or not.
+ /// Use the <see cref="IAuthenticationResponse.GetExtension"/> method to retrieve
+ /// extension responses only if they are signed by the Provider to
+ /// protect against tampering. </para>
+ /// <para>Unsigned extensions are completely unreliable and should be
+ /// used only to prefill user forms since the user or any other third
+ /// party may have tampered with the data carried by the extension.</para>
+ /// <para>Signed extensions are only reliable if the relying party
+ /// trusts the OpenID Provider that signed them. Signing does not mean
+ /// the relying party can trust the values -- it only means that the values
+ /// have not been tampered with since the Provider sent the message.</para>
+ /// </remarks>
+ IOpenIdMessageExtension IAuthenticationResponse.GetUntrustedExtension(Type extensionType) {
+ Contract.Requires<ArgumentNullException>(extensionType != null);
+ Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType));
+ ////ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), string.Format(CultureInfo.CurrentCulture, OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName));
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets a callback argument's value that was previously added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/>.
+ /// </summary>
+ /// <param name="key">The name of the parameter whose value is sought.</param>
+ /// <returns>
+ /// The value of the argument, or null if the named parameter could not be found.
+ /// </returns>
+ /// <remarks>
+ /// Callback parameters are only available even if the RP is in stateless mode,
+ /// or the callback parameters are otherwise unverifiable as untampered with.
+ /// Therefore, use this method only when the callback argument is not to be
+ /// used to make a security-sensitive decision.
+ /// </remarks>
+ string IAuthenticationResponse.GetUntrustedCallbackArgument(string key) {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(key));
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Gets all the callback arguments that were previously added using
+ /// <see cref="IAuthenticationRequest.AddCallbackArguments(string, string)"/> or as a natural part
+ /// of the return_to URL.
+ /// </summary>
+ /// <returns>A name-value dictionary. Never null.</returns>
+ /// <remarks>
+ /// Callback parameters are only available even if the RP is in stateless mode,
+ /// or the callback parameters are otherwise unverifiable as untampered with.
+ /// Therefore, use this method only when the callback argument is not to be
+ /// used to make a security-sensitive decision.
+ /// </remarks>
+ IDictionary<string, string> IAuthenticationResponse.GetUntrustedCallbackArguments() {
+ Contract.Ensures(Contract.Result<IDictionary<string, string>>() != null);
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs
index ed9d65a..566a929 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IProviderEndpoint.cs
@@ -7,6 +7,8 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
@@ -18,6 +20,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Because information provided by this interface is suppplied by a
/// user's individually published documents, it may be incomplete or inaccurate.
/// </remarks>
+ ////[ContractClass(typeof(IProviderEndpointContract))]
public interface IProviderEndpoint {
/// <summary>
/// Gets the detected version of OpenID implemented by the Provider.
@@ -58,4 +61,67 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
bool IsExtensionSupported(Type extensionType);
}
+
+ /// <summary>
+ /// Code contract for the <see cref="IProviderEndpoint"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(IProviderEndpoint))]
+ internal abstract class IProviderEndpointContract : IProviderEndpoint {
+ #region IProviderEndpoint Members
+
+ /// <summary>
+ /// Gets the detected version of OpenID implemented by the Provider.
+ /// </summary>
+ Version IProviderEndpoint.Version {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Gets the URL that the OpenID Provider receives authentication requests at.
+ /// </summary>
+ Uri IProviderEndpoint.Uri {
+ get { throw new NotImplementedException(); }
+ }
+
+ /// <summary>
+ /// Checks whether the OpenId Identifier claims support for a given extension.
+ /// </summary>
+ /// <typeparam name="T">The extension whose support is being queried.</typeparam>
+ /// <returns>
+ /// True if support for the extension is advertised. False otherwise.
+ /// </returns>
+ /// <remarks>
+ /// Note that a true or false return value is no guarantee of a Provider's
+ /// support for or lack of support for an extension. The return value is
+ /// determined by how the authenticating user filled out his/her XRDS document only.
+ /// The only way to be sure of support for a given extension is to include
+ /// the extension in the request and see if a response comes back for that extension.
+ /// </remarks>
+ bool IProviderEndpoint.IsExtensionSupported<T>() {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Checks whether the OpenId Identifier claims support for a given extension.
+ /// </summary>
+ /// <param name="extensionType">The extension whose support is being queried.</param>
+ /// <returns>
+ /// True if support for the extension is advertised. False otherwise.
+ /// </returns>
+ /// <remarks>
+ /// Note that a true or false return value is no guarantee of a Provider's
+ /// support for or lack of support for an extension. The return value is
+ /// determined by how the authenticating user filled out his/her XRDS document only.
+ /// The only way to be sure of support for a given extension is to include
+ /// the extension in the request and see if a response comes back for that extension.
+ /// </remarks>
+ bool IProviderEndpoint.IsExtensionSupported(Type extensionType) {
+ Contract.Requires<ArgumentNullException>(extensionType != null);
+ Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType));
+ ////ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), string.Format(CultureInfo.CurrentCulture, OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName));
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs
index d0be768..300a15f 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IRelyingPartyBehavior.cs
@@ -5,9 +5,13 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Diagnostics.Contracts;
+
/// <summary>
/// Applies a custom security policy to certain OpenID security settings and behaviors.
/// </summary>
+ [ContractClass(typeof(IRelyingPartyBehaviorContract))]
public interface IRelyingPartyBehavior {
/// <summary>
/// Applies a well known set of security requirements to a default set of security settings.
@@ -36,4 +40,53 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="assertion">The positive assertion.</param>
void OnIncomingPositiveAssertion(IAuthenticationResponse assertion);
}
+
+ /// <summary>
+ /// Contract class for the <see cref="IRelyingPartyBehavior"/> interface.
+ /// </summary>
+ [ContractClassFor(typeof(IRelyingPartyBehavior))]
+ internal class IRelyingPartyBehaviorContract : IRelyingPartyBehavior {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IRelyingPartyBehaviorContract"/> class.
+ /// </summary>
+ protected IRelyingPartyBehaviorContract() {
+ }
+
+ #region IRelyingPartyBehavior Members
+
+ /// <summary>
+ /// Applies a well known set of security requirements to a default set of security settings.
+ /// </summary>
+ /// <param name="securitySettings">The security settings to enhance with the requirements of this profile.</param>
+ /// <remarks>
+ /// Care should be taken to never decrease security when applying a profile.
+ /// Profiles should only enhance security requirements to avoid being
+ /// incompatible with each other.
+ /// </remarks>
+ void IRelyingPartyBehavior.ApplySecuritySettings(RelyingPartySecuritySettings securitySettings) {
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ }
+
+ /// <summary>
+ /// Called when an authentication request is about to be sent.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <remarks>
+ /// Implementations should be prepared to be called multiple times on the same outgoing message
+ /// without malfunctioning.
+ /// </remarks>
+ void IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(IAuthenticationRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+ }
+
+ /// <summary>
+ /// Called when an incoming positive assertion is received.
+ /// </summary>
+ /// <param name="assertion">The positive assertion.</param>
+ void IRelyingPartyBehavior.OnIncomingPositiveAssertion(IAuthenticationResponse assertion) {
+ Contract.Requires<ArgumentNullException>(assertion != null);
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs
index e4f220f..cfbccef 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/ISetupRequiredAuthenticationResponse.cs
@@ -5,11 +5,15 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Diagnostics.Contracts;
+
/// <summary>
/// An interface to expose useful properties and functionality for handling
/// authentication responses that are returned from Immediate authentication
/// requests that require a subsequent request to be made in non-immediate mode.
/// </summary>
+ [ContractClass(typeof(ISetupRequiredAuthenticationResponseContract))]
public interface ISetupRequiredAuthenticationResponse {
/// <summary>
/// Gets the <see cref="Identifier"/> to pass to <see cref="OpenIdRelyingParty.CreateRequest(Identifier)"/>
@@ -17,4 +21,31 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
Identifier UserSuppliedIdentifier { get; }
}
+
+ /// <summary>
+ /// Code contract class for the <see cref="ISetupRequiredAuthenticationResponse"/> type.
+ /// </summary>
+ [ContractClassFor(typeof(ISetupRequiredAuthenticationResponse))]
+ internal abstract class ISetupRequiredAuthenticationResponseContract : ISetupRequiredAuthenticationResponse {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ISetupRequiredAuthenticationResponseContract"/> class.
+ /// </summary>
+ protected ISetupRequiredAuthenticationResponseContract() {
+ }
+
+ #region ISetupRequiredAuthenticationResponse Members
+
+ /// <summary>
+ /// Gets the <see cref="Identifier"/> to pass to <see cref="OpenIdRelyingParty.CreateRequest(Identifier)"/>
+ /// in a subsequent authentication attempt.
+ /// </summary>
+ Identifier ISetupRequiredAuthenticationResponse.UserSuppliedIdentifier {
+ get {
+ Contract.Requires<InvalidOperationException>(((IAuthenticationResponse)this).Status == AuthenticationStatus.SetupRequired, OpenIdStrings.OperationOnlyValidForSetupRequiredState);
+ throw new System.NotImplementedException();
+ }
+ }
+
+ #endregion
+ }
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs
index ebd8518..89b4ef0 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpoint.cs
@@ -5,13 +5,16 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
/// <summary>
/// An <see cref="IProviderEndpoint"/> interface with additional members for use
/// in sorting for most preferred endpoint.
/// </summary>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xrds", Justification = "Xrds is an acronym.")]
+ [ContractClass(typeof(IXrdsProviderEndpointContract))]
public interface IXrdsProviderEndpoint : IProviderEndpoint {
/// <summary>
/// Gets the priority associated with this service that may have been given
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs
new file mode 100644
index 0000000..e0e2b0b
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/IXrdsProviderEndpointContract.cs
@@ -0,0 +1,59 @@
+// <auto-generated />
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
+ using DotNetOpenAuth.OpenId.Messages;
+
+ [ContractClassFor(typeof(IXrdsProviderEndpoint))]
+ internal abstract class IXrdsProviderEndpointContract : IXrdsProviderEndpoint {
+ #region IXrdsProviderEndpoint Properties
+
+ int? IXrdsProviderEndpoint.ServicePriority {
+ get { throw new System.NotImplementedException(); }
+ }
+
+ int? IXrdsProviderEndpoint.UriPriority {
+ get { throw new System.NotImplementedException(); }
+ }
+
+ #endregion
+
+ #region IProviderEndpoint Properties
+
+ Version IProviderEndpoint.Version {
+ get { throw new System.NotImplementedException(); }
+ }
+
+ Uri IProviderEndpoint.Uri {
+ get { throw new System.NotImplementedException(); }
+ }
+
+ #endregion
+
+ #region IXrdsProviderEndpoint Methods
+
+ bool IXrdsProviderEndpoint.IsTypeUriPresent(string typeUri) {
+ throw new System.NotImplementedException();
+ }
+
+ #endregion
+
+ #region IProviderEndpoint Methods
+
+ bool IProviderEndpoint.IsExtensionSupported<T>() {
+ throw new System.NotImplementedException();
+ }
+
+ bool IProviderEndpoint.IsExtensionSupported(System.Type extensionType) {
+ Contract.Requires<ArgumentNullException>(extensionType != null);
+ Contract.Requires<ArgumentException>(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType));
+ ////ErrorUtilities.VerifyArgument(typeof(IOpenIdMessageExtension).IsAssignableFrom(extensionType), string.Format(CultureInfo.CurrentCulture, OpenIdStrings.TypeMustImplementX, typeof(IOpenIdMessageExtension).FullName));
+ throw new System.NotImplementedException();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/NegativeAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/NegativeAuthenticationResponse.cs
index 5aa2e24..02c5185 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/NegativeAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/NegativeAuthenticationResponse.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Web;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Messages;
@@ -27,7 +28,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The negative assertion response received by the Relying Party.</param>
internal NegativeAuthenticationResponse(NegativeAssertionResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
}
@@ -128,8 +129,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <value></value>
public Identifier UserSuppliedIdentifier {
get {
- ErrorUtilities.VerifyOperation(this.Status == AuthenticationStatus.SetupRequired, OpenIdStrings.OperationOnlyValidForSetupRequiredState);
-
string userSuppliedIdentifier;
this.response.ExtraData.TryGetValue(AuthenticationRequest.UserSuppliedIdentifierParameterName, out userSuppliedIdentifier);
return userSuppliedIdentifier;
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
index 6a4413f..d293cad 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs
@@ -5,6 +5,7 @@
//-----------------------------------------------------------------------
[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedScriptResourceName, "text/javascript")]
+[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName, "text/css")]
[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedDotNetOpenIdLogoResourceName, "image/gif")]
[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName, "image/gif")]
[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName, "image/png")]
@@ -19,18 +20,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Drawing.Design;
using System.Globalization;
- using System.Linq;
using System.Text;
- using System.Text.RegularExpressions;
- using System.Web;
using System.Web.UI;
- using System.Web.UI.WebControls;
+ using System.Web.UI.HtmlControls;
using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.OpenId.ChannelElements;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Extensions.UI;
/// <summary>
/// An ASP.NET control that provides a minimal text box that is OpenID-aware and uses AJAX for
@@ -38,13 +34,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
[DefaultProperty("Text"), ValidationProperty("Text")]
[ToolboxData("<{0}:OpenIdAjaxTextBox runat=\"server\" />")]
- public sealed class OpenIdAjaxTextBox : WebControl, ICallbackEventHandler {
+ public class OpenIdAjaxTextBox : OpenIdRelyingPartyAjaxControlBase, IEditableTextControl, ITextControl, IPostBackDataHandler {
/// <summary>
/// The name of the manifest stream containing the OpenIdAjaxTextBox.js file.
/// </summary>
internal const string EmbeddedScriptResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdAjaxTextBox.js";
/// <summary>
+ /// The name of the manifest stream containing the OpenIdAjaxTextBox.css file.
+ /// </summary>
+ internal const string EmbeddedStylesheetResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdAjaxTextBox.css";
+
+ /// <summary>
/// The name of the manifest stream containing the dotnetopenid_16x16.gif file.
/// </summary>
internal const string EmbeddedDotNetOpenIdLogoResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.dotnetopenid_16x16.gif";
@@ -64,47 +65,47 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
internal const string EmbeddedLoginFailureResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.login_failure.png";
- #region Property viewstate keys
-
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Columns"/> property.
+ /// The default value for the <see cref="DownloadYahooUILibrary"/> property.
/// </summary>
- private const string ColumnsViewStateKey = "Columns";
+ internal const bool DownloadYahooUILibraryDefault = true;
+
+ #region Property viewstate keys
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="OnClientAssertionReceived"/> property.
+ /// The viewstate key to use for storing the value of the <see cref="AutoPostBack"/> property.
/// </summary>
- private const string OnClientAssertionReceivedViewStateKey = "OnClientAssertionReceived";
+ private const string AutoPostBackViewStateKey = "AutoPostback";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationResponse"/> property.
+ /// The viewstate key to use for the <see cref="Text"/> property.
/// </summary>
- private const string AuthenticationResponseViewStateKey = "AuthenticationResponse";
+ private const string TextViewStateKey = "Text";
/// <summary>
- /// The viewstate key to use for storing the value of the a successful authentication.
+ /// The viewstate key to use for storing the value of the <see cref="Columns"/> property.
/// </summary>
- private const string AuthDataViewStateKey = "AuthData";
+ private const string ColumnsViewStateKey = "Columns";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticatedAsToolTip"/> property.
+ /// The viewstate key to use for the <see cref="CssClass"/> property.
/// </summary>
- private const string AuthenticatedAsToolTipViewStateKey = "AuthenticatedAsToolTip";
+ private const string CssClassViewStateKey = "CssClass";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="AuthenticationSucceededToolTip"/> property.
+ /// The viewstate key to use for storing the value of the <see cref="OnClientAssertionReceived"/> property.
/// </summary>
- private const string AuthenticationSucceededToolTipViewStateKey = "AuthenticationSucceededToolTip";
+ private const string OnClientAssertionReceivedViewStateKey = "OnClientAssertionReceived";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="ReturnToUrl"/> property.
+ /// The viewstate key to use for storing the value of the <see cref="AuthenticatedAsToolTip"/> property.
/// </summary>
- private const string ReturnToUrlViewStateKey = "ReturnToUrl";
+ private const string AuthenticatedAsToolTipViewStateKey = "AuthenticatedAsToolTip";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="RealmUrl"/> property.
+ /// The viewstate key to use for storing the value of the <see cref="AuthenticationSucceededToolTip"/> property.
/// </summary>
- private const string RealmUrlViewStateKey = "RealmUrl";
+ private const string AuthenticationSucceededToolTipViewStateKey = "AuthenticationSucceededToolTip";
/// <summary>
/// The viewstate key to use for storing the value of the <see cref="LogOnInProgressMessage"/> property.
@@ -142,6 +143,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string LogOnToolTipViewStateKey = "LoginToolTip";
/// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="LogOnPostBackToolTip"/> property.
+ /// </summary>
+ private const string LogOnPostBackToolTipViewStateKey = "LoginPostBackToolTip";
+
+ /// <summary>
/// The viewstate key to use for storing the value of the <see cref="Name"/> property.
/// </summary>
private const string NameViewStateKey = "Name";
@@ -152,14 +158,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string TimeoutViewStateKey = "Timeout";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="Text"/> property.
+ /// The viewstate key to use for storing the value of the <see cref="TabIndex"/> property.
/// </summary>
- private const string TextViewStateKey = "Text";
+ private const string TabIndexViewStateKey = "TabIndex";
/// <summary>
- /// The viewstate key to use for storing the value of the <see cref="TabIndex"/> property.
+ /// The viewstate key to use for the <see cref="Enabled"/> property.
/// </summary>
- private const string TabIndexViewStateKey = "TabIndex";
+ private const string EnabledViewStateKey = "Enabled";
/// <summary>
/// The viewstate key to use for storing the value of the <see cref="RetryToolTip"/> property.
@@ -171,24 +177,34 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
private const string RetryTextViewStateKey = "RetryText";
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="DownloadYahooUILibrary"/> property.
+ /// </summary>
+ private const string DownloadYahooUILibraryViewStateKey = "DownloadYahooUILibrary";
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="ShowLogOnPostBackButton"/> property.
+ /// </summary>
+ private const string ShowLogOnPostBackButtonViewStateKey = "ShowLogOnPostBackButton";
+
#endregion
#region Property defaults
/// <summary>
- /// The default value for the <see cref="Columns"/> property.
+ /// The default value for the <see cref="AutoPostBack"/> property.
/// </summary>
- private const int ColumnsDefault = 40;
+ private const bool AutoPostBackDefault = false;
/// <summary>
- /// The default value for the <see cref="ReturnToUrl"/> property.
+ /// The default value for the <see cref="Columns"/> property.
/// </summary>
- private const string ReturnToUrlDefault = "";
+ private const int ColumnsDefault = 40;
/// <summary>
- /// The default value for the <see cref="RealmUrl"/> property.
+ /// The default value for the <see cref="CssClass"/> property.
/// </summary>
- private const string RealmUrlDefault = "~/";
+ private const string CssClassDefault = "openid";
/// <summary>
/// The default value for the <see cref="LogOnInProgressMessage"/> property.
@@ -251,71 +267,46 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string LogOnToolTipDefault = "Click here to log in using a pop-up window.";
/// <summary>
- /// The default value for the <see cref="RetryText"/> property.
+ /// The default value for the <see cref="LogOnPostBackToolTip"/> property.
/// </summary>
- private const string RetryTextDefault = "RETRY";
-
- #endregion
+ private const string LogOnPostBackToolTipDefault = "Click here to log in immediately.";
/// <summary>
- /// Backing field for the <see cref="RelyingParty"/> property.
+ /// The default value for the <see cref="RetryText"/> property.
/// </summary>
- private OpenIdRelyingParty relyingParty;
+ private const string RetryTextDefault = "RETRY";
/// <summary>
- /// Backing field for the <see cref="RelyingPartyNonVerifying"/> property.
+ /// The default value for the <see cref="ShowLogOnPostBackButton"/> property.
/// </summary>
- private OpenIdRelyingParty relyingPartyNonVerifying;
+ private const bool ShowLogOnPostBackButtonDefault = false;
- /// <summary>
- /// Tracks whether the text box should receive input focus when the page is rendered.
- /// </summary>
- private bool focusCalled;
+ #endregion
/// <summary>
- /// The authentication response that just came in.
+ /// The path where the YUI control library should be downloaded from for HTTP pages.
/// </summary>
- private IAuthenticationResponse authenticationResponse;
+ private const string YuiLoaderHttp = "http://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js";
/// <summary>
- /// A dictionary of extension response types and the javascript member
- /// name to map them to on the user agent.
+ /// The path where the YUI control library should be downloaded from for HTTPS pages.
/// </summary>
- private Dictionary<Type, string> clientScriptExtensions = new Dictionary<Type, string>();
+ private const string YuiLoaderHttps = "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js";
/// <summary>
- /// Stores the result of an AJAX discovery request while it is waiting
- /// to be picked up by ASP.NET on the way down to the user agent.
+ /// Initializes a new instance of the <see cref="OpenIdAjaxTextBox"/> class.
/// </summary>
- private string discoveryResult;
+ public OpenIdAjaxTextBox() {
+ this.HookFormSubmit = true;
+ }
#region Events
/// <summary>
- /// Fired when the user has typed in their identifier, discovery was successful
- /// and a login attempt is about to begin.
- /// </summary>
- [Description("Fired when the user has typed in their identifier, discovery was successful and a login attempt is about to begin.")]
- public event EventHandler<OpenIdEventArgs> LoggingIn;
-
- /// <summary>
- /// Fired when a Provider sends back a positive assertion to this control,
- /// but the authentication has not yet been verified.
- /// </summary>
- /// <remarks>
- /// <b>No security critical decisions should be made within event handlers
- /// for this event</b> as the authenticity of the assertion has not been
- /// verified yet. All security related code should go in the event handler
- /// for the <see cref="LoggedIn"/> event.
- /// </remarks>
- [Description("Fired when a Provider sends back a positive assertion to this control, but the authentication has not yet been verified.")]
- public event EventHandler<OpenIdEventArgs> UnconfirmedPositiveAssertion;
-
- /// <summary>
- /// Fired when authentication has completed successfully.
+ /// Fired when the content of the text changes between posts to the server.
/// </summary>
- [Description("Fired when authentication has completed successfully.")]
- public event EventHandler<OpenIdEventArgs> LoggedIn;
+ [Description("Occurs when the content of the text changes between posts to the server."), Category(BehaviorCategory)]
+ public event EventHandler TextChanged;
/// <summary>
/// Gets or sets the client-side script that executes when an authentication
@@ -331,10 +322,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// the authentication has not been verified and may have been spoofed.
/// No security-sensitive operations should take place in this javascript code.
/// The authentication is verified on the server by the time the
- /// <see cref="LoggedIn"/> server-side event fires.</para>
+ /// <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> server-side event fires.</para>
/// </remarks>
[Description("Gets or sets the client-side script that executes when an authentication assertion is received (but before it is verified).")]
- [Bindable(true), DefaultValue(""), Category("Behavior")]
+ [Bindable(true), DefaultValue(""), Category(BehaviorCategory)]
public string OnClientAssertionReceived {
get { return this.ViewState[OnClientAssertionReceivedViewStateKey] as string; }
set { this.ViewState[OnClientAssertionReceivedViewStateKey] = value; }
@@ -345,54 +336,51 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#region Properties
/// <summary>
- /// Gets the completed authentication response.
+ /// Gets or sets the value in the text field, completely unprocessed or normalized.
/// </summary>
- public IAuthenticationResponse AuthenticationResponse {
+ [Bindable(true), DefaultValue(""), Category(AppearanceCategory)]
+ [Description("The content of the text box.")]
+ public string Text {
get {
- if (this.authenticationResponse == null) {
- // We will either validate a new response and return a live AuthenticationResponse
- // or we will try to deserialize a previous IAuthenticationResponse (snapshot)
- // from viewstate and return that.
- IAuthenticationResponse viewstateResponse = this.ViewState[AuthenticationResponseViewStateKey] as IAuthenticationResponse;
- string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
- string formAuthData = this.Page.Request.Form[this.OpenIdAuthDataFormKey];
-
- // First see if there is fresh auth data to be processed into a response.
- if (!string.IsNullOrEmpty(formAuthData) && !string.Equals(viewstateAuthData, formAuthData, StringComparison.Ordinal)) {
- this.ViewState[AuthDataViewStateKey] = formAuthData;
-
- Uri authUri = new Uri(formAuthData);
- HttpRequestInfo clientResponseInfo = new HttpRequestInfo {
- UrlBeforeRewriting = authUri,
- };
-
- this.authenticationResponse = this.RelyingParty.GetResponse(clientResponseInfo);
-
- // Save out the authentication response to viewstate so we can find it on
- // a subsequent postback.
- this.ViewState[AuthenticationResponseViewStateKey] = new AuthenticationResponseSnapshot(this.authenticationResponse);
- } else {
- this.authenticationResponse = viewstateResponse;
- }
+ return this.Identifier != null ? this.Identifier.OriginalString : (this.ViewState[TextViewStateKey] as string ?? string.Empty);
+ }
+
+ set {
+ // Try to store it as a validated identifier,
+ // but failing that at least store the text.
+ Identifier id;
+ if (Identifier.TryParse(value, out id)) {
+ this.Identifier = id;
+ } else {
+ // Be sure to set the viewstate AFTER setting the Identifier,
+ // since setting the Identifier clears the viewstate in OnIdentifierChanged.
+ this.Identifier = null;
+ this.ViewState[TextViewStateKey] = value;
}
- return this.authenticationResponse;
}
}
/// <summary>
- /// Gets or sets the value in the text field, completely unprocessed or normalized.
+ /// Gets or sets a value indicating whether a postback is made to fire the
+ /// <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event as soon as authentication has completed
+ /// successfully.
/// </summary>
- [Bindable(true), DefaultValue(""), Category("Appearance")]
- [Description("The value in the text field, completely unprocessed or normalized.")]
- public string Text {
- get { return (string)(this.ViewState[TextViewStateKey] ?? string.Empty); }
- set { this.ViewState[TextViewStateKey] = value ?? string.Empty; }
+ /// <value>
+ /// <c>true</c> if a postback should be made automatically upon authentication;
+ /// otherwise, <c>false</c> to delay the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/>
+ /// event from firing at the server until a postback is made by some other control.
+ /// </value>
+ [Bindable(true), Category(BehaviorCategory), DefaultValue(AutoPostBackDefault)]
+ [Description("Whether the LoggedIn event fires on the server as soon as authentication completes successfully.")]
+ public bool AutoPostBack {
+ get { return (bool)(this.ViewState[AutoPostBackViewStateKey] ?? AutoPostBackDefault); }
+ set { this.ViewState[AutoPostBackViewStateKey] = value; }
}
/// <summary>
/// Gets or sets the width of the text box in characters.
/// </summary>
- [Bindable(true), Category("Appearance"), DefaultValue(ColumnsDefault)]
+ [Bindable(true), Category(AppearanceCategory), DefaultValue(ColumnsDefault)]
[Description("The width of the text box in characters.")]
public int Columns {
get {
@@ -400,22 +388,44 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value >= 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value >= 0);
this.ViewState[ColumnsViewStateKey] = value;
}
}
/// <summary>
+ /// Gets or sets the CSS class assigned to the text box.
+ /// </summary>
+ [Bindable(true), DefaultValue(CssClassDefault), Category(AppearanceCategory)]
+ [Description("The CSS class assigned to the text box.")]
+ public string CssClass {
+ get { return (string)this.ViewState[CssClassViewStateKey]; }
+ set { this.ViewState[CssClassViewStateKey] = value; }
+ }
+
+ /// <summary>
/// Gets or sets the tab index of the text box control. Use 0 to omit an explicit tabindex.
/// </summary>
- [Bindable(true), Category("Behavior"), DefaultValue(TabIndexDefault)]
+ [Bindable(true), Category(BehaviorCategory), DefaultValue(TabIndexDefault)]
[Description("The tab index of the text box control. Use 0 to omit an explicit tabindex.")]
- public override short TabIndex {
+ public virtual short TabIndex {
get { return (short)(this.ViewState[TabIndexViewStateKey] ?? TabIndexDefault); }
set { this.ViewState[TabIndexViewStateKey] = value; }
}
/// <summary>
+ /// Gets or sets a value indicating whether this <see cref="OpenIdTextBox"/> is enabled
+ /// in the browser for editing and will respond to incoming OpenID messages.
+ /// </summary>
+ /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
+ [Bindable(true), DefaultValue(true), Category(BehaviorCategory)]
+ [Description("Whether the control is editable in the browser and will respond to OpenID messages.")]
+ public bool Enabled {
+ get { return (bool)(this.ViewState[EnabledViewStateKey] ?? true); }
+ set { this.ViewState[EnabledViewStateKey] = value; }
+ }
+
+ /// <summary>
/// Gets or sets the HTML name to assign to the text field.
/// </summary>
[Bindable(true), DefaultValue(NameDefault), Category("Misc")]
@@ -426,7 +436,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyNonZeroLength(value, "value");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
this.ViewState[NameViewStateKey] = value ?? string.Empty;
}
}
@@ -434,7 +444,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.
/// </summary>
- [Browsable(true), DefaultValue(typeof(TimeSpan), "00:00:01"), Category("Behavior")]
+ [Browsable(true), DefaultValue(typeof(TimeSpan), "00:00:08"), Category(BehaviorCategory)]
[Description("The time duration for the AJAX control to wait for an OP to respond before reporting failure to the user.")]
public TimeSpan Timeout {
get {
@@ -442,7 +452,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value.TotalMilliseconds > 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value.TotalMilliseconds > 0);
this.ViewState[TimeoutViewStateKey] = value;
}
}
@@ -450,7 +460,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the maximum number of OpenID Providers to simultaneously try to authenticate with.
/// </summary>
- [Browsable(true), DefaultValue(ThrottleDefault), Category("Behavior")]
+ [Browsable(true), DefaultValue(ThrottleDefault), Category(BehaviorCategory)]
[Description("The maximum number of OpenID Providers to simultaneously try to authenticate with.")]
public int Throttle {
get {
@@ -458,7 +468,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyArgumentInRange(value > 0, "value");
+ Contract.Requires<ArgumentOutOfRangeException>(value > 0);
this.ViewState[ThrottleViewStateKey] = value;
}
}
@@ -466,7 +476,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.
/// </summary>
- [Bindable(true), DefaultValue(LogOnTextDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(LogOnTextDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.")]
public string LogOnText {
get {
@@ -474,7 +484,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyNonZeroLength(value, "value");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
this.ViewState[LogOnTextViewStateKey] = value ?? string.Empty;
}
}
@@ -482,7 +492,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the rool tip text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.
/// </summary>
- [Bindable(true), DefaultValue(LogOnToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(LogOnToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears on the LOG IN button in cases where immediate (invisible) authentication fails.")]
public string LogOnToolTip {
get { return (string)(this.ViewState[LogOnToolTipViewStateKey] ?? LogOnToolTipDefault); }
@@ -490,9 +500,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
+ /// Gets or sets the rool tip text that appears on the LOG IN button when clicking the button will result in an immediate postback.
+ /// </summary>
+ [Bindable(true), DefaultValue(LogOnPostBackToolTipDefault), Localizable(true), Category(AppearanceCategory)]
+ [Description("The tool tip text that appears on the LOG IN button when clicking the button will result in an immediate postback.")]
+ public string LogOnPostBackToolTip {
+ get { return (string)(this.ViewState[LogOnPostBackToolTipViewStateKey] ?? LogOnPostBackToolTipDefault); }
+ set { this.ViewState[LogOnPostBackToolTipViewStateKey] = value ?? string.Empty; }
+ }
+
+ /// <summary>
/// Gets or sets the text that appears on the RETRY button in cases where authentication times out.
/// </summary>
- [Bindable(true), DefaultValue(RetryTextDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(RetryTextDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The text that appears on the RETRY button in cases where authentication times out.")]
public string RetryText {
get {
@@ -500,7 +520,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- ErrorUtilities.VerifyNonZeroLength(value, "value");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(value));
this.ViewState[RetryTextViewStateKey] = value ?? string.Empty;
}
}
@@ -508,7 +528,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the tool tip text that appears on the RETRY button in cases where authentication times out.
/// </summary>
- [Bindable(true), DefaultValue(RetryToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(RetryToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears on the RETRY button in cases where authentication times out.")]
public string RetryToolTip {
get { return (string)(this.ViewState[RetryToolTipViewStateKey] ?? RetryToolTipDefault); }
@@ -518,7 +538,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the tool tip text that appears when authentication succeeds.
/// </summary>
- [Bindable(true), DefaultValue(AuthenticationSucceededToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(AuthenticationSucceededToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears when authentication succeeds.")]
public string AuthenticationSucceededToolTip {
get { return (string)(this.ViewState[AuthenticationSucceededToolTipViewStateKey] ?? AuthenticationSucceededToolTipDefault); }
@@ -528,7 +548,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the tool tip text that appears on the green checkmark when authentication succeeds.
/// </summary>
- [Bindable(true), DefaultValue(AuthenticatedAsToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(AuthenticatedAsToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears on the green checkmark when authentication succeeds.")]
public string AuthenticatedAsToolTip {
get { return (string)(this.ViewState[AuthenticatedAsToolTipViewStateKey] ?? AuthenticatedAsToolTipDefault); }
@@ -538,7 +558,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the tool tip text that appears when authentication fails.
/// </summary>
- [Bindable(true), DefaultValue(AuthenticationFailedToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(AuthenticationFailedToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears when authentication fails.")]
public string AuthenticationFailedToolTip {
get { return (string)(this.ViewState[AuthenticationFailedToolTipViewStateKey] ?? AuthenticationFailedToolTipDefault); }
@@ -548,7 +568,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the tool tip text that appears over the text box when it is discovering and authenticating.
/// </summary>
- [Bindable(true), DefaultValue(BusyToolTipDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(BusyToolTipDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The tool tip text that appears over the text box when it is discovering and authenticating.")]
public string BusyToolTip {
get { return (string)(this.ViewState[BusyToolTipViewStateKey] ?? BusyToolTipDefault); }
@@ -558,7 +578,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the message that is displayed if a postback is about to occur before the identifier has been supplied.
/// </summary>
- [Bindable(true), DefaultValue(IdentifierRequiredMessageDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(IdentifierRequiredMessageDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The message that is displayed if a postback is about to occur before the identifier has been supplied.")]
public string IdentifierRequiredMessage {
get { return (string)(this.ViewState[IdentifierRequiredMessageViewStateKey] ?? IdentifierRequiredMessageDefault); }
@@ -568,7 +588,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Gets or sets the message that is displayed if a postback is attempted while login is in process.
/// </summary>
- [Bindable(true), DefaultValue(LogOnInProgressMessageDefault), Localizable(true), Category("Appearance")]
+ [Bindable(true), DefaultValue(LogOnInProgressMessageDefault), Localizable(true), Category(AppearanceCategory)]
[Description("The message that is displayed if a postback is attempted while login is in process.")]
public string LogOnInProgressMessage {
get { return (string)(this.ViewState[LogOnInProgressMessageViewStateKey] ?? LogOnInProgressMessageDefault); }
@@ -576,222 +596,51 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Gets or sets the OpenID <see cref="Realm"/> of the relying party web site.
+ /// Gets or sets a value indicating whether the Yahoo! User Interface Library (YUI)
+ /// will be downloaded in order to provide a login split button.
/// </summary>
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId.Realm", Justification = "Using ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Property grid on form designer only supports primitive types.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid on form designer only supports primitive types.")]
- [Bindable(true)]
- [Category("Behavior")]
- [DefaultValue(RealmUrlDefault)]
- [Description("The OpenID Realm of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string RealmUrl {
- get {
- return (string)(this.ViewState[RealmUrlViewStateKey] ?? RealmUrlDefault);
- }
-
- set {
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Realm object based on it.
- new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, this.RelyingParty.Channel.GetRequestFromContext())); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value.Replace("*.", "")); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
- this.ViewState[RealmUrlViewStateKey] = value;
- }
+ /// <value>
+ /// <c>true</c> to use a split button; otherwise, <c>false</c> to use a standard HTML button
+ /// or a split button by downloading the YUI library yourself on the hosting web page.
+ /// </value>
+ /// <remarks>
+ /// The split button brings in about 180KB of YUI javascript dependencies.
+ /// </remarks>
+ [Bindable(true), DefaultValue(DownloadYahooUILibraryDefault), Category(BehaviorCategory)]
+ [Description("Whether a split button will be used for the \"log in\" when the user provides an identifier that delegates to more than one Provider.")]
+ public bool DownloadYahooUILibrary {
+ get { return (bool)(this.ViewState[DownloadYahooUILibraryViewStateKey] ?? DownloadYahooUILibraryDefault); }
+ set { this.ViewState[DownloadYahooUILibraryViewStateKey] = value; }
}
/// <summary>
- /// Gets or sets the OpenID ReturnTo of the relying party web site.
+ /// Gets or sets a value indicating whether the "Log in" button will be shown
+ /// to initiate a postback containing the positive assertion.
/// </summary>
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Property grid on form designer only supports primitive types.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid on form designer only supports primitive types.")]
- [Bindable(true)]
- [Category("Behavior")]
- [DefaultValue(ReturnToUrlDefault)]
- [Description("The OpenID ReturnTo of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string ReturnToUrl {
- get {
- return (string)(this.ViewState[ReturnToUrlViewStateKey] ?? ReturnToUrlDefault);
- }
-
- set {
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Uri based on it.
- new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, Page.ResolveUrl(value)); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
- this.ViewState[ReturnToUrlViewStateKey] = value;
- }
+ [Bindable(true), DefaultValue(ShowLogOnPostBackButtonDefault), Category(AppearanceCategory)]
+ [Description("Whether the log in button will be shown to initiate a postback containing the positive assertion.")]
+ public bool ShowLogOnPostBackButton {
+ get { return (bool)(this.ViewState[ShowLogOnPostBackButtonViewStateKey] ?? ShowLogOnPostBackButtonDefault); }
+ set { this.ViewState[ShowLogOnPostBackButtonViewStateKey] = value; }
}
#endregion
- #region Properties to hide
-
- /// <summary>
- /// Gets or sets the foreground color (typically the color of the text) of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the foreground color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color ForeColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the background color of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the background color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>, which indicates that this property is not set.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color BackColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the border color of the Web control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the border color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>, which indicates that this property is not set.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color BorderColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the border width of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the border width of a Web server control. The default value is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>, which indicates that this property is not set.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The specified border width is a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit BorderWidth {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the border style of the Web server control.
- /// </summary>
- /// <returns>
- /// One of the <see cref="T:System.Web.UI.WebControls.BorderStyle"/> enumeration values. The default is NotSet.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override BorderStyle BorderStyle {
- get { return BorderStyle.None; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets the font properties associated with the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.FontInfo"/> that represents the font properties of the Web server control.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override FontInfo Font {
- get { return null; }
- }
-
- /// <summary>
- /// Gets or sets the height of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the height of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The height was set to a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit Height {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the width of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the width of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The width of the Web server control was set to a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit Width {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the text displayed when the mouse pointer hovers over the Web server control.
- /// </summary>
- /// <returns>
- /// The text displayed when the mouse pointer hovers over the Web server control. The default is <see cref="F:System.String.Empty"/>.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override string ToolTip {
- get { return string.Empty; }
- set { throw new NotSupportedException(); }
- }
-
/// <summary>
- /// Gets or sets the skin to apply to the control.
+ /// Gets or sets a value indicating whether the ajax text box should hook the form's submit event for special behavior.
/// </summary>
- /// <returns>
- /// The name of the skin to apply to the control. The default is <see cref="F:System.String.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The skin specified in the <see cref="P:System.Web.UI.WebControls.WebControl.SkinID"/> property does not exist in the theme.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override string SkinID {
- get { return string.Empty; }
- set { throw new NotSupportedException(); }
- }
+ internal bool HookFormSubmit { get; set; }
/// <summary>
- /// Gets or sets a value indicating whether themes apply to this control.
+ /// Gets the name of the open id auth data form key.
/// </summary>
- /// <returns>true to use themes; otherwise, false. The default is false.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override bool EnableTheming {
- get { return false; }
- set { throw new NotSupportedException(); }
+ /// <value>
+ /// A concatenation of <see cref="Name"/> and <c>"_openidAuthData"</c>.
+ /// </value>
+ protected override string OpenIdAuthDataFormKey {
+ get { return this.Name + "_openidAuthData"; }
}
- #endregion
-
/// <summary>
/// Gets the default value for the <see cref="Timeout"/> property.
/// </summary>
@@ -807,171 +656,45 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
}
- /// <summary>
- /// Gets the relying party to use when verification of incoming messages is needed.
- /// </summary>
- private OpenIdRelyingParty RelyingParty {
- get {
- if (this.relyingParty == null) {
- this.relyingParty = CreateRelyingParty(true);
- }
- return this.relyingParty;
- }
- }
+ #region IPostBackDataHandler Members
/// <summary>
- /// Gets the relying party to use when verification of incoming messages is NOT wanted.
+ /// When implemented by a class, processes postback data for an ASP.NET server control.
/// </summary>
- private OpenIdRelyingParty RelyingPartyNonVerifying {
- get {
- if (this.relyingPartyNonVerifying == null) {
- this.relyingPartyNonVerifying = CreateRelyingParty(false);
- }
- return this.relyingPartyNonVerifying;
- }
- }
-
- /// <summary>
- /// Gets the name of the open id auth data form key.
- /// </summary>
- /// <value>A concatenation of <see cref="Name"/> and <c>"_openidAuthData"</c>.</value>
- private string OpenIdAuthDataFormKey {
- get { return this.Name + "_openidAuthData"; }
- }
-
- /// <summary>
- /// Places focus on the text box when the page is rendered on the browser.
- /// </summary>
- public override void Focus() {
- // we don't emit the code to focus the control immediately, in case the control
- // is never rendered to the page because its Visible property is false or that
- // of any of its parent containers.
- this.focusCalled = true;
- }
-
- /// <summary>
- /// Allows an OpenID extension to read data out of an unverified positive authentication assertion
- /// and send it down to the client browser so that Javascript running on the page can perform
- /// some preprocessing on the extension data.
- /// </summary>
- /// <typeparam name="T">The extension <i>response</i> type that will read data from the assertion.</typeparam>
- /// <param name="propertyName">The property name on the openid_identifier input box object that will be used to store the extension data. For example: sreg</param>
- /// <remarks>
- /// This method should be called from the <see cref="UnconfirmedPositiveAssertion"/> event handler.
- /// </remarks>
- [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "By design")]
- public void RegisterClientScriptExtension<T>(string propertyName) where T : IClientScriptExtensionResponse {
- ErrorUtilities.VerifyNonZeroLength(propertyName, "propertyName");
- ErrorUtilities.VerifyArgumentNamed(!this.clientScriptExtensions.ContainsValue(propertyName), "propertyName", OpenIdStrings.ClientScriptExtensionPropertyNameCollision, propertyName);
- foreach (var ext in this.clientScriptExtensions.Keys) {
- ErrorUtilities.VerifyArgument(ext != typeof(T), OpenIdStrings.ClientScriptExtensionTypeCollision, typeof(T).FullName);
- }
- this.clientScriptExtensions.Add(typeof(T), propertyName);
+ /// <param name="postDataKey">The key identifier for the control.</param>
+ /// <param name="postCollection">The collection of all incoming name values.</param>
+ /// <returns>
+ /// true if the server control's state changes as a result of the postback; otherwise, false.
+ /// </returns>
+ bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) {
+ return this.LoadPostData(postDataKey, postCollection);
}
- #region ICallbackEventHandler Members
-
/// <summary>
- /// Returns the result of discovery on some Identifier passed to <see cref="ICallbackEventHandler.RaiseCallbackEvent"/>.
+ /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
/// </summary>
- /// <returns>The result of the callback.</returns>
- /// <value>A whitespace delimited list of URLs that can be used to initiate authentication.</value>
- string ICallbackEventHandler.GetCallbackResult() {
- this.Page.Response.ContentType = "text/javascript";
- return this.discoveryResult;
- }
-
- /// <summary>
- /// Performs discovery on some OpenID Identifier. Called directly from the user agent via
- /// AJAX callback mechanisms.
- /// </summary>
- /// <param name="eventArgument">The identifier to perform discovery on.</param>
- void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
- string userSuppliedIdentifier = eventArgument;
-
- ErrorUtilities.VerifyNonZeroLength(userSuppliedIdentifier, "userSuppliedIdentifier");
- Logger.OpenId.InfoFormat("AJAX discovery on {0} requested.", userSuppliedIdentifier);
-
- // We prepare a JSON object with this interface:
- // class jsonResponse {
- // string claimedIdentifier;
- // Array requests; // never null
- // string error; // null if no error
- // }
- // Each element in the requests array looks like this:
- // class jsonAuthRequest {
- // string endpoint; // URL to the OP endpoint
- // string immediate; // URL to initiate an immediate request
- // string setup; // URL to initiate a setup request.
- // }
- StringBuilder discoveryResultBuilder = new StringBuilder();
- discoveryResultBuilder.Append("{");
- try {
- List<IAuthenticationRequest> requests = this.CreateRequests(userSuppliedIdentifier, true).Where(req => this.OnLoggingIn(req)).ToList();
- if (requests.Count > 0) {
- discoveryResultBuilder.AppendFormat("claimedIdentifier: {0},", MessagingUtilities.GetSafeJavascriptValue(requests[0].ClaimedIdentifier));
- discoveryResultBuilder.Append("requests: [");
- foreach (IAuthenticationRequest request in requests) {
- discoveryResultBuilder.Append("{");
- discoveryResultBuilder.AppendFormat("endpoint: {0},", MessagingUtilities.GetSafeJavascriptValue(request.Provider.Uri.AbsoluteUri));
- request.Mode = AuthenticationRequestMode.Immediate;
- OutgoingWebResponse response = request.RedirectingResponse;
- discoveryResultBuilder.AppendFormat("immediate: {0},", MessagingUtilities.GetSafeJavascriptValue(response.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri));
- request.Mode = AuthenticationRequestMode.Setup;
- response = request.RedirectingResponse;
- discoveryResultBuilder.AppendFormat("setup: {0}", MessagingUtilities.GetSafeJavascriptValue(response.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri));
- discoveryResultBuilder.Append("},");
- }
- discoveryResultBuilder.Length -= 1; // trim off last comma
- discoveryResultBuilder.Append("]");
- } else {
- discoveryResultBuilder.Append("requests: new Array(),");
- discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(OpenIdStrings.OpenIdEndpointNotFound));
- }
- } catch (ProtocolException ex) {
- discoveryResultBuilder.Append("requests: new Array(),");
- discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(ex.Message));
- }
- discoveryResultBuilder.Append("}");
- this.discoveryResult = discoveryResultBuilder.ToString();
+ void IPostBackDataHandler.RaisePostDataChangedEvent() {
+ this.RaisePostDataChangedEvent();
}
#endregion
/// <summary>
- /// Enables a server control to perform final clean up before it is released from memory.
- /// </summary>
- public sealed override void Dispose() {
- this.Dispose(true);
- base.Dispose();
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Prepares the control for loading.
+ /// Raises the <see cref="E:Load"/> event.
/// </summary>
- /// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
+ /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
- if (this.Page.IsPostBack) {
- // If the control was temporarily hidden, it won't be in the Form data,
- // and we'll just implicitly keep the last Text setting.
- if (this.Page.Request.Form[this.Name] != null) {
- this.Text = this.Page.Request.Form[this.Name];
- }
+ this.Page.RegisterRequiresPostBack(this);
+ }
- // If there is a response, and it is fresh (live object, not a snapshot object)...
- if (this.AuthenticationResponse != null && this.AuthenticationResponse.Status == AuthenticationStatus.Authenticated) {
- this.OnLoggedIn(this.AuthenticationResponse);
- }
- } else {
- NameValueCollection query = this.RelyingParty.Channel.GetRequestFromContext().GetQueryOrFormFromContext();
- string userSuppliedIdentifier = query["dotnetopenid.userSuppliedIdentifier"];
- if (!string.IsNullOrEmpty(userSuppliedIdentifier) && query["dotnetopenid.phase"] == "2") {
- this.ReportAuthenticationResult();
- }
- }
+ /// <summary>
+ /// Called when the <see cref="Identifier"/> property is changed.
+ /// </summary>
+ protected override void OnIdentifierChanged() {
+ this.ViewState.Remove(TextViewStateKey);
+ base.OnIdentifierChanged();
}
/// <summary>
@@ -981,204 +704,122 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
protected override void OnPreRender(EventArgs e) {
base.OnPreRender(e);
+ if (this.DownloadYahooUILibrary) {
+ string yuiLoadScript = @"var loader = new YAHOO.util.YUILoader({
+ require: ['button', 'menu'],
+ loadOptional: false,
+ combine: true
+});
+
+loader.insert();";
+ this.Page.ClientScript.RegisterClientScriptInclude("yuiloader", this.Page.Request.Url.IsTransportSecure() ? YuiLoaderHttps : YuiLoaderHttp);
+ this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "requiredYuiComponents", yuiLoadScript, true);
+ }
+
+ var css = new HtmlLink();
+ css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName);
+ css.Attributes["rel"] = "stylesheet";
+ css.Attributes["type"] = "text/css";
+ ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer);
+ this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override
+
this.PrepareClientJavascript();
+
+ // If an Identifier is preset on this control, preload discovery on that identifier,
+ // but only if we're not already persisting an authentication result since that would
+ // be redundant.
+ if (this.Identifier != null && this.AuthenticationResponse == null) {
+ this.PreloadDiscovery(this.Identifier);
+ }
}
/// <summary>
/// Renders the control.
/// </summary>
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
- protected override void Render(System.Web.UI.HtmlTextWriter writer) {
+ protected override void Render(HtmlTextWriter writer) {
+ base.Render(writer);
+
// We surround the textbox with a span so that the .js file can inject a
// login button within the text box with easy placement.
- writer.WriteBeginTag("span");
- writer.WriteAttribute("class", this.CssClass);
- writer.Write(" style='");
- writer.WriteStyleAttribute("display", "inline-block");
- writer.WriteStyleAttribute("position", "relative");
- writer.WriteStyleAttribute("font-size", "16px");
- writer.Write("'>");
-
- writer.WriteBeginTag("input");
- writer.WriteAttribute("name", this.Name);
- writer.WriteAttribute("id", this.ClientID);
- writer.WriteAttribute("value", this.Text, true);
- writer.WriteAttribute("size", this.Columns.ToString(CultureInfo.InvariantCulture));
+ string css = this.CssClass ?? string.Empty;
+ css += " OpenIdAjaxTextBox";
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, css);
+
+ writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "inline-block");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "relative");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "16px");
+ writer.RenderBeginTag(HtmlTextWriterTag.Span);
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Name, this.Name);
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
+ writer.AddAttribute(HtmlTextWriterAttribute.Size, this.Columns.ToString(CultureInfo.InvariantCulture));
+ if (!string.IsNullOrEmpty(this.Text)) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text, true);
+ }
+
if (this.TabIndex > 0) {
- writer.WriteAttribute("tabindex", this.TabIndex.ToString(CultureInfo.InvariantCulture));
+ writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, this.TabIndex.ToString(CultureInfo.InvariantCulture));
}
if (!this.Enabled) {
- writer.WriteAttribute("disabled", "true");
+ writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "true");
}
if (!string.IsNullOrEmpty(this.CssClass)) {
- writer.WriteAttribute("class", this.CssClass);
- }
- writer.Write(" style='");
- writer.WriteStyleAttribute("padding-left", "18px");
- writer.WriteStyleAttribute("border-style", "solid");
- writer.WriteStyleAttribute("border-width", "1px");
- writer.WriteStyleAttribute("border-color", "lightgray");
- writer.Write("'");
- writer.Write(" />");
-
- writer.WriteEndTag("span");
-
- // Emit a hidden field to let the javascript on the user agent know if an
- // authentication has already successfully taken place.
- string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
- if (!string.IsNullOrEmpty(viewstateAuthData)) {
- writer.WriteBeginTag("input");
- writer.WriteAttribute("type", "hidden");
- writer.WriteAttribute("name", this.OpenIdAuthDataFormKey);
- writer.WriteAttribute("value", viewstateAuthData, true);
- writer.Write(" />");
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
}
+ writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "18px");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "lightgray");
+ writer.RenderBeginTag(HtmlTextWriterTag.Input);
+ writer.RenderEndTag(); // </input>
+ writer.RenderEndTag(); // </span>
}
/// <summary>
- /// Filters a sequence of OP endpoints so that an OP hostname only appears once in the list.
+ /// When implemented by a class, processes postback data for an ASP.NET server control.
/// </summary>
- /// <param name="requests">The authentication requests against those OP endpoints.</param>
- /// <returns>The filtered list.</returns>
- private static List<IAuthenticationRequest> RemoveDuplicateEndpoints(List<IAuthenticationRequest> requests) {
- var filteredRequests = new List<IAuthenticationRequest>(requests.Count);
- foreach (IAuthenticationRequest request in requests) {
- // We'll distinguish based on the host name only, which
- // admittedly is only a heuristic, but if we remove one that really wasn't a duplicate, well,
- // this multiple OP attempt thing was just a convenience feature anyway.
- if (!filteredRequests.Any(req => string.Equals(req.Provider.Uri.Host, request.Provider.Uri.Host, StringComparison.OrdinalIgnoreCase))) {
- filteredRequests.Add(request);
+ /// <param name="postDataKey">The key identifier for the control.</param>
+ /// <param name="postCollection">The collection of all incoming name values.</param>
+ /// <returns>
+ /// true if the server control's state changes as a result of the postback; otherwise, false.
+ /// </returns>
+ protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
+ // If the control was temporarily hidden, it won't be in the Form data,
+ // and we'll just implicitly keep the last Text setting.
+ if (postCollection[this.Name] != null) {
+ Identifier identifier = postCollection[this.Name].Length == 0 ? null : postCollection[this.Name];
+ if (identifier != this.Identifier) {
+ this.Identifier = identifier;
+ return true;
}
}
- return filteredRequests;
+ return false;
}
/// <summary>
- /// Creates the relying party.
+ /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
/// </summary>
- /// <param name="verifySignature">
- /// A value indicating whether message protections should be applied to the processed messages.
- /// Use <c>false</c> to postpone verification to a later time without invalidating nonces.
- /// </param>
- /// <returns>The newly instantiated relying party.</returns>
- private static OpenIdRelyingParty CreateRelyingParty(bool verifySignature) {
- return verifySignature ? new OpenIdRelyingParty() : OpenIdRelyingParty.CreateNonVerifying();
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")]
+ protected virtual void RaisePostDataChangedEvent() {
+ this.OnTextChanged();
}
/// <summary>
- /// Releases unmanaged and - optionally - managed resources
+ /// Called on a postback when the Text property has changed.
/// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- private void Dispose(bool disposing) {
- if (disposing) {
- if (this.relyingParty != null) {
- this.relyingParty.Dispose();
- this.relyingParty = null;
- }
-
- if (this.relyingPartyNonVerifying != null) {
- this.relyingPartyNonVerifying.Dispose();
- this.relyingPartyNonVerifying = null;
- }
+ protected virtual void OnTextChanged() {
+ EventHandler textChanged = this.TextChanged;
+ if (textChanged != null) {
+ textChanged(this, EventArgs.Empty);
}
}
/// <summary>
- /// Fires the <see cref="LoggingIn"/> event.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns><c>true</c> if the login should proceed; <c>false</c> otherwise.</returns>
- private bool OnLoggingIn(IAuthenticationRequest request) {
- var loggingIn = this.LoggingIn;
- if (loggingIn != null) {
- var args = new OpenIdEventArgs(request);
- loggingIn(this, args);
- return !args.Cancel;
- }
-
- return true;
- }
-
- /// <summary>
- /// Fires the <see cref="UnconfirmedPositiveAssertion"/> event.
- /// </summary>
- private void OnUnconfirmedPositiveAssertion() {
- var unconfirmedPositiveAssertion = this.UnconfirmedPositiveAssertion;
- if (unconfirmedPositiveAssertion != null) {
- unconfirmedPositiveAssertion(this, null);
- }
- }
-
- /// <summary>
- /// Fires the <see cref="LoggedIn"/> event.
- /// </summary>
- /// <param name="response">The response.</param>
- private void OnLoggedIn(IAuthenticationResponse response) {
- var loggedIn = this.LoggedIn;
- if (loggedIn != null) {
- loggedIn(this, new OpenIdEventArgs(response));
- }
- }
-
- /// <summary>
- /// Invokes a method on a parent frame/window's OpenIdAjaxTextBox,
- /// and closes the calling popup window if applicable.
- /// </summary>
- /// <param name="methodCall">The method to call on the OpenIdAjaxTextBox, including
- /// parameters. (i.e. "callback('arg1', 2)"). No escaping is done by this method.</param>
- private void CallbackUserAgentMethod(string methodCall) {
- this.CallbackUserAgentMethod(methodCall, null);
- }
-
- /// <summary>
- /// Invokes a method on a parent frame/window's OpenIdAjaxTextBox,
- /// and closes the calling popup window if applicable.
- /// </summary>
- /// <param name="methodCall">The method to call on the OpenIdAjaxTextBox, including
- /// parameters. (i.e. "callback('arg1', 2)"). No escaping is done by this method.</param>
- /// <param name="preAssignments">An optional list of assignments to make to the input box object before placing the method call.</param>
- private void CallbackUserAgentMethod(string methodCall, string[] preAssignments) {
- Logger.OpenId.InfoFormat("Sending Javascript callback: {0}", methodCall);
- Page.Response.Write(@"<html><body><script language='javascript'>
- var inPopup = !window.frameElement;
- var objSrc = inPopup ? window.opener.waiting_openidBox : window.frameElement.openidBox;
-");
- if (preAssignments != null) {
- foreach (string assignment in preAssignments) {
- Page.Response.Write(string.Format(CultureInfo.InvariantCulture, " objSrc.{0};\n", assignment));
- }
- }
-
- // Something about calling objSrc.{0} can somehow cause FireFox to forget about the inPopup variable,
- // so we have to actually put the test for it ABOVE the call to objSrc.{0} so that it already
- // whether to call window.self.close() after the call.
- string htmlFormat = @" if (inPopup) {{
- objSrc.{0};
- window.self.close();
-}} else {{
- objSrc.{0};
-}}
-</script></body></html>";
- Page.Response.Write(string.Format(CultureInfo.InvariantCulture, htmlFormat, methodCall));
- Page.Response.End();
- }
-
- /// <summary>
/// Assembles the javascript to send to the client and registers it with ASP.NET for transmission.
/// </summary>
private void PrepareClientJavascript() {
- string identifierParameterName = "identifier";
- string discoveryCallbackResultParameterName = "resultFunction";
- string discoveryErrorCallbackParameterName = "errorCallback";
- string discoveryCallback = Page.ClientScript.GetCallbackEventReference(
- this,
- identifierParameterName,
- discoveryCallbackResultParameterName,
- identifierParameterName,
- discoveryErrorCallbackParameterName,
- true);
-
// Import the .js file where most of the code is.
this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdAjaxTextBox), EmbeddedScriptResourceName);
@@ -1186,12 +827,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
StringBuilder startupScript = new StringBuilder();
startupScript.AppendLine("<script language='javascript'>");
startupScript.AppendFormat("var box = document.getElementsByName('{0}')[0];{1}", this.Name, Environment.NewLine);
- if (this.focusCalled) {
- startupScript.AppendLine("box.focus();");
- }
startupScript.AppendFormat(
CultureInfo.InvariantCulture,
- "initAjaxOpenId(box, {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, function({18}, {19}, {20}) {{{21}}});{22}",
+ "initAjaxOpenId(box, {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, function() {{{21};}});{22}",
MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), OpenIdTextBox.EmbeddedLogoResourceName)),
MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedDotNetOpenIdLogoResourceName)),
MessagingUtilities.GetSafeJavascriptValue(this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedSpinnerResourceName)),
@@ -1202,6 +840,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
string.IsNullOrEmpty(this.OnClientAssertionReceived) ? "null" : "'" + this.OnClientAssertionReceived.Replace(@"\", @"\\").Replace("'", @"\'") + "'",
MessagingUtilities.GetSafeJavascriptValue(this.LogOnText),
MessagingUtilities.GetSafeJavascriptValue(this.LogOnToolTip),
+ this.ShowLogOnPostBackButton ? "true" : "false",
+ MessagingUtilities.GetSafeJavascriptValue(this.LogOnPostBackToolTip),
MessagingUtilities.GetSafeJavascriptValue(this.RetryText),
MessagingUtilities.GetSafeJavascriptValue(this.RetryToolTip),
MessagingUtilities.GetSafeJavascriptValue(this.BusyToolTip),
@@ -1210,124 +850,24 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationSucceededToolTip),
MessagingUtilities.GetSafeJavascriptValue(this.AuthenticatedAsToolTip),
MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationFailedToolTip),
- identifierParameterName,
- discoveryCallbackResultParameterName,
- discoveryErrorCallbackParameterName,
- discoveryCallback,
+ this.AutoPostBack ? "true" : "false",
+ Page.ClientScript.GetPostBackEventReference(this, null),
Environment.NewLine);
startupScript.AppendLine("</script>");
Page.ClientScript.RegisterStartupScript(this.GetType(), "ajaxstartup", startupScript.ToString());
- string htmlFormat = @"
+
+ if (this.HookFormSubmit) {
+ string htmlFormat = @"
var openidbox = document.getElementsByName('{0}')[0];
if (!openidbox.dnoi_internal.onSubmit()) {{ return false; }}
";
- Page.ClientScript.RegisterOnSubmitStatement(
- this.GetType(),
- "loginvalidation",
- string.Format(CultureInfo.InvariantCulture, htmlFormat, this.Name));
- }
-
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <param name="userSuppliedIdentifier">The user supplied identifier.</param>
- /// <param name="immediate">A value indicating whether the authentication
- /// requests should be initialized for use in invisible iframes for background authentication.</param>
- /// <returns>The list of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.</returns>
- private IEnumerable<IAuthenticationRequest> CreateRequests(string userSuppliedIdentifier, bool immediate) {
- var requests = new List<IAuthenticationRequest>();
-
- // Approximate the returnTo (either based on the customize property or the page URL)
- // so we can use it to help with Realm resolution.
- Uri returnToApproximation = this.ReturnToUrl != null ? new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.ReturnToUrl) : this.Page.Request.Url;
-
- // Resolve the trust root, and swap out the scheme and port if necessary to match the
- // return_to URL, since this match is required by OpenId, and the consumer app
- // may be using HTTP at some times and HTTPS at others.
- UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, this.RelyingParty.Channel.GetRequestFromContext());
- realm.Scheme = returnToApproximation.Scheme;
- realm.Port = returnToApproximation.Port;
-
- // Initiate openid request
- // We use TryParse here to avoid throwing an exception which
- // might slip through our validator control if it is disabled.
- Realm typedRealm = new Realm(realm);
- if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- requests.AddRange(this.RelyingParty.CreateRequests(userSuppliedIdentifier, typedRealm));
- } else {
- // Since the user actually gave us a return_to value,
- // the "approximation" is exactly what we want.
- requests.AddRange(this.RelyingParty.CreateRequests(userSuppliedIdentifier, typedRealm, returnToApproximation));
- }
-
- // Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
- // Since we're gathering OPs to try one after the other, just take the first choice of each OP
- // and don't try it multiple times.
- requests = RemoveDuplicateEndpoints(requests);
-
- // Configure each generated request.
- int reqIndex = 0;
- foreach (var req in requests) {
- req.AddCallbackArguments("index", (reqIndex++).ToString(CultureInfo.InvariantCulture));
-
- if (req.Provider.IsExtensionSupported<UIRequest>()) {
- // Inform the OP that we'll be using a popup window.
- req.AddExtension(new UIRequest());
-
- // Provide a hint for the client javascript about whether the OP supports the UI extension.
- // This is so the window can be made the correct size for the extension.
- // If the OP doesn't advertise support for the extension, the javascript will use
- // a bigger popup window.
- req.AddCallbackArguments("dotnetopenid.popupUISupported", "1");
- }
-
- // If the ReturnToUrl was explicitly set, we'll need to reset our first parameter
- if (string.IsNullOrEmpty(HttpUtility.ParseQueryString(req.ReturnToUrl.Query)["dotnetopenid.userSuppliedIdentifier"])) {
- req.AddCallbackArguments("dotnetopenid.userSuppliedIdentifier", userSuppliedIdentifier);
- }
-
- // Our javascript needs to let the user know which endpoint responded. So we force it here.
- // This gives us the info even for 1.0 OPs and 2.0 setup_required responses.
- req.AddCallbackArguments("dotnetopenid.op_endpoint", req.Provider.Uri.AbsoluteUri);
- req.AddCallbackArguments("dotnetopenid.claimed_id", (string)req.ClaimedIdentifier ?? string.Empty);
- req.AddCallbackArguments("dotnetopenid.phase", "2");
- if (immediate) {
- req.Mode = AuthenticationRequestMode.Immediate;
- ((AuthenticationRequest)req).AssociationPreference = AssociationPreference.IfAlreadyEstablished;
- }
- }
-
- return requests;
- }
-
- /// <summary>
- /// Notifies the user agent via an AJAX response of a completed authentication attempt.
- /// </summary>
- private void ReportAuthenticationResult() {
- Logger.OpenId.InfoFormat("AJAX (iframe) callback from OP: {0}", this.Page.Request.Url);
- List<string> assignments = new List<string>();
-
- var authResponse = this.RelyingPartyNonVerifying.GetResponse();
- if (authResponse.Status == AuthenticationStatus.Authenticated) {
- this.OnUnconfirmedPositiveAssertion();
- foreach (var pair in this.clientScriptExtensions) {
- IClientScriptExtensionResponse extension = (IClientScriptExtensionResponse)authResponse.GetExtension(pair.Key);
- if (extension == null) {
- continue;
- }
- var positiveResponse = (PositiveAuthenticationResponse)authResponse;
- string js = extension.InitializeJavaScriptData(positiveResponse.Response);
- if (string.IsNullOrEmpty(js)) {
- js = "null";
- }
- assignments.Add(pair.Value + " = " + js);
- }
+ Page.ClientScript.RegisterOnSubmitStatement(
+ this.GetType(),
+ "loginvalidation",
+ string.Format(CultureInfo.InvariantCulture, htmlFormat, this.Name));
}
-
- this.CallbackUserAgentMethod("dnoi_internal.processAuthorizationResult(document.URL)", assignments.ToArray());
}
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.css b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.css
new file mode 100644
index 0000000..bed2e79
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.css
@@ -0,0 +1,49 @@
+.OpenIdAjaxTextBox input
+{
+ margin: 0px;
+}
+
+.OpenIdAjaxTextBox > span
+{
+ position: absolute;
+ right: -1px;
+ top: 2px;
+}
+
+.OpenIdAjaxTextBox input[type=button]
+{
+ visibility: hidden;
+ position: absolute;
+ padding: 0px;
+ font-size: 8px;
+ top: 1px;
+ bottom: 1px;
+ right: 2px;
+}
+
+.OpenIdAjaxTextBox .yui-split-button span button
+{
+ font-size: 50%;
+ font-size: 60%\9; /* the \9 is a hack that causes only IE7/8 to use this value. */
+ line-height: 1;
+ min-height: 1em;
+ padding-top: 2px;
+ padding-top: 3px\9;
+ padding-bottom: 1px;
+ padding-left: 5px;
+ height: auto;
+}
+
+.OpenIdAjaxTextBox .yuimenuitem .yuimenuitemlabel
+{
+ padding-left: 5px;
+}
+
+.OpenIdAjaxTextBox .yuimenuitem .yuimenuitemlabel img
+{
+ border: 0;
+ margin-right: 4px;
+ vertical-align: middle;
+ width: 16px;
+ height: 16px;
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
index 1078003..1941175 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.js
@@ -1,152 +1,101 @@
//-----------------------------------------------------------------------
// <copyright file="OpenIdAjaxTextBox.js" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
+// This file may be used and redistributed under the terms of the
+// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
// </copyright>
//-----------------------------------------------------------------------
-// Options that can be set on the host page:
-//window.openid_visible_iframe = true; // causes the hidden iframe to show up
-//window.openid_trace = true; // causes lots of messages
-
-function trace(msg) {
- if (window.openid_trace) {
- if (!window.tracediv) {
- window.tracediv = document.createElement("ol");
- document.body.appendChild(window.tracediv);
- }
- var el = document.createElement("li");
- el.appendChild(document.createTextNode(msg));
- window.tracediv.appendChild(el);
- //alert(msg);
- }
-}
-
-/// <summary>Removes a given element from the array.</summary>
-/// <returns>True if the element was in the array, or false if it was not found.</returns>
-Array.prototype.remove = function(element) {
- function elementToRemoveLast(a, b) {
- if (a == element) { return 1; }
- if (b == element) { return -1; }
- return 0;
- }
- this.sort(elementToRemoveLast);
- if (this[this.length - 1] == element) {
- this.pop();
- return true;
- } else {
- return false;
- }
-};
-
function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url, success_icon_url, failure_icon_url,
throttle, timeout, assertionReceivedCode,
- loginButtonText, loginButtonToolTip, retryButtonText, retryButtonToolTip, busyToolTip,
+ loginButtonText, loginButtonToolTip, showLoginPostBackButton, loginPostBackToolTip,
+ retryButtonText, retryButtonToolTip, busyToolTip,
identifierRequiredMessage, loginInProgressMessage,
authenticatedByToolTip, authenticatedAsToolTip, authenticationFailedToolTip,
- discoverCallback, discoveryFailedCallback) {
- box.dnoi_internal = new Object();
+ autoPostback, postback) {
+ box.dnoi_internal = {
+ postback: postback
+ };
if (assertionReceivedCode) {
- box.dnoi_internal.onauthenticated = function(sender, e) { eval(assertionReceivedCode); }
+ box.dnoi_internal.onauthenticated = function(sender, e) { eval(assertionReceivedCode); };
}
box.dnoi_internal.originalBackground = box.style.background;
box.timeout = timeout;
- box.dnoi_internal.discoverIdentifier = discoverCallback;
- box.dnoi_internal.authenticationRequests = new Array();
-
- // The possible authentication results
- var authSuccess = new Object();
- var authRefused = new Object();
- var timedOut = new Object();
-
- function FrameManager(maxFrames) {
- this.queuedWork = new Array();
- this.frames = new Array();
- this.maxFrames = maxFrames;
-
- /// <summary>Called to queue up some work that will use an iframe as soon as it is available.</summary>
- /// <param name="job">
- /// A delegate that must return the url to point to iframe to.
- /// Its first parameter is the iframe created to service the request.
- /// It will only be called when the work actually begins.
- /// </param>
- this.enqueueWork = function(job) {
- // Assign an iframe to this task immediately if there is one available.
- if (this.frames.length < this.maxFrames) {
- this.createIFrame(job);
- } else {
- this.queuedWork.unshift(job);
- }
- };
- /// <summary>Clears the job queue and immediately closes all iframes.</summary>
- this.cancelAllWork = function() {
- trace('Canceling all open and pending iframes.');
- while (this.queuedWork.pop());
- this.closeFrames();
- };
-
- /// <summary>An event fired when a frame is closing.</summary>
- this.onJobCompleted = function() {
- // If there is a job in the queue, go ahead and start it up.
- if (job = this.queuedWork.pop()) {
- this.createIFrame(job);
- }
- }
-
- this.createIFrame = function(job) {
- var iframe = document.createElement("iframe");
- if (!window.openid_visible_iframe) {
- iframe.setAttribute("width", 0);
- iframe.setAttribute("height", 0);
- iframe.setAttribute("style", "display: none");
- }
- iframe.setAttribute("src", job(iframe));
- iframe.openidBox = box;
- box.parentNode.insertBefore(iframe, box);
- this.frames.push(iframe);
- return iframe;
- };
- this.closeFrames = function() {
- if (this.frames.length == 0) { return false; }
- for (var i = 0; i < this.frames.length; i++) {
- if (this.frames[i].parentNode) { this.frames[i].parentNode.removeChild(this.frames[i]); }
- }
- while (this.frames.length > 0) { this.frames.pop(); }
- return true;
- };
- this.closeFrame = function(frame) {
- if (frame.parentNode) { frame.parentNode.removeChild(frame); }
- var removed = this.frames.remove(frame);
- this.onJobCompleted();
- return removed;
- };
- }
-
- box.dnoi_internal.authenticationIFrames = new FrameManager(throttle);
+ box.dnoi_internal.authenticationIFrames = new window.dnoa_internal.FrameManager(throttle);
box.dnoi_internal.constructButton = function(text, tooltip, onclick) {
var button = document.createElement('input');
button.textContent = text; // Mozilla
button.value = text; // IE
button.type = 'button';
- button.title = tooltip != null ? tooltip : '';
+ button.title = tooltip || '';
button.onclick = onclick;
- button.style.visibility = 'hidden';
- button.style.position = 'absolute';
- button.style.padding = "0px";
- button.style.fontSize = '8px';
- button.style.top = "1px";
- button.style.bottom = "1px";
- button.style.right = "2px";
box.parentNode.appendChild(button);
return button;
- }
+ };
+
+ box.dnoi_internal.constructSplitButton = function(text, tooltip, onclick, menu) {
+ var htmlButton = box.dnoi_internal.constructButton(text, tooltip, onclick);
+
+ if (!box.parentNode.className || box.parentNode.className.indexOf(' yui-skin-sam') < 0) {
+ box.parentNode.className = (box.parentNode.className || '') + ' yui-skin-sam';
+ }
+
+ var splitButton = new YAHOO.widget.Button(htmlButton, {
+ type: 'split',
+ menu: menu
+ });
+
+ splitButton.on('click', onclick);
+
+ return splitButton;
+ };
+
+ box.dnoi_internal.createLoginPostBackButton = function() {
+ var postback = function() {
+ var discoveryResult = window.dnoa_internal.discoveryResults[box.value];
+ var respondingEndpoint = discoveryResult.findSuccessfulRequest();
+ box.dnoi_internal.postback(discoveryResult, respondingEndpoint, respondingEndpoint.extensionResponses, { background: false });
+ };
+ var button = box.dnoi_internal.constructButton(loginButtonText, loginPostBackToolTip, postback);
+ button.style.visibility = 'visible';
+ button.destroy = function() {
+ button.parentNode.removeChild(button);
+ };
+
+ return button;
+ };
+
+ box.dnoi_internal.createLoginButton = function(providers) {
+ var onMenuItemClick = function(p_sType, p_aArgs, p_oItem) {
+ var selectedProvider = (p_oItem && p_oItem.value) ? p_oItem.value : providers[0].value;
+ selectedProvider.loginPopup();
+ return false;
+ };
+
+ for (var i = 0; i < providers.length; i++) {
+ providers[i].onclick = { fn: onMenuItemClick };
+ }
+
+ // We'll use the split button if we have more than one Provider, and the YUI library is available.
+ if (providers.length > 1 && YAHOO && YAHOO.widget && YAHOO.widget.Button) {
+ return box.dnoi_internal.constructSplitButton(loginButtonText, loginButtonToolTip, onMenuItemClick, providers);
+ } else {
+ var button = box.dnoi_internal.constructButton(loginButtonText, loginButtonToolTip, onMenuItemClick);
+ button.style.visibility = 'visible';
+ button.destroy = function() {
+ button.parentNode.removeChild(button);
+ };
+ return button;
+ }
+ };
box.dnoi_internal.constructIcon = function(imageUrl, tooltip, rightSide, visible, height) {
var icon = document.createElement('img');
icon.src = imageUrl;
- icon.title = tooltip != null ? tooltip : '';
+ icon.title = tooltip || '';
icon.originalTitle = icon.title;
if (!visible) {
icon.style.visibility = 'hidden';
@@ -164,7 +113,7 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
}
box.parentNode.appendChild(icon);
return icon;
- }
+ };
box.dnoi_internal.prefetchImage = function(imageUrl) {
var img = document.createElement('img');
@@ -172,15 +121,15 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
img.style.display = 'none';
box.parentNode.appendChild(img);
return img;
- }
+ };
function findParentForm(element) {
- if (element == null || element.nodeName == "FORM") {
+ if (!element || element.nodeName == "FORM") {
return element;
}
return findParentForm(element.parentNode);
- };
+ }
box.parentForm = findParentForm(box);
@@ -196,22 +145,11 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
hiddenField.setAttribute("type", "hidden");
box.parentForm.appendChild(hiddenField);
return hiddenField;
- };
+ }
- box.dnoi_internal.loginButton = box.dnoi_internal.constructButton(loginButtonText, loginButtonToolTip, function() {
- var discoveryInfo = box.dnoi_internal.authenticationRequests[box.lastDiscoveredIdentifier];
- if (discoveryInfo == null) {
- trace('Ooops! Somehow the login button click event was invoked, but no openid discovery information for ' + box.lastDiscoveredIdentifier + ' is available.');
- return;
- }
- // The login button always sends a setup message to the first OP.
- var selectedProvider = discoveryInfo[0];
- selectedProvider.trySetup();
- return false;
- });
box.dnoi_internal.retryButton = box.dnoi_internal.constructButton(retryButtonText, retryButtonToolTip, function() {
box.timeout += 5000; // give the retry attempt 5s longer than the last attempt
- box.dnoi_internal.performDiscovery(box.value);
+ box.dnoi_internal.performDiscovery();
return false;
});
box.dnoi_internal.openid_logo = box.dnoi_internal.constructIcon(openid_logo_url, null, false, true);
@@ -219,24 +157,32 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.dnoi_internal.op_logo.style.maxWidth = '16px';
box.dnoi_internal.spinner = box.dnoi_internal.constructIcon(spinner_url, busyToolTip, true);
box.dnoi_internal.success_icon = box.dnoi_internal.constructIcon(success_icon_url, authenticatedAsToolTip, true);
- //box.dnoi_internal.failure_icon = box.dnoi_internal.constructIcon(failure_icon_url, authenticationFailedToolTip, true);
+ box.dnoi_internal.failure_icon = box.dnoi_internal.constructIcon(failure_icon_url, authenticationFailedToolTip, true);
// Disable the display of the DotNetOpenId logo
//box.dnoi_internal.dnoi_logo = box.dnoi_internal.constructIcon(dotnetopenid_logo_url);
box.dnoi_internal.dnoi_logo = box.dnoi_internal.openid_logo;
- box.dnoi_internal.setVisualCue = function(state, authenticatedBy, authenticatedAs) {
+ box.dnoi_internal.setVisualCue = function(state, authenticatedBy, authenticatedAs, providers, errorMessage) {
box.dnoi_internal.openid_logo.style.visibility = 'hidden';
box.dnoi_internal.dnoi_logo.style.visibility = 'hidden';
box.dnoi_internal.op_logo.style.visibility = 'hidden';
box.dnoi_internal.openid_logo.title = box.dnoi_internal.openid_logo.originalTitle;
box.dnoi_internal.spinner.style.visibility = 'hidden';
box.dnoi_internal.success_icon.style.visibility = 'hidden';
- // box.dnoi_internal.failure_icon.style.visibility = 'hidden';
- box.dnoi_internal.loginButton.style.visibility = 'hidden';
+ box.dnoi_internal.failure_icon.style.visibility = 'hidden';
box.dnoi_internal.retryButton.style.visibility = 'hidden';
+ if (box.dnoi_internal.loginButton) {
+ box.dnoi_internal.loginButton.destroy();
+ box.dnoi_internal.loginButton = null;
+ }
+ if (box.dnoi_internal.postbackLoginButton) {
+ box.dnoi_internal.postbackLoginButton.destroy();
+ box.dnoi_internal.postbackLoginButton = null;
+ }
box.title = '';
box.dnoi_internal.state = state;
+ var opLogo;
if (state == "discovering") {
box.dnoi_internal.dnoi_logo.style.visibility = 'visible';
box.dnoi_internal.spinner.style.visibility = 'visible';
@@ -244,42 +190,55 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.title = '';
window.status = "Discovering OpenID Identifier '" + box.value + "'...";
} else if (state == "authenticated") {
- var opLogo = box.dnoi_internal.deriveOPFavIcon();
+ opLogo = box.dnoi_internal.deriveOPFavIcon();
if (opLogo) {
box.dnoi_internal.op_logo.src = opLogo;
box.dnoi_internal.op_logo.style.visibility = 'visible';
box.dnoi_internal.op_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
}
- trace("OP icon size: " + box.dnoi_internal.op_logo.fileSize);
- if (opLogo == null || box.dnoi_internal.op_logo.fileSize == -1 /*IE*/ || box.dnoi_internal.op_logo.fileSize === undefined /* FF */) {
+ //trace("OP icon size: " + box.dnoi_internal.op_logo.fileSize);
+ // The filesize check just doesn't seem to work any more.
+ if (!opLogo) {// || box.dnoi_internal.op_logo.fileSize == -1 /*IE*/ || box.dnoi_internal.op_logo.fileSize === undefined /* FF */) {
trace('recovering from missing OP icon');
box.dnoi_internal.op_logo.style.visibility = 'hidden';
box.dnoi_internal.openid_logo.style.visibility = 'visible';
box.dnoi_internal.openid_logo.title = box.dnoi_internal.op_logo.originalTitle.replace('{0}', authenticatedBy.getHost());
}
- box.dnoi_internal.success_icon.style.visibility = 'visible';
- box.dnoi_internal.success_icon.title = box.dnoi_internal.success_icon.originalTitle.replace('{0}', authenticatedAs);
+ if (showLoginPostBackButton) {
+ box.dnoi_internal.postbackLoginButton = box.dnoi_internal.createLoginPostBackButton();
+ } else {
+ box.dnoi_internal.success_icon.style.visibility = 'visible';
+ box.dnoi_internal.success_icon.title = box.dnoi_internal.success_icon.originalTitle.replace('{0}', authenticatedAs);
+ }
box.title = box.dnoi_internal.claimedIdentifier;
- window.status = "Authenticated as " + box.value;
+ window.status = "Authenticated as " + authenticatedAs;
} else if (state == "setup") {
- var opLogo = box.dnoi_internal.deriveOPFavIcon();
+ opLogo = box.dnoi_internal.deriveOPFavIcon();
if (opLogo) {
box.dnoi_internal.op_logo.src = opLogo;
box.dnoi_internal.op_logo.style.visibility = 'visible';
} else {
box.dnoi_internal.openid_logo.style.visibility = 'visible';
}
- box.dnoi_internal.loginButton.style.visibility = 'visible';
+
+ box.dnoi_internal.loginButton = box.dnoi_internal.createLoginButton(providers);
+
box.dnoi_internal.claimedIdentifier = null;
- window.status = "Authentication requires setup.";
+ window.status = "Authentication requires user interaction.";
} else if (state == "failed") {
box.dnoi_internal.openid_logo.style.visibility = 'visible';
- //box.dnoi_internal.failure_icon.style.visibility = 'visible';
box.dnoi_internal.retryButton.style.visibility = 'visible';
box.dnoi_internal.claimedIdentifier = null;
window.status = authenticationFailedToolTip;
box.title = authenticationFailedToolTip;
- } else if (state == '' || state == null) {
+ } else if (state == "failednoretry") {
+ box.dnoi_internal.failure_icon.title = errorMessage;
+ box.dnoi_internal.failure_icon.style.visibility = 'visible';
+ box.dnoi_internal.openid_logo.style.visibility = 'visible';
+ box.dnoi_internal.claimedIdentifier = null;
+ window.status = errorMessage;
+ box.title = errorMessage;
+ } else if (state == '' || !state) {
box.dnoi_internal.openid_logo.style.visibility = 'visible';
box.title = '';
box.dnoi_internal.claimedIdentifier = null;
@@ -288,35 +247,39 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
box.dnoi_internal.claimedIdentifier = null;
trace('unrecognized state ' + state);
}
- }
+
+ if (box.onStateChanged) {
+ box.onStateChanged(state);
+ }
+ };
box.dnoi_internal.isBusy = function() {
- var lastDiscovery = box.dnoi_internal.authenticationRequests[box.lastDiscoveredIdentifier];
+ var lastDiscovery = window.dnoa_internal.discoveryResults[box.lastDiscoveredIdentifier];
return box.dnoi_internal.state == 'discovering' ||
(lastDiscovery && lastDiscovery.busy());
};
box.dnoi_internal.canAttemptLogin = function() {
- if (box.value.length == 0) return false;
- if (box.dnoi_internal.authenticationRequests[box.value] == null) return false;
- if (box.dnoi_internal.state == 'failed') return false;
+ if (box.value.length === 0) { return false; }
+ if (!window.dnoa_internal.discoveryResults[box.value]) { return false; }
+ if (box.dnoi_internal.state == 'failed') { return false; }
return true;
};
box.dnoi_internal.getUserSuppliedIdentifierResults = function() {
- return box.dnoi_internal.authenticationRequests[box.value];
- }
+ return window.dnoa_internal.discoveryResults[box.value];
+ };
box.dnoi_internal.isAuthenticated = function() {
var results = box.dnoi_internal.getUserSuppliedIdentifierResults();
- return results != null && results.findSuccessfulRequest() != null;
- }
+ return results && results.findSuccessfulRequest();
+ };
box.dnoi_internal.onSubmit = function() {
var hiddenField = findOrCreateHiddenField();
if (box.dnoi_internal.isAuthenticated()) {
// stick the result in a hidden field so the RP can verify it
- hiddenField.setAttribute("value", box.dnoi_internal.authenticationRequests[box.value].successAuthData);
+ hiddenField.setAttribute("value", window.dnoa_internal.discoveryResults[box.value].successAuthData);
} else {
hiddenField.setAttribute("value", '');
if (box.dnoi_internal.isBusy()) {
@@ -332,7 +295,7 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
// after leaving a note for ourselves to automatically click submit
// when login is complete.
box.dnoi_internal.submitPending = box.dnoi_internal.submitButtonJustClicked;
- if (box.dnoi_internal.submitPending == null) {
+ if (box.dnoi_internal.submitPending === null) {
box.dnoi_internal.submitPending = true;
}
box.dnoi_internal.loginButton.onclick();
@@ -380,398 +343,302 @@ function initAjaxOpenId(box, openid_logo_url, dotnetopenid_logo_url, spinner_url
/// <summary>
/// Returns the URL of the authenticating OP's logo so it can be displayed to the user.
/// </summary>
- box.dnoi_internal.deriveOPFavIcon = function() {
- var response = box.dnoi_internal.getUserSuppliedIdentifierResults().successAuthData;
- if (!response || response.length == 0) return;
- var authResult = new Uri(response);
- var opUri;
- if (authResult.getQueryArgValue("openid.op_endpoint")) {
- opUri = new Uri(authResult.getQueryArgValue("openid.op_endpoint"));
- } if (authResult.getQueryArgValue("dotnetopenid.op_endpoint")) {
- opUri = new Uri(authResult.getQueryArgValue("dotnetopenid.op_endpoint"));
- } else if (authResult.getQueryArgValue("openid.user_setup_url")) {
- opUri = new Uri(authResult.getQueryArgValue("openid.user_setup_url"));
- } else return null;
- var favicon = opUri.getAuthority() + "/favicon.ico";
- return favicon;
- };
-
- box.dnoi_internal.createDiscoveryInfo = function(discoveryInfo, identifier) {
- this.identifier = identifier;
- // The claimed identifier may be null if the user provided an OP Identifier.
- this.claimedIdentifier = discoveryInfo.claimedIdentifier;
- trace('Discovered claimed identifier: ' + this.claimedIdentifier);
-
- // Add extra tracking bits and behaviors.
- this.findByEndpoint = function(opEndpoint) {
- for (var i = 0; i < this.length; i++) {
- if (this[i].endpoint == opEndpoint) {
- return this[i];
- }
- }
- };
- this.findSuccessfulRequest = function() {
- for (var i = 0; i < this.length; i++) {
- if (this[i].result == authSuccess) {
- return this[i];
- }
- }
- };
- this.busy = function() {
- for (var i = 0; i < this.length; i++) {
- if (this[i].busy()) {
- return true;
- }
- }
- };
- this.abortAll = function() {
- // Abort all other asynchronous authentication attempts that may be in progress.
- box.dnoi_internal.authenticationIFrames.cancelAllWork();
- for (var i = 0; i < this.length; i++) {
- this[i].abort();
+ /// <param name="opUri">The OP Endpoint, if known.</param>
+ box.dnoi_internal.deriveOPFavIcon = function(opUri) {
+ if (!opUri) {
+ var idresults = box.dnoi_internal.getUserSuppliedIdentifierResults();
+ var response = idresults ? idresults.successAuthData : null;
+ if (!response || response.length === 0) {
+ trace('No favicon because no successAuthData.');
+ return;
}
- };
- this.tryImmediate = function() {
- if (this.length > 0) {
- for (var i = 0; i < this.length; i++) {
- box.dnoi_internal.authenticationIFrames.enqueueWork(this[i].tryImmediate);
- }
+ var authResult = new window.dnoa_internal.Uri(response);
+ if (authResult.getQueryArgValue("openid.op_endpoint")) {
+ opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("openid.op_endpoint"));
+ } else if (authResult.getQueryArgValue("dnoa.op_endpoint")) {
+ opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("dnoa.op_endpoint"));
+ } else if (authResult.getQueryArgValue("openid.user_setup_url")) {
+ opUri = new window.dnoa_internal.Uri(authResult.getQueryArgValue("openid.user_setup_url"));
} else {
- box.dnoi_internal.discoveryFailed(null, this.identifier);
+ return null;
}
- };
-
- this.length = discoveryInfo.requests.length;
- for (var i = 0; i < discoveryInfo.requests.length; i++) {
- this[i] = new box.dnoi_internal.createTrackingRequest(discoveryInfo.requests[i], identifier);
}
+ var favicon = opUri.getAuthority() + "/favicon.ico";
+ trace('Guessing favicon location of: ' + favicon);
+ return favicon;
};
- box.dnoi_internal.createTrackingRequest = function(requestInfo, identifier) {
- // It's possible during a postback that discovered request URLs are not available.
- this.immediate = requestInfo.immediate ? new Uri(requestInfo.immediate) : null;
- this.setup = requestInfo.setup ? new Uri(requestInfo.setup) : null;
- this.endpoint = new Uri(requestInfo.endpoint);
- this.identifier = identifier;
- var self = this; // closure so that delegates have the right instance
-
- this.host = self.endpoint.getHost();
+ /*****************************************
+ * Event Handlers
+ *****************************************/
- this.getDiscoveryInfo = function() {
- return box.dnoi_internal.authenticationRequests[self.identifier];
+ window.dnoa_internal.addDiscoveryStarted(function(identifier) {
+ if (identifier == box.value) {
+ box.dnoi_internal.setVisualCue('discovering');
}
+ });
- this.busy = function() {
- return self.iframe != null || self.popup != null;
- };
-
- this.completeAttempt = function() {
- if (!self.busy()) return false;
- if (self.iframe) {
- trace('iframe hosting ' + self.endpoint + ' now CLOSING.');
- box.dnoi_internal.authenticationIFrames.closeFrame(self.iframe);
- self.iframe = null;
- }
- if (self.popup) {
- self.popup.close();
- self.popup = null;
- }
- if (self.timeout) {
- window.clearTimeout(self.timeout);
- self.timeout = null;
- }
-
- if (!self.getDiscoveryInfo().busy() && self.getDiscoveryInfo().findSuccessfulRequest() == null) {
- trace('No asynchronous authentication attempt is in progress. Display setup view.');
- // visual cue that auth failed
- box.dnoi_internal.setVisualCue('setup');
- }
-
- return true;
- };
-
- this.authenticationTimedOut = function() {
- if (self.completeAttempt()) {
- trace(self.host + " timed out");
- self.result = timedOut;
- }
- };
- this.authSuccess = function(authUri) {
- if (self.completeAttempt()) {
- trace(self.host + " authenticated!");
- self.result = authSuccess;
- self.response = authUri;
- box.dnoi_internal.authenticationRequests[self.identifier].abortAll();
- }
- };
- this.authFailed = function() {
- if (self.completeAttempt()) {
- //trace(self.host + " failed authentication");
- self.result = authRefused;
- }
- };
- this.abort = function() {
- if (self.completeAttempt()) {
- trace(self.host + " aborted");
- // leave the result as whatever it was before.
+ window.dnoa_internal.addDiscoverySuccess(function(identifier, discoveryResult, state) {
+ if (identifier == box.value && (box.dnoi_internal.state == 'discovering' || !box.dnoi_internal.state)) {
+ // Start pre-fetching the OP favicons
+ for (var i = 0; i < discoveryResult.length; i++) {
+ var favicon = box.dnoi_internal.deriveOPFavIcon(discoveryResult[i].endpoint);
+ if (favicon) {
+ trace('Prefetching ' + favicon);
+ box.dnoi_internal.prefetchImage(favicon);
+ }
}
- };
-
- this.tryImmediate = function(iframe) {
- self.abort(); // ensure no concurrent attempts
- self.timeout = setTimeout(function() { self.authenticationTimedOut(); }, box.timeout);
- trace('iframe hosting ' + self.endpoint + ' now OPENING.');
- self.iframe = iframe;
- //trace('initiating auth attempt with: ' + self.immediate);
- return self.immediate.toString();
- };
- this.trySetup = function() {
- self.abort(); // ensure no concurrent attempts
- window.waiting_openidBox = box;
- var width = 800;
- var height = 600;
- if (self.setup.getQueryArgValue("openid.return_to").indexOf("dotnetopenid.popupUISupported") >= 0) {
- width = 450;
- height = 500;
+ if (discoveryResult.length > 0) {
+ discoveryResult.loginBackground(
+ box.dnoi_internal.authenticationIFrames,
+ null,
+ null,
+ null,
+ box.timeout);
+ } else {
+ // discovery completed successfully -- it just didn't yield any service endpoints.
+ box.dnoi_internal.setVisualCue('failednoretry', null, null, null, discoveryResult.error);
+ if (discoveryResult.error) { box.title = discoveryResult.error; }
}
+ }
+ });
- var left = (screen.width - width) / 2;
- var top = (screen.height - height) / 2;
- self.popup = window.open(self.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
-
- // If the OP supports the UI extension it MAY close its own window
- // for a negative assertion. We must be able to recover from that scenario.
- var localSelf = self;
- self.popupCloseChecker = window.setInterval(function() {
- if (localSelf.popup && localSelf.popup.closed) {
- // So the user canceled and the window closed.
- // It turns out we hae nothing special to do.
- // If we were graying out the entire page while the child window was up,
- // we would probably revert that here.
- trace('User or OP canceled by closing the window.');
- window.clearInterval(localSelf.popupCloseChecker);
- localSelf.popup = null;
- }
- }, 250);
- };
- };
-
- /*****************************************
- * Flow
- *****************************************/
-
- /// <summary>Called to initiate discovery on some identifier.</summary>
- box.dnoi_internal.performDiscovery = function(identifier) {
- box.dnoi_internal.authenticationIFrames.closeFrames();
- box.dnoi_internal.setVisualCue('discovering');
- box.lastDiscoveredIdentifier = identifier;
- box.dnoi_internal.discoverIdentifier(identifier, box.dnoi_internal.discoveryResult, box.dnoi_internal.discoveryFailed);
- };
-
- /// <summary>Callback that is invoked when discovery fails.</summary>
- box.dnoi_internal.discoveryFailed = function(message, identifier) {
- box.dnoi_internal.setVisualCue('failed');
- if (message) { box.title = message; }
- }
-
- /// <summary>Callback that is invoked when discovery results are available.</summary>
- /// <param name="discoveryResult">The JSON object containing the OpenID auth requests.</param>
- /// <param name="identifier">The identifier that discovery was performed on.</param>
- box.dnoi_internal.discoveryResult = function(discoveryResult, identifier) {
- // Deserialize the JSON object and store the result if it was a successful discovery.
- discoveryResult = eval('(' + discoveryResult + ')');
- // Store the discovery results and added behavior for later use.
- box.dnoi_internal.authenticationRequests[identifier] = discoveryBehavior = new box.dnoi_internal.createDiscoveryInfo(discoveryResult, identifier);
-
- // Only act on the discovery event if we're still interested in the result.
- // If the user already changed the identifier since discovery was initiated,
- // we aren't interested in it any more.
- if (identifier == box.lastDiscoveredIdentifier) {
- discoveryBehavior.tryImmediate();
+ window.dnoa_internal.addDiscoveryFailed(function(identifier, message) {
+ if (identifier == box.value) {
+ box.dnoi_internal.setVisualCue('failed');
+ if (message) { box.title = message; }
}
- }
+ });
- /// <summary>Invoked by RP web server when an authentication has completed.</summary>
- /// <remarks>The duty of this method is to distribute the notification to the appropriate tracking object.</remarks>
- box.dnoi_internal.processAuthorizationResult = function(resultUrl) {
- self.waiting_openidBox = null;
- //trace('processAuthorizationResult ' + resultUrl);
- var resultUri = new Uri(resultUrl);
-
- // Find the tracking object responsible for this request.
- var discoveryInfo = box.dnoi_internal.authenticationRequests[resultUri.getQueryArgValue('dotnetopenid.userSuppliedIdentifier')];
- if (discoveryInfo == null) {
- trace('processAuthorizationResult called but no userSuppliedIdentifier parameter was found. Exiting function.');
- return;
+ window.dnoa_internal.addAuthStarted(function(discoveryResult, serviceEndpoint, state) {
+ if (discoveryResult.userSuppliedIdentifier == box.value) {
+ box.dnoi_internal.setVisualCue('discovering');
}
- var opEndpoint = resultUri.getQueryArgValue("openid.op_endpoint") ? resultUri.getQueryArgValue("openid.op_endpoint") : resultUri.getQueryArgValue("dotnetopenid.op_endpoint");
- var tracker = discoveryInfo.findByEndpoint(opEndpoint);
- //trace('Auth result for ' + tracker.host + ' received:\n' + resultUrl);
-
- if (isAuthSuccessful(resultUri)) {
- tracker.authSuccess(resultUri);
-
- discoveryInfo.successAuthData = resultUrl;
- var claimed_id = resultUri.getQueryArgValue("openid.claimed_id");
- if (claimed_id && claimed_id != discoveryInfo.claimedIdentifier) {
- discoveryInfo.claimedIdentifier = resultUri.getQueryArgValue("openid.claimed_id");
- trace('Authenticated as ' + claimed_id);
- }
+ });
+ window.dnoa_internal.addAuthSuccess(function(discoveryResult, serviceEndpoint, extensionResponses, state) {
+ if (discoveryResult.userSuppliedIdentifier == box.value) {
// visual cue that auth was successful
- box.dnoi_internal.claimedIdentifier = discoveryInfo.claimedIdentifier;
- box.dnoi_internal.setVisualCue('authenticated', tracker.endpoint, discoveryInfo.claimedIdentifier);
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(discoveryResult.successAuthData);
+ box.dnoi_internal.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
+
+ // If the OP doesn't support delegation, "correct" the identifier the user entered
+ // so he realizes his identity didn't stick. But don't change out OP Identifiers.
+ if (discoveryResult.claimedIdentifier && discoveryResult.claimedIdentifier != parsedPositiveAssertion.claimedIdentifier) {
+ box.value = parsedPositiveAssertion.claimedIdentifier;
+ box.lastDiscoveredIdentifier = box.value;
+
+ // Also inject a fake discovery result for this new identifier to keep the UI from performing
+ // discovery on the new identifier (the RP will perform the necessary verification server-side).
+ if (!window.dnoa_internal.discoveryResults[box.value]) {
+ // We must make sure that the only service endpoint from the earlier discovery that
+ // is copied over is the one that sent the assertion just now. Deep clone, then strip
+ // out the other SEPs.
+ window.dnoa_internal.discoveryResults[box.value] = discoveryResult.cloneWithOneServiceEndpoint(serviceEndpoint);
+ }
+ }
+ box.dnoi_internal.setVisualCue('authenticated', parsedPositiveAssertion.endpoint, parsedPositiveAssertion.claimedIdentifier);
if (box.dnoi_internal.onauthenticated) {
- box.dnoi_internal.onauthenticated(box);
+ box.dnoi_internal.onauthenticated(box, extensionResponses);
}
- if (box.dnoi_internal.submitPending) {
+
+ if (showLoginPostBackButton && !state.background) {
+ box.dnoi_internal.postback(discoveryResult, serviceEndpoint, extensionResponses, state);
+ } else if (box.dnoi_internal.submitPending) {
// We submit the form BEFORE resetting the submitPending so
// the submit handler knows we've already tried this route.
- if (box.dnoi_internal.submitPending == true) {
+ if (box.dnoi_internal.submitPending === true) {
box.parentForm.submit();
} else {
box.dnoi_internal.submitPending.click();
}
+
+ box.dnoi_internal.submitPending = null;
+ } else if (!state.deserialized && autoPostback) {
+ // as long as this is a fresh auth response, postback to the server if configured to do so.
+ box.dnoi_internal.postback(discoveryResult, serviceEndpoint, extensionResponses, state);
}
- } else {
- tracker.authFailed();
}
+ });
- box.dnoi_internal.submitPending = null;
- };
+ window.dnoa_internal.addAuthFailed(function(discoveryResult, serviceEndpoint, state) {
+ if (discoveryResult.userSuppliedIdentifier == box.value) {
+ box.dnoi_internal.submitPending = null;
+ if (!serviceEndpoint || !state.background) { // if the last service endpoint just turned the user down
+ box.dnoi_internal.displayLoginButton(discoveryResult);
+ }
+ }
+ });
- function isAuthSuccessful(resultUri) {
- if (isOpenID2Response(resultUri)) {
- return resultUri.getQueryArgValue("openid.mode") == "id_res";
- } else {
- return resultUri.getQueryArgValue("openid.mode") == "id_res" && !resultUri.containsQueryArg("openid.user_setup_url");
+ window.dnoa_internal.addAuthCleared(function(discoveryResult, serviceEndpoint) {
+ if (discoveryResult.userSuppliedIdentifier == box.value) {
+ if (!discoveryResult.findSuccessfulRequest()) {
+ // attempt to renew the positive assertion.
+ discoveryResult.loginBackground(
+ box.dnoi_internal.authenticationIFrames,
+ null,
+ null,
+ null,
+ box.timeout);
+ }
}
+ });
+
+ box.dnoi_internal.displayLoginButton = function(discoveryResult) {
+ trace('No asynchronous authentication attempt is in progress. Display setup view.');
+ var providers = [];
+ for (var i = 0; i < discoveryResult.length; i++) {
+ var favicon = box.dnoi_internal.deriveOPFavIcon(discoveryResult[i].endpoint);
+ var img = '<img src="' + favicon + '" />';
+ providers.push({ text: img + discoveryResult[i].host, value: discoveryResult[i] });
+ }
+
+ // visual cue that auth failed
+ box.dnoi_internal.setVisualCue('setup', null, null, providers);
};
- function isOpenID2Response(resultUri) {
- return resultUri.containsQueryArg("openid.ns");
+ /*****************************************
+ * Flow
+ *****************************************/
+
+ /// <summary>Called to initiate discovery on some identifier.</summary>
+ box.dnoi_internal.performDiscovery = function() {
+ box.dnoi_internal.authenticationIFrames.closeFrames();
+ box.lastDiscoveredIdentifier = box.value;
+ var openid = new window.OpenIdIdentifier(box.value);
+ openid.discover();
};
box.onblur = function(event) {
- var discoveryInfo = box.dnoi_internal.authenticationRequests[box.value];
- if (discoveryInfo == null) {
+ if (box.lastDiscoveredIdentifier != box.value || !box.dnoi_internal.state) {
if (box.value.length > 0) {
- box.dnoi_internal.performDiscovery(box.value);
+ box.dnoi_internal.resetAndDiscover();
} else {
box.dnoi_internal.setVisualCue();
}
- } else {
- if ((priorSuccess = discoveryInfo.findSuccessfulRequest())) {
- box.dnoi_internal.setVisualCue('authenticated', priorSuccess.endpoint, discoveryInfo.claimedIdentifier);
- } else {
- discoveryInfo.tryImmediate();
- }
}
- return true;
- };
- box.onkeyup = function(event) {
- box.dnoi_internal.setVisualCue();
+
return true;
};
- box.getClaimedIdentifier = function() { return box.dnoi_internal.claimedIdentifier; };
+ //{
+ var rate = NaN;
+ var lastValue = box.value;
+ var keyPresses = 0;
+ var startTime = null;
+ var lastKeyPress = null;
+ var discoveryTimer;
+
+ function cancelTimer() {
+ if (discoveryTimer) {
+ trace('canceling timer', 'gray');
+ clearTimeout(discoveryTimer);
+ discoveryTimer = null;
+ }
+ }
- // Restore a previously achieved state (from pre-postback) if it is given.
- var oldAuth = findOrCreateHiddenField().value;
- if (oldAuth.length > 0) {
- var oldAuthResult = new Uri(oldAuth);
- // The control ensures that we ALWAYS have an OpenID 2.0-style claimed_id attribute, even against
- // 1.0 Providers via the return_to URL mechanism.
- var claimedId = oldAuthResult.getQueryArgValue("dotnetopenid.claimed_id");
- var endpoint = oldAuthResult.getQueryArgValue("dotnetopenid.op_endpoint");
- // We weren't given a full discovery history, but we can spoof this much from the
- // authentication assertion.
- box.dnoi_internal.authenticationRequests[box.value] = new box.dnoi_internal.createDiscoveryInfo({
- claimedIdentifier: claimedId,
- requests: [{ endpoint: endpoint }]
- }, box.value);
-
- box.dnoi_internal.processAuthorizationResult(oldAuthResult.toString());
- }
-}
+ function identifierSanityCheck(id) {
+ return id.match("^[=@+$!(].+|.*?\\..*[^\\.]|\\w+://.+");
+ }
-function Uri(url) {
- this.originalUri = url;
+ function discover() {
+ cancelTimer();
+ trace('typist discovery candidate', 'gray');
+ if (identifierSanityCheck(box.value)) {
+ trace('typist discovery begun', 'gray');
+ box.dnoi_internal.performDiscovery();
+ } else {
+ trace('typist discovery canceled due to incomplete identifier.', 'gray');
+ }
+ }
- this.toString = function() {
- return this.originalUri;
- };
+ function reset() {
+ keyPresses = 0;
+ startTime = null;
+ rate = NaN;
+ trace('resetting state', 'gray');
+ }
- this.getAuthority = function() {
- var authority = this.getScheme() + "://" + this.getHost();
- return authority;
- }
+ box.dnoi_internal.resetAndDiscover = function() {
+ reset();
+ discover();
+ };
- this.getHost = function() {
- var hostStartIdx = this.originalUri.indexOf("://") + 3;
- var hostEndIndex = this.originalUri.indexOf("/", hostStartIdx);
- if (hostEndIndex < 0) hostEndIndex = this.originalUri.length;
- var host = this.originalUri.substr(hostStartIdx, hostEndIndex - hostStartIdx);
- return host;
- }
+ box.onkeyup = function(e) {
+ e = e || window.event; // for IE
- this.getScheme = function() {
- var schemeStartIdx = this.indexOf("://");
- return this.originalUri.substr(this.originalUri, schemeStartIdx);
- }
+ if (new Date() - lastKeyPress > 3000) {
+ // the user seems to have altogether stopped typing,
+ // so reset our typist speed detector.
+ reset();
+ }
+ lastKeyPress = new Date();
- this.trimFragment = function() {
- var hashmark = this.originalUri.indexOf('#');
- if (hashmark >= 0) {
- return new Uri(this.originalUri.substr(0, hashmark));
- }
- return this;
- };
+ var newValue = box.value;
+ if (e.keyCode == 13) {
+ if (box.dnoi_internal.state == 'setup') {
+ box.dnoi_internal.loginButton.click();
+ } else {
+ discover();
+ }
+ } else {
+ if (lastValue != newValue && newValue != box.lastDiscoveredIdentifier) {
+ box.dnoi_internal.setVisualCue();
+ if (newValue.length === 0) {
+ reset();
+ } else if (Math.abs((lastValue || '').length - newValue.length) > 1) {
+ // One key press is responsible for multiple character changes.
+ // The user may have pasted in his identifier in which case
+ // we want to begin discovery immediately.
+ trace(newValue + ': paste detected (old value ' + lastValue + ')', 'gray');
+ discover();
+ } else {
+ keyPresses++;
+ var timeout = 3000; // timeout to use if we don't have enough keying to figure out type rate
+ if (startTime === null) {
+ startTime = new Date();
+ } else if (keyPresses > 1) {
+ cancelTimer();
+ rate = (new Date() - startTime) / keyPresses;
+ var minTimeout = 300;
+ var maxTimeout = 3000;
+ var typistFactor = 5;
+ timeout = Math.max(minTimeout, Math.min(rate * typistFactor, maxTimeout));
+ }
- this.appendQueryVariable = function(name, value) {
- var pair = encodeURI(name) + "=" + encodeURI(value);
- if (this.originalUri.indexOf('?') >= 0) {
- this.originalUri = this.originalUri + "&" + pair;
- } else {
- this.originalUri = this.originalUri + "?" + pair;
- }
- };
+ trace(newValue + ': setting timer for ' + timeout, 'gray');
+ discoveryTimer = setTimeout(discover, timeout);
+ }
+ }
+ }
- function KeyValuePair(key, value) {
- this.key = key;
- this.value = value;
- };
+ trace(newValue + ': updating lastValue', 'gray');
+ lastValue = newValue;
- this.Pairs = new Array();
+ return true;
+ };
+ //}
- var queryBeginsAt = this.originalUri.indexOf('?');
- if (queryBeginsAt >= 0) {
- this.queryString = url.substr(queryBeginsAt + 1);
- var queryStringPairs = this.queryString.split('&');
+ box.getClaimedIdentifier = function() { return box.dnoi_internal.claimedIdentifier; };
- for (var i = 0; i < queryStringPairs.length; i++) {
- var equalsAt = queryStringPairs[i].indexOf('=');
- left = (equalsAt >= 0) ? queryStringPairs[i].substring(0, equalsAt) : null;
- right = (equalsAt >= 0) ? queryStringPairs[i].substring(equalsAt + 1) : queryStringPairs[i];
- this.Pairs.push(new KeyValuePair(unescape(left), unescape(right)));
- }
- };
+ // If an identifier is preset on the box, perform discovery on it, but only
+ // if there isn't a prior authentication that we're about to deserialize.
+ if (box.value.length > 0 && findOrCreateHiddenField().value.length === 0) {
+ trace('jumpstarting discovery on ' + box.value + ' because it was preset.');
+ box.dnoi_internal.performDiscovery();
+ }
+
+ // Restore a previously achieved state (from pre-postback) if it is given.
+ window.dnoa_internal.deserializePreviousAuthentication(findOrCreateHiddenField().value);
- this.getQueryArgValue = function(key) {
- for (var i = 0; i < this.Pairs.length; i++) {
- if (this.Pairs[i].key == key) {
- return this.Pairs[i].value;
- }
+ // public methods
+ box.setValue = function(value) {
+ box.value = value;
+ if (box.value) {
+ box.dnoi_internal.performDiscovery();
}
};
- this.containsQueryArg = function(key) {
- return this.getQueryArgValue(key);
- };
-
- this.indexOf = function(args) {
- return this.originalUri.indexOf(args);
- };
-
- return this;
-};
+ // public events
+ // box.onStateChanged(state)
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs
index a090032..dbf6944 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs
@@ -20,7 +20,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// An ASP.NET control that renders a button that initiates an
/// authentication when clicked.
/// </summary>
- public class OpenIdButton : OpenIdRelyingPartyControlBase, IPostBackEventHandler {
+ public class OpenIdButton : OpenIdRelyingPartyControlBase {
#region Property defaults
/// <summary>
@@ -110,13 +110,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set { ErrorUtilities.VerifySupported(value == base.Popup, OpenIdStrings.PropertyValueNotSupported); }
}
- #region IPostBackEventHandler Members
-
/// <summary>
/// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
/// </summary>
/// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
- public void RaisePostBackEvent(string eventArgument) {
+ protected override void RaisePostBackEvent(string eventArgument) {
if (!this.PrecreateRequest) {
try {
IAuthenticationRequest request = this.CreateRequests().First();
@@ -127,8 +125,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
}
- #endregion
-
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
/// </summary>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdEventArgs.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdEventArgs.cs
index 4d68fcc..5668cf4 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdEventArgs.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdEventArgs.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -21,7 +22,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="request">The outgoing authentication request.</param>
internal OpenIdEventArgs(IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
this.Request = request;
this.ClaimedIdentifier = request.ClaimedIdentifier;
@@ -35,7 +36,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The incoming authentication response.</param>
internal OpenIdEventArgs(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.Response = response;
this.ClaimedIdentifier = response.ClaimedIdentifier;
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
index fe1ce67..3e13ef0 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs
@@ -8,10 +8,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
+ using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
+ using DotNetOpenAuth.Messaging;
/// <summary>
/// An ASP.NET control providing a complete OpenID login experience.
@@ -105,7 +108,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// The default value for the <see cref="RememberMe"/> property.
/// </summary>
- private const bool RememberMeDefault = UsePersistentCookieDefault;
+ private const bool RememberMeDefault = false;
/// <summary>
/// The default value for the <see cref="UriValidatorEnabled"/> property.
@@ -226,14 +229,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#region Events
/// <summary>
- /// Fired after the user clicks the log in button, but before the authentication
- /// process begins. Offers a chance for the web application to disallow based on
- /// OpenID URL before redirecting the user to the OpenID Provider.
- /// </summary>
- [Description("Fired after the user clicks the log in button, but before the authentication process begins. Offers a chance for the web application to disallow based on OpenID URL before redirecting the user to the OpenID Provider.")]
- public event EventHandler<OpenIdEventArgs> LoggingIn;
-
- /// <summary>
/// Fired when the Remember Me checkbox is changed by the user.
/// </summary>
[Description("Fires when the Remember Me checkbox is changed by the user.")]
@@ -242,6 +237,20 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
#region Properties
+
+ /// <summary>
+ /// Gets a <see cref="T:System.Web.UI.ControlCollection"/> object that represents the child controls for a specified server control in the UI hierarchy.
+ /// </summary>
+ /// <returns>
+ /// The collection of child controls for the specified server control.
+ /// </returns>
+ public override ControlCollection Controls {
+ get {
+ this.EnsureChildControls();
+ return base.Controls;
+ }
+ }
+
/// <summary>
/// Gets or sets the caption that appears before the text box.
/// </summary>
@@ -251,8 +260,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The caption that appears before the text box.")]
public string LabelText {
- get { return this.label.InnerText; }
- set { this.label.InnerText = value; }
+ get {
+ EnsureChildControls();
+ return this.label.InnerText;
+ }
+
+ set {
+ EnsureChildControls();
+ this.label.InnerText = value;
+ }
}
/// <summary>
@@ -264,8 +280,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text that introduces the example OpenID url.")]
public string ExamplePrefix {
- get { return this.examplePrefixLabel.Text; }
- set { this.examplePrefixLabel.Text = value; }
+ get {
+ EnsureChildControls();
+ return this.examplePrefixLabel.Text;
+ }
+
+ set {
+ EnsureChildControls();
+ this.examplePrefixLabel.Text = value;
+ }
}
/// <summary>
@@ -278,8 +301,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The example OpenID Identifier to display to the user.")]
public string ExampleUrl {
- get { return this.exampleUrlLabel.Text; }
- set { this.exampleUrlLabel.Text = value; }
+ get {
+ EnsureChildControls();
+ return this.exampleUrlLabel.Text;
+ }
+
+ set {
+ EnsureChildControls();
+ this.exampleUrlLabel.Text = value;
+ }
}
/// <summary>
@@ -292,8 +322,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text to display if the user attempts to login without providing an Identifier.")]
public string RequiredText {
- get { return this.requiredValidator.Text.Substring(0, this.requiredValidator.Text.Length - RequiredTextSuffix.Length); }
- set { this.requiredValidator.ErrorMessage = this.requiredValidator.Text = value + RequiredTextSuffix; }
+ get {
+ EnsureChildControls();
+ return this.requiredValidator.Text.Substring(0, this.requiredValidator.Text.Length - RequiredTextSuffix.Length);
+ }
+
+ set {
+ EnsureChildControls();
+ this.requiredValidator.ErrorMessage = this.requiredValidator.Text = value + RequiredTextSuffix;
+ }
}
/// <summary>
@@ -306,8 +343,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text to display if the user provides an invalid form for an Identifier.")]
public string UriFormatText {
- get { return this.identifierFormatValidator.Text.Substring(0, this.identifierFormatValidator.Text.Length - RequiredTextSuffix.Length); }
- set { this.identifierFormatValidator.ErrorMessage = this.identifierFormatValidator.Text = value + RequiredTextSuffix; }
+ get {
+ EnsureChildControls();
+ return this.identifierFormatValidator.Text.Substring(0, this.identifierFormatValidator.Text.Length - RequiredTextSuffix.Length);
+ }
+
+ set {
+ EnsureChildControls();
+ this.identifierFormatValidator.ErrorMessage = this.identifierFormatValidator.Text = value + RequiredTextSuffix;
+ }
}
/// <summary>
@@ -319,8 +363,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[DefaultValue(UriValidatorEnabledDefault)]
[Description("Whether to perform Identifier format validation prior to an authentication attempt.")]
public bool UriValidatorEnabled {
- get { return this.identifierFormatValidator.Enabled; }
- set { this.identifierFormatValidator.Enabled = value; }
+ get {
+ EnsureChildControls();
+ return this.identifierFormatValidator.Enabled;
+ }
+
+ set {
+ EnsureChildControls();
+ this.identifierFormatValidator.Enabled = value;
+ }
}
/// <summary>
@@ -332,8 +383,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text of the link users can click on to obtain an OpenID.")]
public string RegisterText {
- get { return this.registerLink.Text; }
- set { this.registerLink.Text = value; }
+ get {
+ EnsureChildControls();
+ return this.registerLink.Text;
+ }
+
+ set {
+ EnsureChildControls();
+ this.registerLink.Text = value;
+ }
}
/// <summary>
@@ -346,8 +404,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The URL to link users to who click the link to obtain a new OpenID.")]
public string RegisterUrl {
- get { return this.registerLink.NavigateUrl; }
- set { this.registerLink.NavigateUrl = value; }
+ get {
+ EnsureChildControls();
+ return this.registerLink.NavigateUrl;
+ }
+
+ set {
+ EnsureChildControls();
+ this.registerLink.NavigateUrl = value;
+ }
}
/// <summary>
@@ -360,8 +425,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text of the tooltip to display when the user hovers over the link to obtain a new OpenID.")]
public string RegisterToolTip {
- get { return this.registerLink.ToolTip; }
- set { this.registerLink.ToolTip = value; }
+ get {
+ EnsureChildControls();
+ return this.registerLink.ToolTip;
+ }
+
+ set {
+ EnsureChildControls();
+ this.registerLink.ToolTip = value;
+ }
}
/// <summary>
@@ -373,8 +445,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[DefaultValue(RegisterVisibleDefault)]
[Description("Whether to display a link to allow users to easily obtain a new OpenID.")]
public bool RegisterVisible {
- get { return this.registerLink.Visible; }
- set { this.registerLink.Visible = value; }
+ get {
+ EnsureChildControls();
+ return this.registerLink.Visible;
+ }
+
+ set {
+ EnsureChildControls();
+ this.registerLink.Visible = value;
+ }
}
/// <summary>
@@ -386,8 +465,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text that appears on the button that initiates login.")]
public string ButtonText {
- get { return this.loginButton.Text; }
- set { this.loginButton.Text = value; }
+ get {
+ EnsureChildControls();
+ return this.loginButton.Text;
+ }
+
+ set {
+ EnsureChildControls();
+ this.loginButton.Text = value;
+ }
}
/// <summary>
@@ -399,8 +485,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The text of the \"Remember Me\" checkbox.")]
public string RememberMeText {
- get { return this.rememberMeCheckBox.Text; }
- set { this.rememberMeCheckBox.Text = value; }
+ get {
+ EnsureChildControls();
+ return this.rememberMeCheckBox.Text;
+ }
+
+ set {
+ EnsureChildControls();
+ this.rememberMeCheckBox.Text = value;
+ }
}
/// <summary>
@@ -438,8 +531,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[DefaultValue(RememberMeVisibleDefault)]
[Description("Whether the \"Remember Me\" checkbox should be displayed.")]
public bool RememberMeVisible {
- get { return this.rememberMeCheckBox.Visible; }
- set { this.rememberMeCheckBox.Visible = value; }
+ get {
+ EnsureChildControls();
+ return this.rememberMeCheckBox.Visible;
+ }
+
+ set {
+ EnsureChildControls();
+ this.rememberMeCheckBox.Visible = value;
+ }
}
/// <summary>
@@ -448,11 +548,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
[Bindable(true)]
[Category("Appearance")]
- [DefaultValue(UsePersistentCookieDefault)]
+ [DefaultValue(RememberMeDefault)]
[Description("Whether a successful authentication should result in a persistent cookie being saved to the browser.")]
public bool RememberMe {
- get { return this.UsePersistentCookie; }
- set { this.UsePersistentCookie = value; }
+ get { return this.UsePersistentCookie != LogOnPersistence.Session; }
+ set { this.UsePersistentCookie = value ? LogOnPersistence.PersistentAuthentication : LogOnPersistence.Session; }
}
/// <summary>
@@ -468,7 +568,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set {
unchecked {
- this.WrappedTextBox.TabIndex = (short)(value + TextBoxTabIndexOffset);
+ EnsureChildControls();
+ base.TabIndex = (short)(value + TextBoxTabIndexOffset);
this.loginButton.TabIndex = (short)(value + LoginButtonTabIndexOffset);
this.rememberMeCheckBox.TabIndex = (short)(value + RememberMeTabIndexOffset);
this.registerLink.TabIndex = (short)(value + RegisterTabIndexOffset);
@@ -485,8 +586,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Localizable(true)]
[Description("The tooltip to display when the user hovers over the login button.")]
public string ButtonToolTip {
- get { return this.loginButton.ToolTip; }
- set { this.loginButton.ToolTip = value; }
+ get {
+ EnsureChildControls();
+ return this.loginButton.ToolTip;
+ }
+
+ set {
+ EnsureChildControls();
+ this.loginButton.ToolTip = value;
+ }
}
/// <summary>
@@ -497,10 +605,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Description("The validation group that the login button and text box validator belong to.")]
public string ValidationGroup {
get {
+ EnsureChildControls();
return this.requiredValidator.ValidationGroup;
}
set {
+ EnsureChildControls();
this.requiredValidator.ValidationGroup = value;
this.loginButton.ValidationGroup = value;
}
@@ -525,7 +635,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// cookie should persist across user sessions.
/// </summary>
[Browsable(false), Bindable(false)]
- public override bool UsePersistentCookie {
+ public override LogOnPersistence UsePersistentCookie {
get {
return base.UsePersistentCookie;
}
@@ -535,8 +645,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// use conditional here to prevent infinite recursion
// with CheckedChanged event.
- if (this.rememberMeCheckBox.Checked != value) {
- this.rememberMeCheckBox.Checked = value;
+ bool rememberMe = value != LogOnPersistence.Session;
+ if (this.rememberMeCheckBox.Checked != rememberMe) {
+ this.rememberMeCheckBox.Checked = rememberMe;
}
}
}
@@ -544,27 +655,40 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
/// <summary>
+ /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
+ /// </summary>
+ /// <param name="writer">The <see cref="T:System.Web.UI.HTmlTextWriter"/> object that receives the control content.</param>
+ public override void RenderControl(HtmlTextWriter writer) {
+ this.RenderChildren(writer);
+ }
+
+ /// <summary>
/// Creates the child controls.
/// </summary>
protected override void CreateChildControls() {
- // Don't call base.CreateChildControls(). This would add the WrappedTextBox
- // to the Controls collection, which would implicitly remove it from the table
- // we have already added it to.
+ this.InitializeControls();
// Just add the panel we've assembled earlier.
- this.Controls.Add(this.panel);
+ base.Controls.Add(this.panel);
+ }
- if (ShouldBeFocused) {
- WrappedTextBox.Focus();
- }
+ /// <summary>
+ /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
+ /// </summary>
+ /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
+ protected override void OnPreRender(EventArgs e) {
+ base.OnPreRender(e);
+
+ EnsureChildControls();
+ EnsureID();
+ this.requiredValidator.ControlToValidate = this.ID;
+ this.identifierFormatValidator.ControlToValidate = this.ID;
}
/// <summary>
/// Initializes the child controls.
/// </summary>
- protected override void InitializeControls() {
- base.InitializeControls();
-
+ protected void InitializeControls() {
this.panel = new Panel();
Table table = new Table();
@@ -583,7 +707,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// top row, middle cell
cell = new TableCell();
- cell.Controls.Add(this.WrappedTextBox);
+ cell.Controls.Add(new InPlaceControl(this));
row1.Cells.Add(cell);
// top row, right cell
@@ -611,7 +735,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
this.requiredValidator.ErrorMessage = RequiredTextDefault + RequiredTextSuffix;
this.requiredValidator.Text = RequiredTextDefault + RequiredTextSuffix;
this.requiredValidator.Display = ValidatorDisplay.Dynamic;
- this.requiredValidator.ControlToValidate = WrappedTextBox.ID;
this.requiredValidator.ValidationGroup = ValidationGroupDefault;
cell.Controls.Add(this.requiredValidator);
this.identifierFormatValidator = new CustomValidator();
@@ -620,7 +743,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
this.identifierFormatValidator.ServerValidate += this.IdentifierFormatValidator_ServerValidate;
this.identifierFormatValidator.Enabled = UriValidatorEnabledDefault;
this.identifierFormatValidator.Display = ValidatorDisplay.Dynamic;
- this.identifierFormatValidator.ControlToValidate = WrappedTextBox.ID;
this.identifierFormatValidator.ValidationGroup = ValidationGroupDefault;
cell.Controls.Add(this.identifierFormatValidator);
this.errorLabel = new Label();
@@ -680,26 +802,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Customizes HTML rendering of the control.
- /// </summary>
- /// <param name="writer">An <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>
- protected override void Render(HtmlTextWriter writer) {
- // avoid writing begin and end SPAN tags for XHTML validity.
- RenderContents(writer);
- }
-
- /// <summary>
/// Renders the child controls.
/// </summary>
/// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the rendered content.</param>
protected override void RenderChildren(HtmlTextWriter writer) {
if (!this.DesignMode) {
- this.label.Attributes["for"] = this.WrappedTextBox.ClientID;
+ this.label.Attributes["for"] = this.ClientID;
if (!string.IsNullOrEmpty(this.IdSelectorIdentifier)) {
this.idselectorJavascript.Visible = true;
this.idselectorJavascript.Text = @"<script type='text/javascript'><!--
-idselector_input_id = '" + WrappedTextBox.ClientID + @"';
+idselector_input_id = '" + this.ClientID + @"';
// --></script>
<script type='text/javascript' id='__openidselector' src='https://www.idselector.com/selector/" + this.IdSelectorIdentifier + @"' charset='utf-8'></script>";
} else {
@@ -737,30 +850,6 @@ idselector_input_id = '" + WrappedTextBox.ClientID + @"';
}
/// <summary>
- /// Fires the <see cref="LoggingIn"/> event.
- /// </summary>
- /// <returns>
- /// Returns whether the login should proceed. False if some event handler canceled the request.
- /// </returns>
- protected virtual bool OnLoggingIn() {
- EventHandler<OpenIdEventArgs> loggingIn = this.LoggingIn;
- if (this.Request == null) {
- this.CreateRequest();
- }
-
- if (this.Request != null) {
- OpenIdEventArgs args = new OpenIdEventArgs(this.Request);
- if (loggingIn != null) {
- loggingIn(this, args);
- }
-
- return !args.Cancel;
- } else {
- return false;
- }
- }
-
- /// <summary>
/// Fires the <see cref="RememberMeChanged"/> event.
/// </summary>
protected virtual void OnRememberMeChanged() {
@@ -799,8 +888,49 @@ idselector_input_id = '" + WrappedTextBox.ClientID + @"';
return;
}
- if (this.OnLoggingIn()) {
- this.LogOn();
+ IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
+ if (request != null) {
+ this.LogOn(request);
+ } else {
+ if (!string.IsNullOrEmpty(this.FailedMessageText)) {
+ this.errorLabel.Text = string.Format(CultureInfo.CurrentCulture, this.FailedMessageText, OpenIdStrings.OpenIdEndpointNotFound);
+ this.errorLabel.Visible = true;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Renders the control inner.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ private void RenderControlInner(HtmlTextWriter writer) {
+ base.RenderControl(writer);
+ }
+
+ /// <summary>
+ /// A control that acts as a placeholder to indicate where
+ /// the OpenIdLogin control should render its OpenIdTextBox parent.
+ /// </summary>
+ private class InPlaceControl : PlaceHolder {
+ /// <summary>
+ /// The owning control to render.
+ /// </summary>
+ private OpenIdLogin renderControl;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InPlaceControl"/> class.
+ /// </summary>
+ /// <param name="renderControl">The render control.</param>
+ internal InPlaceControl(OpenIdLogin renderControl) {
+ this.renderControl = renderControl;
+ }
+
+ /// <summary>
+ /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
+ /// </summary>
+ /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
+ protected override void Render(HtmlTextWriter writer) {
+ this.renderControl.RenderControlInner(writer);
}
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdMobileTextBox.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdMobileTextBox.cs
index e6e31e5..ce77df1 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdMobileTextBox.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdMobileTextBox.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web.Security;
@@ -581,8 +582,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")]
public IAuthenticationRequest CreateRequest() {
- ErrorUtilities.VerifyOperation(this.Request == null, OpenIdStrings.CreateRequestAlreadyCalled);
- ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Text), OpenIdStrings.OpenIdTextBoxEmpty);
+ Contract.Requires<InvalidOperationException>(this.Request == null, OpenIdStrings.CreateRequestAlreadyCalled);
+ Contract.Requires<InvalidOperationException>(!string.IsNullOrEmpty(this.Text), OpenIdStrings.OpenIdTextBoxEmpty);
try {
// Resolve the trust root, and swap out the scheme and port if necessary to match the
@@ -610,7 +611,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
// Add state that needs to survive across the redirect.
- this.Request.AddCallbackArguments(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString(CultureInfo.InvariantCulture));
+ this.Request.SetUntrustedCallbackArgument(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString(CultureInfo.InvariantCulture));
} else {
Logger.OpenId.WarnFormat("An invalid identifier was entered ({0}), but not caught by any validation routine.", this.Text);
this.Request = null;
@@ -667,7 +668,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnLoggedIn(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Authenticated, "Firing OnLoggedIn event without an authenticated response.");
var loggedIn = this.LoggedIn;
@@ -686,7 +687,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnFailed(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Failed, "Firing Failed event for the wrong response type.");
var failed = this.Failed;
@@ -700,7 +701,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnCanceled(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Canceled, "Firing Canceled event for the wrong response type.");
var canceled = this.Canceled;
@@ -714,7 +715,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnSetupRequired(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.SetupRequired, "Firing SetupRequired event for the wrong response type.");
// Why are we firing Failed when we're OnSetupRequired? Backward compatibility.
@@ -732,7 +733,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="request">The authentication request to add the extensions to.</param>
private void AddProfileArgs(IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
request.AddExtension(new ClaimsRequest() {
Nickname = this.RequestNickname,
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cd b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cd
new file mode 100644
index 0000000..0519ecb
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cd
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
index 68dd4e9..2808d39 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -87,8 +87,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// If we are a smart-mode RP (supporting associations), then we MUST also be
// capable of storing nonces to prevent replay attacks.
// If we're a dumb-mode RP, then 2.0 OPs are responsible for preventing replays.
- Contract.Requires(associationStore == null || nonceStore != null);
- ErrorUtilities.VerifyArgument(associationStore == null || nonceStore != null, OpenIdStrings.AssociationStoreRequiresNonceStore);
+ Contract.Requires<ArgumentException>(associationStore == null || nonceStore != null, OpenIdStrings.AssociationStoreRequiresNonceStore);
this.securitySettings = DotNetOpenAuthSection.Configuration.OpenId.RelyingParty.SecuritySettings.CreateSecuritySettings();
this.behaviors.CollectionChanged += this.OnBehaviorsChanged;
@@ -155,8 +154,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.channel = value;
this.AssociationManager.Channel = value;
}
@@ -172,8 +170,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
internal set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.securitySettings = value;
this.AssociationManager.SecuritySettings = value;
}
@@ -206,8 +203,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
set {
- Contract.Requires(value != null);
- ErrorUtilities.VerifyArgumentNotNull(value, "value");
+ Contract.Requires<ArgumentNullException>(value != null);
this.endpointOrder = value;
}
}
@@ -273,9 +269,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </returns>
/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
public IAuthenticationRequest CreateRequest(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(realm != null);
- Contract.Requires(returnToUrl != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
+ Contract.Requires<ArgumentNullException>(returnToUrl != null);
Contract.Ensures(Contract.Result<IAuthenticationRequest>() != null);
try {
return this.CreateRequests(userSuppliedIdentifier, realm, returnToUrl).First();
@@ -306,11 +302,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
public IAuthenticationRequest CreateRequest(Identifier userSuppliedIdentifier, Realm realm) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(realm != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
Contract.Ensures(Contract.Result<IAuthenticationRequest>() != null);
try {
- return this.CreateRequests(userSuppliedIdentifier, realm).First();
+ var result = this.CreateRequests(userSuppliedIdentifier, realm).First();
+ Contract.Assume(result != null);
+ return result;
} catch (InvalidOperationException ex) {
throw ErrorUtilities.Wrap(ex, OpenIdStrings.OpenIdEndpointNotFound);
}
@@ -333,7 +331,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <exception cref="ProtocolException">Thrown if no OpenID endpoint could be found.</exception>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
public IAuthenticationRequest CreateRequest(Identifier userSuppliedIdentifier) {
- Contract.Requires(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
Contract.Ensures(Contract.Result<IAuthenticationRequest>() != null);
try {
return this.CreateRequests(userSuppliedIdentifier).First();
@@ -370,12 +368,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// An empty enumerable is returned instead.</para>
/// </remarks>
public IEnumerable<IAuthenticationRequest> CreateRequests(Identifier userSuppliedIdentifier, Realm realm, Uri returnToUrl) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(realm != null);
- Contract.Requires(returnToUrl != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
+ Contract.Requires<ArgumentNullException>(returnToUrl != null);
Contract.Ensures(Contract.Result<IEnumerable<IAuthenticationRequest>>() != null);
- ErrorUtilities.VerifyArgumentNotNull(realm, "realm");
- ErrorUtilities.VerifyArgumentNotNull(returnToUrl, "returnToUrl");
return AuthenticationRequest.Create(userSuppliedIdentifier, this, realm, returnToUrl, true).Cast<IAuthenticationRequest>();
}
@@ -406,10 +402,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
public IEnumerable<IAuthenticationRequest> CreateRequests(Identifier userSuppliedIdentifier, Realm realm) {
- Contract.Requires(userSuppliedIdentifier != null);
- Contract.Requires(realm != null);
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(realm != null);
Contract.Ensures(Contract.Result<IEnumerable<IAuthenticationRequest>>() != null);
- ErrorUtilities.VerifyHttpContext();
+ Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<IAuthenticationRequest>>(), el => el != null));
// Build the return_to URL
UriBuilder returnTo = new UriBuilder(this.Channel.GetRequestFromContext().UrlBeforeRewriting);
@@ -450,9 +447,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown if <see cref="HttpContext.Current">HttpContext.Current</see> == <c>null</c>.</exception>
public IEnumerable<IAuthenticationRequest> CreateRequests(Identifier userSuppliedIdentifier) {
- Contract.Requires(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
+ Contract.Requires<InvalidOperationException>(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired);
Contract.Ensures(Contract.Result<IEnumerable<IAuthenticationRequest>>() != null);
- ErrorUtilities.VerifyHttpContext();
// Build the realm URL
UriBuilder realmUrl = new UriBuilder(this.Channel.GetRequestFromContext().UrlBeforeRewriting);
@@ -488,7 +485,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="httpRequestInfo">The HTTP request that may be carrying an authentication response from the Provider.</param>
/// <returns>The processed authentication response if there is any; <c>null</c> otherwise.</returns>
public IAuthenticationResponse GetResponse(HttpRequestInfo httpRequestInfo) {
- Contract.Requires(httpRequestInfo != null);
+ Contract.Requires<ArgumentNullException>(httpRequestInfo != null);
try {
var message = this.Channel.ReadFromRequest(httpRequestInfo);
PositiveAssertionResponse positiveAssertion;
@@ -571,18 +568,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
return rp;
}
-#if CONTRACTS_FULL
- /// <summary>
- /// Verifies conditions that should be true for any valid state of this object.
- /// </summary>
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
- [ContractInvariantMethod]
- private void ObjectInvariant() {
- Contract.Invariant(this.SecuritySettings != null);
- Contract.Invariant(this.Channel != null);
- }
-#endif
-
/// <summary>
/// Releases unmanaged and - optionally - managed resources
/// </summary>
@@ -607,5 +592,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
profile.ApplySecuritySettings(this.SecuritySettings);
}
}
+
+#if CONTRACTS_FULL
+ /// <summary>
+ /// Verifies conditions that should be true for any valid state of this object.
+ /// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
+ [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
+ [ContractInvariantMethod]
+ private void ObjectInvariant() {
+ Contract.Invariant(this.SecuritySettings != null);
+ Contract.Invariant(this.Channel != null);
+ Contract.Invariant(this.EndpointOrder != null);
+ }
+#endif
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
index da2a9ae..4281d96 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.cs
@@ -12,24 +12,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
- using System.Drawing.Design;
using System.Globalization;
using System.Linq;
using System.Text;
- using System.Text.RegularExpressions;
using System.Web;
- using System.Web.Security;
using System.Web.UI;
- using DotNetOpenAuth.ComponentModel;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Extensions.UI;
/// <summary>
/// A common base class for OpenID Relying Party controls.
/// </summary>
- internal abstract class OpenIdRelyingPartyAjaxControlBase : OpenIdRelyingPartyControlBase, ICallbackEventHandler {
+ public abstract class OpenIdRelyingPartyAjaxControlBase : OpenIdRelyingPartyControlBase, ICallbackEventHandler {
/// <summary>
/// The manifest resource name of the javascript file to include on the hosting page.
/// </summary>
@@ -38,15 +33,61 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// The name of the javascript function that will initiate a synchronous callback.
/// </summary>
- protected const string CallbackJsFunction = "window.dnoa_internal.callback";
+ protected const string CallbackJSFunction = "window.dnoa_internal.callback";
/// <summary>
/// The name of the javascript function that will initiate an asynchronous callback.
/// </summary>
- protected const string CallbackJsFunctionAsync = "window.dnoa_internal.callbackAsync";
+ protected const string CallbackJSFunctionAsync = "window.dnoa_internal.callbackAsync";
/// <summary>
- /// Stores the result of a AJAX callback discovery.
+ /// The name of the javascript field that stores the maximum time a positive assertion is
+ /// good for before it must be refreshed.
+ /// </summary>
+ private const string MaxPositiveAssertionLifetimeJsName = "window.dnoa_internal.maxPositiveAssertionLifetime";
+
+ /// <summary>
+ /// The "dnoa.op_endpoint" string.
+ /// </summary>
+ private const string OPEndpointParameterName = OpenIdUtilities.CustomParameterPrefix + "op_endpoint";
+
+ /// <summary>
+ /// The "dnoa.claimed_id" string.
+ /// </summary>
+ private const string ClaimedIdParameterName = OpenIdUtilities.CustomParameterPrefix + "claimed_id";
+
+ #region Property viewstate keys
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of a successful authentication.
+ /// </summary>
+ private const string AuthDataViewStateKey = "AuthData";
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="AuthenticationResponse"/> property.
+ /// </summary>
+ private const string AuthenticationResponseViewStateKey = "AuthenticationResponse";
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="AuthenticationProcessedAlready"/> property.
+ /// </summary>
+ private const string AuthenticationProcessedAlreadyViewStateKey = "AuthenticationProcessedAlready";
+
+ #endregion
+
+ /// <summary>
+ /// Backing field for the <see cref="RelyingPartyNonVerifying"/> property.
+ /// </summary>
+ private static OpenIdRelyingParty relyingPartyNonVerifying;
+
+ /// <summary>
+ /// The authentication response that just came in.
+ /// </summary>
+ private IAuthenticationResponse authenticationResponse;
+
+ /// <summary>
+ /// Stores the result of an AJAX discovery request while it is waiting
+ /// to be picked up by ASP.NET on the way down to the user agent.
/// </summary>
private string discoveryResult;
@@ -61,10 +102,26 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
protected OpenIdRelyingPartyAjaxControlBase() {
// The AJAX login style always uses popups (or invisible iframes).
- this.Popup = PopupBehavior.Always;
+ base.Popup = PopupBehavior.Always;
+
+ // The expected use case for the AJAX login box is for comments... not logging in.
+ this.LogOnMode = LogOnSiteNotification.None;
}
/// <summary>
+ /// Fired when a Provider sends back a positive assertion to this control,
+ /// but the authentication has not yet been verified.
+ /// </summary>
+ /// <remarks>
+ /// <b>No security critical decisions should be made within event handlers
+ /// for this event</b> as the authenticity of the assertion has not been
+ /// verified yet. All security related code should go in the event handler
+ /// for the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event.
+ /// </remarks>
+ [Description("Fired when a Provider sends back a positive assertion to this control, but the authentication has not yet been verified.")]
+ public event EventHandler<OpenIdEventArgs> UnconfirmedPositiveAssertion;
+
+ /// <summary>
/// Gets or sets a value indicating when to use a popup window to complete the login experience.
/// </summary>
/// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
@@ -74,6 +131,90 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set { ErrorUtilities.VerifySupported(value == base.Popup, OpenIdStrings.PropertyValueNotSupported); }
}
+ /// <summary>
+ /// Gets the completed authentication response.
+ /// </summary>
+ public IAuthenticationResponse AuthenticationResponse {
+ get {
+ if (this.authenticationResponse == null) {
+ // We will either validate a new response and return a live AuthenticationResponse
+ // or we will try to deserialize a previous IAuthenticationResponse (snapshot)
+ // from viewstate and return that.
+ IAuthenticationResponse viewstateResponse = this.ViewState[AuthenticationResponseViewStateKey] as IAuthenticationResponse;
+ string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
+ string formAuthData = this.Page.Request.Form[this.OpenIdAuthDataFormKey];
+
+ // First see if there is fresh auth data to be processed into a response.
+ if (!string.IsNullOrEmpty(formAuthData) && !string.Equals(viewstateAuthData, formAuthData, StringComparison.Ordinal)) {
+ this.ViewState[AuthDataViewStateKey] = formAuthData;
+
+ Uri authUri = new Uri(formAuthData);
+ HttpRequestInfo clientResponseInfo = new HttpRequestInfo {
+ UrlBeforeRewriting = authUri,
+ };
+
+ this.authenticationResponse = this.RelyingParty.GetResponse(clientResponseInfo);
+ this.AuthenticationProcessedAlready = false;
+
+ // Save out the authentication response to viewstate so we can find it on
+ // a subsequent postback.
+ this.ViewState[AuthenticationResponseViewStateKey] = new PositiveAuthenticationResponseSnapshot(this.authenticationResponse);
+ } else {
+ this.authenticationResponse = viewstateResponse;
+ }
+ }
+
+ return this.authenticationResponse;
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of the open id auth data form key (for the value as stored at the user agent as a FORM field).
+ /// </summary>
+ /// <value>Usually a concatenation of the control's name and <c>"_openidAuthData"</c>.</value>
+ protected abstract string OpenIdAuthDataFormKey { get; }
+
+ /// <summary>
+ /// Gets the relying party to use when verification of incoming messages is NOT wanted.
+ /// </summary>
+ private static OpenIdRelyingParty RelyingPartyNonVerifying {
+ get {
+ if (relyingPartyNonVerifying == null) {
+ relyingPartyNonVerifying = OpenIdRelyingParty.CreateNonVerifying();
+ }
+ return relyingPartyNonVerifying;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether an authentication in the page's view state
+ /// has already been processed and appropriate events fired.
+ /// </summary>
+ private bool AuthenticationProcessedAlready {
+ get { return (bool)(ViewState[AuthenticationProcessedAlreadyViewStateKey] ?? false); }
+ set { ViewState[AuthenticationProcessedAlreadyViewStateKey] = value; }
+ }
+
+ /// <summary>
+ /// Allows an OpenID extension to read data out of an unverified positive authentication assertion
+ /// and send it down to the client browser so that Javascript running on the page can perform
+ /// some preprocessing on the extension data.
+ /// </summary>
+ /// <typeparam name="T">The extension <i>response</i> type that will read data from the assertion.</typeparam>
+ /// <param name="propertyName">The property name on the openid_identifier input box object that will be used to store the extension data. For example: sreg</param>
+ /// <remarks>
+ /// This method should be called from the <see cref="UnconfirmedPositiveAssertion"/> event handler.
+ /// </remarks>
+ [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "By design")]
+ public void RegisterClientScriptExtension<T>(string propertyName) where T : IClientScriptExtensionResponse {
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(propertyName));
+ ErrorUtilities.VerifyArgumentNamed(!this.clientScriptExtensions.ContainsValue(propertyName), "propertyName", OpenIdStrings.ClientScriptExtensionPropertyNameCollision, propertyName);
+ foreach (var ext in this.clientScriptExtensions.Keys) {
+ ErrorUtilities.VerifyArgument(ext != typeof(T), OpenIdStrings.ClientScriptExtensionTypeCollision, typeof(T).FullName);
+ }
+ this.clientScriptExtensions.Add(typeof(T), propertyName);
+ }
+
#region ICallbackEventHandler Members
/// <summary>
@@ -82,8 +223,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <returns>The result of the callback.</returns>
/// <value>A whitespace delimited list of URLs that can be used to initiate authentication.</value>
string ICallbackEventHandler.GetCallbackResult() {
- this.Page.Response.ContentType = "text/javascript";
- return this.discoveryResult;
+ return this.GetCallbackResult();
}
/// <summary>
@@ -91,12 +231,242 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// AJAX callback mechanisms.
/// </summary>
/// <param name="eventArgument">The identifier to perform discovery on.</param>
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) {
+ this.RaiseCallbackEvent(eventArgument);
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Returns the results of a callback event that targets a control.
+ /// </summary>
+ /// <returns>The result of the callback.</returns>
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
+ protected virtual string GetCallbackResult() {
+ this.Page.Response.ContentType = "text/javascript";
+ return this.discoveryResult;
+ }
+
+ /// <summary>
+ /// Processes a callback event that targets a control.
+ /// </summary>
+ /// <param name="eventArgument">A string that represents an event argument to pass to the event handler.</param>
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "We want to preserve the signature of the interface.")]
+ protected virtual void RaiseCallbackEvent(string eventArgument) {
string userSuppliedIdentifier = eventArgument;
ErrorUtilities.VerifyNonZeroLength(userSuppliedIdentifier, "userSuppliedIdentifier");
Logger.OpenId.InfoFormat("AJAX discovery on {0} requested.", userSuppliedIdentifier);
+ this.Identifier = userSuppliedIdentifier;
+ this.discoveryResult = this.SerializeDiscoveryAsJson(this.Identifier);
+ }
+
+ /// <summary>
+ /// Pre-discovers an identifier and makes the results available to the
+ /// user agent for javascript as soon as the page loads.
+ /// </summary>
+ /// <param name="identifier">The identifier.</param>
+ protected void PreloadDiscovery(Identifier identifier) {
+ this.PreloadDiscovery(new[] { identifier });
+ }
+
+ /// <summary>
+ /// Pre-discovers a given set of identifiers and makes the results available to the
+ /// user agent for javascript as soon as the page loads.
+ /// </summary>
+ /// <param name="identifiers">The identifiers to perform discovery on.</param>
+ protected void PreloadDiscovery(IEnumerable<Identifier> identifiers) {
+ string discoveryResults = this.SerializeDiscoveryAsJson(identifiers);
+ string script = "window.dnoa_internal.loadPreloadedDiscoveryResults(" + discoveryResults + ");";
+ this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), this.ClientID, script, true);
+ }
+
+ /// <summary>
+ /// Fires the <see cref="UnconfirmedPositiveAssertion"/> event.
+ /// </summary>
+ protected virtual void OnUnconfirmedPositiveAssertion() {
+ var unconfirmedPositiveAssertion = this.UnconfirmedPositiveAssertion;
+ if (unconfirmedPositiveAssertion != null) {
+ unconfirmedPositiveAssertion(this, null);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:Load"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
+ protected override void OnLoad(EventArgs e) {
+ base.OnLoad(e);
+
+ // Our parent control ignores all OpenID messages included in a postback,
+ // but our AJAX controls hide an old OpenID message in a postback payload,
+ // so we deserialize it and process it when appropriate.
+ if (this.Page.IsPostBack) {
+ if (this.AuthenticationResponse != null && !this.AuthenticationProcessedAlready) {
+ // Only process messages targeted at this control.
+ // Note that Stateless mode causes no receiver to be indicated.
+ string receiver = this.AuthenticationResponse.GetUntrustedCallbackArgument(ReturnToReceivingControlId);
+ if (receiver == null || receiver == this.ClientID) {
+ this.ProcessResponse(this.AuthenticationResponse);
+ this.AuthenticationProcessedAlready = true;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when the <see cref="Identifier"/> property is changed.
+ /// </summary>
+ protected override void OnIdentifierChanged() {
+ base.OnIdentifierChanged();
+
+ // Since the identifier changed, make sure we reset any cached authentication on the user agent.
+ this.ViewState.Remove(AuthDataViewStateKey);
+ }
+
+ /// <summary>
+ /// Creates the authentication requests for a given user-supplied Identifier.
+ /// </summary>
+ /// <param name="identifier">The identifier to create a request for.</param>
+ /// <returns>
+ /// A sequence of authentication requests, any one of which may be
+ /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
+ /// </returns>
+ protected override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
+ Contract.Requires<ArgumentNullException>(identifier != null);
+
+ // We delegate all our logic to another method, since invoking base. methods
+ // within an iterator method results in unverifiable code.
+ return this.CreateRequestsCore(base.CreateRequests(identifier));
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
+ /// </summary>
+ /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
+ protected override void OnPreRender(EventArgs e) {
+ base.OnPreRender(e);
+
+ this.SetWebAppPathOnUserAgent();
+ this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdRelyingPartyAjaxControlBase), EmbeddedAjaxJavascriptResource);
+
+ StringBuilder initScript = new StringBuilder();
+
+ initScript.AppendLine(CallbackJSFunctionAsync + " = " + this.GetJsCallbackConvenienceFunction(true));
+ initScript.AppendLine(CallbackJSFunction + " = " + this.GetJsCallbackConvenienceFunction(false));
+
+ // Positive assertions can last no longer than this library is willing to consider them valid,
+ // and when they come with OP private associations they last no longer than the OP is willing
+ // to consider them valid. We assume the OP will hold them valid for at least five minutes.
+ double assertionLifetimeInMilliseconds = Math.Min(TimeSpan.FromMinutes(5).TotalMilliseconds, Math.Min(DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime.TotalMilliseconds, DotNetOpenAuthSection.Configuration.Messaging.MaximumMessageLifetime.TotalMilliseconds));
+ initScript.AppendLine(MaxPositiveAssertionLifetimeJsName + " = " + assertionLifetimeInMilliseconds.ToString(CultureInfo.InvariantCulture) + ";");
+
+ this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyControlBase), "initializer", initScript.ToString(), true);
+ }
+
+ /// <summary>
+ /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
+ /// </summary>
+ /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
+ protected override void Render(HtmlTextWriter writer) {
+ base.Render(writer);
+
+ // Emit a hidden field to let the javascript on the user agent know if an
+ // authentication has already successfully taken place.
+ string viewstateAuthData = this.ViewState[AuthDataViewStateKey] as string;
+ if (!string.IsNullOrEmpty(viewstateAuthData)) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Name, this.OpenIdAuthDataFormKey);
+ writer.AddAttribute(HtmlTextWriterAttribute.Value, viewstateAuthData, true);
+ writer.AddAttribute(HtmlTextWriterAttribute.Type, "hidden");
+ writer.RenderBeginTag(HtmlTextWriterTag.Input);
+ writer.RenderEndTag();
+ }
+ }
+
+ /// <summary>
+ /// Notifies the user agent via an AJAX response of a completed authentication attempt.
+ /// </summary>
+ protected override void ScriptClosingPopupOrIFrame() {
+ Logger.OpenId.InfoFormat("AJAX (iframe) callback from OP: {0}", this.Page.Request.Url);
+ string extensionsJson = null;
+
+ var authResponse = RelyingPartyNonVerifying.GetResponse();
+ if (authResponse.Status == AuthenticationStatus.Authenticated) {
+ this.OnUnconfirmedPositiveAssertion(); // event handler will fill the clientScriptExtensions collection.
+ var extensionsDictionary = new Dictionary<string, string>();
+ foreach (var pair in this.clientScriptExtensions) {
+ IClientScriptExtensionResponse extension = (IClientScriptExtensionResponse)authResponse.GetExtension(pair.Key);
+ if (extension == null) {
+ continue;
+ }
+ var positiveResponse = (PositiveAuthenticationResponse)authResponse;
+ string js = extension.InitializeJavaScriptData(positiveResponse.Response);
+ if (!string.IsNullOrEmpty(js)) {
+ extensionsDictionary[pair.Value] = js;
+ }
+ }
+
+ extensionsJson = MessagingUtilities.CreateJsonObject(extensionsDictionary, true);
+ }
+
+ string payload = "document.URL";
+ if (Page.Request.HttpMethod == "POST") {
+ // Promote all form variables to the query string, but since it won't be passed
+ // to any server (this is a javascript window-to-window transfer) the length of
+ // it can be arbitrarily long, whereas it was POSTed here probably because it
+ // was too long for HTTP transit.
+ UriBuilder payloadUri = new UriBuilder(Page.Request.Url);
+ payloadUri.AppendQueryArgs(Page.Request.Form.ToDictionary());
+ payload = MessagingUtilities.GetSafeJavascriptValue(payloadUri.Uri.AbsoluteUri);
+ }
+
+ if (!string.IsNullOrEmpty(extensionsJson)) {
+ payload += ", " + extensionsJson;
+ }
+
+ this.CallbackUserAgentMethod("dnoa_internal.processAuthorizationResult(" + payload + ")");
+ }
+
+ /// <summary>
+ /// Serializes the discovery of multiple identifiers as a JSON object.
+ /// </summary>
+ /// <param name="identifiers">The identifiers to perform discovery on and create requests for.</param>
+ /// <returns>The serialized JSON object.</returns>
+ private string SerializeDiscoveryAsJson(IEnumerable<Identifier> identifiers) {
+ ErrorUtilities.VerifyArgumentNotNull(identifiers, "identifiers");
+
+ // We prepare a JSON object with this interface:
+ // Array discoveryWrappers;
+ // Where each element in the above array has this interface:
+ // class discoveryWrapper {
+ // string userSuppliedIdentifier;
+ // jsonResponse discoveryResult; // contains result of call to SerializeDiscoveryAsJson(Identifier)
+ // }
+ StringBuilder discoveryResultBuilder = new StringBuilder();
+ discoveryResultBuilder.Append("[");
+ foreach (var identifier in identifiers) { // TODO: parallelize discovery on these identifiers
+ discoveryResultBuilder.Append("{");
+ discoveryResultBuilder.AppendFormat("userSuppliedIdentifier: {0},", MessagingUtilities.GetSafeJavascriptValue(identifier));
+ discoveryResultBuilder.AppendFormat("discoveryResult: {0}", this.SerializeDiscoveryAsJson(identifier));
+ discoveryResultBuilder.Append("},");
+ }
+
+ discoveryResultBuilder.Length -= 1; // trim last comma
+ discoveryResultBuilder.Append("]");
+ return discoveryResultBuilder.ToString();
+ }
+
+ /// <summary>
+ /// Serializes the results of discovery and the created auth requests as a JSON object
+ /// for the user agent to initiate.
+ /// </summary>
+ /// <param name="identifier">The identifier to perform discovery on.</param>
+ /// <returns>The JSON string.</returns>
+ private string SerializeDiscoveryAsJson(Identifier identifier) {
+ ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
+
// We prepare a JSON object with this interface:
// class jsonResponse {
// string claimedIdentifier;
@@ -112,13 +482,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
StringBuilder discoveryResultBuilder = new StringBuilder();
discoveryResultBuilder.Append("{");
try {
- this.Identifier = userSuppliedIdentifier;
- IEnumerable<IAuthenticationRequest> requests = this.CreateRequests().CacheGeneratedResults();
+ IEnumerable<IAuthenticationRequest> requests = this.CreateRequests(identifier).CacheGeneratedResults();
if (requests.Any()) {
discoveryResultBuilder.AppendFormat("claimedIdentifier: {0},", MessagingUtilities.GetSafeJavascriptValue(requests.First().ClaimedIdentifier));
discoveryResultBuilder.Append("requests: [");
foreach (IAuthenticationRequest request in requests) {
- this.OnLoggingIn(request);
discoveryResultBuilder.Append("{");
discoveryResultBuilder.AppendFormat("endpoint: {0},", MessagingUtilities.GetSafeJavascriptValue(request.Provider.Uri.AbsoluteUri));
request.Mode = AuthenticationRequestMode.Immediate;
@@ -132,47 +500,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
discoveryResultBuilder.Length -= 1; // trim off last comma
discoveryResultBuilder.Append("]");
} else {
- discoveryResultBuilder.Append("requests: new Array(),");
+ discoveryResultBuilder.Append("requests: [],");
discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(OpenIdStrings.OpenIdEndpointNotFound));
}
} catch (ProtocolException ex) {
- discoveryResultBuilder.Append("requests: new Array(),");
+ discoveryResultBuilder.Append("requests: [],");
discoveryResultBuilder.AppendFormat("error: {0}", MessagingUtilities.GetSafeJavascriptValue(ex.Message));
}
- discoveryResultBuilder.Append("}");
- this.discoveryResult = discoveryResultBuilder.ToString();
- }
-
- #endregion
- /// <summary>
- /// Creates the authentication requests for a given user-supplied Identifier.
- /// </summary>
- /// <returns>A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.</returns>
- protected override IEnumerable<IAuthenticationRequest> CreateRequests() {
- ErrorUtilities.VerifyOperation(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
-
- // We delegate all our logic to another method, since invoking base. methods
- // within an iterator method results in unverifiable code.
- return this.CreateRequestsCore(base.CreateRequests());
- }
-
- /// <summary>
- /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
- /// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
-
- this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdRelyingPartyAjaxControlBase), EmbeddedAjaxJavascriptResource);
-
- StringBuilder initScript = new StringBuilder();
-
- initScript.AppendLine(CallbackJsFunctionAsync + " = " + this.GetJsCallbackConvenienceFunction(true));
- initScript.AppendLine(CallbackJsFunction + " = " + this.GetJsCallbackConvenienceFunction(false));
-
- this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyControlBase), "initializer", initScript.ToString(), true);
+ discoveryResultBuilder.Append("}");
+ return discoveryResultBuilder.ToString();
}
/// <summary>
@@ -184,30 +521,26 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
private IEnumerable<IAuthenticationRequest> CreateRequestsCore(IEnumerable<IAuthenticationRequest> requests) {
- Contract.Requires(requests != null);
+ Contract.Requires<ArgumentNullException>(requests != null);
// Configure each generated request.
int reqIndex = 0;
foreach (var req in requests) {
- req.AddCallbackArguments("index", (reqIndex++).ToString(CultureInfo.InvariantCulture));
-
- if (req.Provider.IsExtensionSupported<UIRequest>()) {
- // Provide a hint for the client javascript about whether the OP supports the UI extension.
- // This is so the window can be made the correct size for the extension.
- // If the OP doesn't advertise support for the extension, the javascript will use
- // a bigger popup window.
- req.AddCallbackArguments("dotnetopenid.popupUISupported", "1");
- }
+ req.SetUntrustedCallbackArgument("index", (reqIndex++).ToString(CultureInfo.InvariantCulture));
// If the ReturnToUrl was explicitly set, we'll need to reset our first parameter
- if (string.IsNullOrEmpty(HttpUtility.ParseQueryString(req.ReturnToUrl.Query)["dotnetopenid.userSuppliedIdentifier"])) {
- req.AddCallbackArguments("dotnetopenid.userSuppliedIdentifier", this.Identifier);
+ if (string.IsNullOrEmpty(HttpUtility.ParseQueryString(req.ReturnToUrl.Query)[AuthenticationRequest.UserSuppliedIdentifierParameterName])) {
+ Identifier userSuppliedIdentifier = ((AuthenticationRequest)req).Endpoint.UserSuppliedIdentifier;
+ req.SetUntrustedCallbackArgument(AuthenticationRequest.UserSuppliedIdentifierParameterName, userSuppliedIdentifier.OriginalString);
}
// Our javascript needs to let the user know which endpoint responded. So we force it here.
// This gives us the info even for 1.0 OPs and 2.0 setup_required responses.
- req.AddCallbackArguments("dotnetopenid.op_endpoint", req.Provider.Uri.AbsoluteUri);
- req.AddCallbackArguments("dotnetopenid.claimed_id", (string)req.ClaimedIdentifier ?? string.Empty);
+ req.SetUntrustedCallbackArgument(OPEndpointParameterName, req.Provider.Uri.AbsoluteUri);
+ req.SetUntrustedCallbackArgument(ClaimedIdParameterName, (string)req.ClaimedIdentifier ?? string.Empty);
+
+ // Inform ourselves in return_to that we're in a popup or iframe.
+ req.SetUntrustedCallbackArgument(UIPopupCallbackKey, "1");
// We append a # at the end so that if the OP happens to support it,
// the OpenID response "query string" is appended after the hash rather than before, resulting in the
@@ -247,73 +580,38 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Notifies the user agent via an AJAX response of a completed authentication attempt.
- /// </summary>
- private void ReportAuthenticationResult() {
- Logger.OpenId.InfoFormat("AJAX (iframe) callback from OP: {0}", this.Page.Request.Url);
- List<string> assignments = new List<string>();
-
- var authResponse = this.RelyingParty.GetResponse();
- if (authResponse.Status == AuthenticationStatus.Authenticated) {
- this.OnLoggedIn(authResponse);
- foreach (var pair in this.clientScriptExtensions) {
- IClientScriptExtensionResponse extension = (IClientScriptExtensionResponse)authResponse.GetExtension(pair.Key);
- if (extension == null) {
- continue;
- }
- var positiveResponse = (PositiveAuthenticationResponse)authResponse;
- string js = extension.InitializeJavaScriptData(positiveResponse.Response);
- if (string.IsNullOrEmpty(js)) {
- js = "null";
- }
- assignments.Add(pair.Value + " = " + js);
- }
- }
-
- this.CallbackUserAgentMethod("dnoi_internal.processAuthorizationResult(document.URL)", assignments.ToArray());
- }
-
- /// <summary>
/// Invokes a method on a parent frame/window's OpenIdAjaxTextBox,
/// and closes the calling popup window if applicable.
/// </summary>
/// <param name="methodCall">The method to call on the OpenIdAjaxTextBox, including
/// parameters. (i.e. "callback('arg1', 2)"). No escaping is done by this method.</param>
private void CallbackUserAgentMethod(string methodCall) {
- this.CallbackUserAgentMethod(methodCall, null);
- }
-
- /// <summary>
- /// Invokes a method on a parent frame/window's OpenIdAjaxTextBox,
- /// and closes the calling popup window if applicable.
- /// </summary>
- /// <param name="methodCall">The method to call on the OpenIdAjaxTextBox, including
- /// parameters. (i.e. "callback('arg1', 2)"). No escaping is done by this method.</param>
- /// <param name="preAssignments">An optional list of assignments to make to the input box object before placing the method call.</param>
- private void CallbackUserAgentMethod(string methodCall, string[] preAssignments) {
Logger.OpenId.InfoFormat("Sending Javascript callback: {0}", methodCall);
Page.Response.Write(@"<html><body><script language='javascript'>
var inPopup = !window.frameElement;
- var objSrc = inPopup ? window.opener.waiting_openidBox : window.frameElement.openidBox;
+ var objSrc = inPopup ? window.opener : window.frameElement;
");
- if (preAssignments != null) {
- foreach (string assignment in preAssignments) {
- Page.Response.Write(string.Format(CultureInfo.InvariantCulture, " objSrc.{0};\n", assignment));
- }
- }
// Something about calling objSrc.{0} can somehow cause FireFox to forget about the inPopup variable,
// so we have to actually put the test for it ABOVE the call to objSrc.{0} so that it already
// whether to call window.self.close() after the call.
string htmlFormat = @" if (inPopup) {{
- objSrc.{0};
- window.self.close();
-}} else {{
- objSrc.{0};
-}}
+ objSrc.{0};
+ window.self.close();
+ }} else {{
+ objSrc.{0};
+ }}
</script></body></html>";
Page.Response.Write(string.Format(CultureInfo.InvariantCulture, htmlFormat, methodCall));
Page.Response.End();
}
+
+ /// <summary>
+ /// Sets the window.aspnetapppath variable on the user agent so that cookies can be set with the proper path.
+ /// </summary>
+ private void SetWebAppPathOnUserAgent() {
+ string script = "window.aspnetapppath = " + MessagingUtilities.GetSafeJavascriptValue(this.Page.Request.ApplicationPath) + ";";
+ this.Page.ClientScript.RegisterClientScriptBlock(typeof(OpenIdRelyingPartyAjaxControlBase), "webapppath", script, true);
+ }
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
index 65b1b99..26d1252 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyAjaxControlBase.js
@@ -1,150 +1,719 @@
//-----------------------------------------------------------------------
-// <copyright file="OpenIdRelyingPartyControlBase.js" company="Andrew Arnott">
+// <copyright file="OpenIdRelyingPartyAjaxControlBase.js" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
+// This file may be used and redistributed under the terms of the
+// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
// </copyright>
//-----------------------------------------------------------------------
if (window.dnoa_internal === undefined) {
- window.dnoa_internal = new Object();
+ window.dnoa_internal = {};
+}
+
+/// <summary>Removes a given element from the array.</summary>
+/// <returns>True if the element was in the array, or false if it was not found.</returns>
+Array.prototype.remove = function(element) {
+ function elementToRemoveLast(a, b) {
+ if (a == element) { return 1; }
+ if (b == element) { return -1; }
+ return 0;
+ }
+ this.sort(elementToRemoveLast);
+ if (this[this.length - 1] == element) {
+ this.pop();
+ return true;
+ } else {
+ return false;
+ }
+};
+
+// Renders all the parameters in their string form, surrounded by parentheses.
+window.dnoa_internal.argsToString = function() {
+ result = "(";
+ for (var i = 0; i < arguments.length; i++) {
+ if (i > 0) { result += ', '; }
+ var arg = arguments[i];
+ if (typeof (arg) == 'string') { arg = '"' + arg + '"'; }
+ if (arg === null) { arg = '[null]'; }
+ result += arg.toString();
+ }
+ result += ')';
+ return result;
+};
+
+window.dnoa_internal.registerEvent = function(name) {
+ window.dnoa_internal[name + 'Listeners'] = [];
+ window.dnoa_internal['add' + name] = function(fn) { window.dnoa_internal[name + 'Listeners'].push(fn); };
+ window.dnoa_internal['remove' + name] = function(fn) { window.dnoa_internal[name + 'Listeners'].remove(fn); };
+ window.dnoa_internal['fire' + name] = function() {
+ var args = Array.prototype.slice.call(arguments);
+ trace('Firing event ' + name + window.dnoa_internal.argsToString.apply(null, args), 'blue');
+ var listeners = window.dnoa_internal[name + 'Listeners'];
+ for (var i = 0; i < listeners.length; i++) {
+ listeners[i].apply(null, args);
+ }
+ };
};
-window.dnoa_internal.discoveryResults = new Array(); // user supplied identifiers and discovery results
+window.dnoa_internal.registerEvent('DiscoveryStarted'); // (identifier) - fired when a discovery callback is ACTUALLY made to the RP
+window.dnoa_internal.registerEvent('DiscoverySuccess'); // (identifier, discoveryResult, { fresh: true|false }) - fired after a discovery callback is returned from the RP successfully or a cached result is retrieved
+window.dnoa_internal.registerEvent('DiscoveryFailed'); // (identifier, message) - fired after a discovery callback fails
+window.dnoa_internal.registerEvent('AuthStarted'); // (discoveryResult, serviceEndpoint, { background: true|false })
+window.dnoa_internal.registerEvent('AuthFailed'); // (discoveryResult, serviceEndpoint, { background: true|false }) - fired for each individual ServiceEndpoint, and once at last with serviceEndpoint==null if all failed
+window.dnoa_internal.registerEvent('AuthSuccess'); // (discoveryResult, serviceEndpoint, extensionResponses, { background: true|false, deserialized: true|false })
+window.dnoa_internal.registerEvent('AuthCleared'); // (discoveryResult, serviceEndpoint)
+
+window.dnoa_internal.discoveryResults = []; // user supplied identifiers and discovery results
+window.dnoa_internal.discoveryInProgress = []; // identifiers currently being discovered and their callbacks
+
+// The possible authentication results
+window.dnoa_internal.authSuccess = 'auth-success';
+window.dnoa_internal.authRefused = 'auth-refused';
+window.dnoa_internal.timedOut = 'timed-out';
+
+/// <summary>Instantiates a new FrameManager.</summary>
+/// <param name="maxFrames">The maximum number of concurrent 'jobs' (authentication attempts).</param>
+window.dnoa_internal.FrameManager = function(maxFrames) {
+ this.queuedWork = [];
+ this.frames = [];
+ this.maxFrames = maxFrames;
+
+ /// <summary>Called to queue up some work that will use an iframe as soon as it is available.</summary>
+ /// <param name="job">
+ /// A delegate that must return { url: /*to point the iframe to*/, onCanceled: /* callback */ }
+ /// Its first parameter is the iframe created to service the request.
+ /// It will only be called when the work actually begins.
+ /// </param>
+ /// <param name="p1">Arbitrary additional parameter to pass to the job.</param>
+ this.enqueueWork = function(job, p1) {
+ // Assign an iframe to this task immediately if there is one available.
+ if (this.frames.length < this.maxFrames) {
+ this.createIFrame(job, p1);
+ } else {
+ this.queuedWork.unshift({ job: job, p1: p1 });
+ }
+ };
+
+ /// <summary>Clears the job queue and immediately closes all iframes.</summary>
+ this.cancelAllWork = function() {
+ trace('Canceling all open and pending iframes.');
+ while (this.queuedWork.pop()) { }
+ this.closeFrames();
+ };
+
+ /// <summary>An event fired when a frame is closing.</summary>
+ this.onJobCompleted = function() {
+ // If there is a job in the queue, go ahead and start it up.
+ if (jobDesc = this.queuedWork.pop()) {
+ this.createIFrame(jobDesc.job, jobDesc.p1);
+ }
+ };
+
+ this.createIFrame = function(job, p1) {
+ var iframe = document.createElement("iframe");
+ if (!window.openid_visible_iframe) {
+ iframe.setAttribute("width", 0);
+ iframe.setAttribute("height", 0);
+ iframe.setAttribute("style", "display: none");
+ }
+ var jobDescription = job(iframe, p1);
+ iframe.setAttribute("src", jobDescription.url);
+ iframe.onCanceled = jobDescription.onCanceled;
+ iframe.dnoa_internal = window.dnoa_internal;
+ document.body.insertBefore(iframe, document.body.firstChild);
+ this.frames.push(iframe);
+ return iframe;
+ };
+
+ this.closeFrames = function() {
+ if (this.frames.length === 0) { return false; }
+ for (var i = 0; i < this.frames.length; i++) {
+ this.frames[i].src = "about:blank"; // doesn't have to exist. Just stop its processing.
+ if (this.frames[i].parentNode) { this.frames[i].parentNode.removeChild(this.frames[i]); }
+ }
+ while (this.frames.length > 0) {
+ var frame = this.frames.pop();
+ if (frame.onCanceled) { frame.onCanceled(); }
+ }
+ return true;
+ };
+
+ this.closeFrame = function(frame) {
+ frame.src = "about:blank"; // doesn't have to exist. Just stop its processing.
+ if (frame.parentNode) { frame.parentNode.removeChild(frame); }
+ var removed = this.frames.remove(frame);
+ this.onJobCompleted();
+ return removed;
+ };
+};
/// <summary>Instantiates an object that represents an OpenID Identifier.</summary>
-window.OpenId = function(identifier) {
+window.OpenIdIdentifier = function(identifier) {
+ if (!identifier || identifier.length === 0) {
+ throw 'Error: trying to create OpenIdIdentifier for null or empty string.';
+ }
+
/// <summary>Performs discovery on the identifier.</summary>
- /// <param name="onCompleted">A function(DiscoveryResult) callback to be called when discovery has completed.</param>
- this.discover = function(onCompleted) {
- /// <summary>Instantiates an object that stores discovery results of some identifier.</summary>
- function DiscoveryResult(identifier, discoveryInfo) {
- /// <summary>
- /// Instantiates an object that describes an OpenID service endpoint and facilitates
- /// initiating and tracking an authentication request.
- /// </summary>
- function ServiceEndpoint(requestInfo, userSuppliedIdentifier) {
- this.immediate = requestInfo.immediate ? new window.dnoa_internal.Uri(requestInfo.immediate) : null;
- this.setup = requestInfo.setup ? new window.dnoa_internal.Uri(requestInfo.setup) : null;
- this.endpoint = new window.dnoa_internal.Uri(requestInfo.endpoint);
- this.userSuppliedIdentifier = userSuppliedIdentifier;
- var self = this; // closure so that delegates have the right instance
- this.loginPopup = function(onSuccess, onFailure) {
- //self.abort(); // ensure no concurrent attempts
- window.dnoa_internal.processAuthorizationResult = function(childLocation) {
- window.dnoa_internal.processAuthorizationResult = null;
- trace('Received event from child window: ' + childLocation);
- var success = true; // TODO: discern between success and failure, and fire the correct event.
-
- if (success) {
- if (onSuccess) {
- onSuccess();
- }
- } else {
- if (onFailure) {
- onFailure();
- }
- }
- };
- var width = 800;
- var height = 600;
- if (self.setup.getQueryArgValue("openid.return_to").indexOf("dotnetopenid.popupUISupported") >= 0) {
- width = 450;
- height = 500;
+ /// <param name="onDiscoverSuccess">A function(DiscoveryResult) callback to be called when discovery has completed successfully.</param>
+ /// <param name="onDiscoverFailure">A function callback to be called when discovery has completed in failure.</param>
+ this.discover = function(onDiscoverSuccess, onDiscoverFailure) {
+ /// <summary>Receives the results of a successful discovery (even if it yielded 0 results).</summary>
+ function discoverSuccessCallback(discoveryResult, identifier) {
+ trace('Discovery completed for: ' + identifier);
+
+ // Deserialize the JSON object and store the result if it was a successful discovery.
+ discoveryResult = eval('(' + discoveryResult + ')');
+
+ // Add behavior for later use.
+ discoveryResult = new window.dnoa_internal.DiscoveryResult(identifier, discoveryResult);
+ window.dnoa_internal.discoveryResults[identifier] = discoveryResult;
+
+ window.dnoa_internal.fireDiscoverySuccess(identifier, discoveryResult, { fresh: true });
+
+ // Clear our "in discovery" state and fire callbacks
+ var callbacks = window.dnoa_internal.discoveryInProgress[identifier];
+ window.dnoa_internal.discoveryInProgress[identifier] = null;
+
+ if (callbacks) {
+ for (var i = 0; i < callbacks.onSuccess.length; i++) {
+ if (callbacks.onSuccess[i]) {
+ callbacks.onSuccess[i](discoveryResult);
+ }
+ }
+ }
+ }
+
+ /// <summary>Receives the discovery failure notification.</summary>
+ function discoverFailureCallback(message, userSuppliedIdentifier) {
+ trace('Discovery failed for: ' + identifier);
+
+ // Clear our "in discovery" state and fire callbacks
+ var callbacks = window.dnoa_internal.discoveryInProgress[identifier];
+ window.dnoa_internal.discoveryInProgress[identifier] = null;
+
+ if (callbacks) {
+ for (var i = 0; i < callbacks.onSuccess.length; i++) {
+ if (callbacks.onFailure[i]) {
+ callbacks.onFailure[i](message);
}
+ }
+ }
+
+ window.dnoa_internal.fireDiscoveryFailed(identifier, message);
+ }
+
+ if (window.dnoa_internal.discoveryResults[identifier]) {
+ trace("We've already discovered " + identifier + " so we're using the cached version.");
+
+ // In this special case, we never fire the DiscoveryStarted event.
+ window.dnoa_internal.fireDiscoverySuccess(identifier, window.dnoa_internal.discoveryResults[identifier], { fresh: false });
+
+ if (onDiscoverSuccess) {
+ onDiscoverSuccess(window.dnoa_internal.discoveryResults[identifier]);
+ }
+
+ return;
+ }
+
+ window.dnoa_internal.fireDiscoveryStarted(identifier);
+
+ if (!window.dnoa_internal.discoveryInProgress[identifier]) {
+ trace('starting discovery on ' + identifier);
+ window.dnoa_internal.discoveryInProgress[identifier] = {
+ onSuccess: [onDiscoverSuccess],
+ onFailure: [onDiscoverFailure]
+ };
+ window.dnoa_internal.callbackAsync(identifier, discoverSuccessCallback, discoverFailureCallback);
+ } else {
+ trace('Discovery on ' + identifier + ' already started. Registering an additional callback.');
+ window.dnoa_internal.discoveryInProgress[identifier].onSuccess.push(onDiscoverSuccess);
+ window.dnoa_internal.discoveryInProgress[identifier].onFailure.push(onDiscoverFailure);
+ }
+ };
+
+ /// <summary>Performs discovery and immediately begins checkid_setup to authenticate the user using a given identifier.</summary>
+ this.login = function(onSuccess, onLoginFailure) {
+ this.discover(function(discoveryResult) {
+ if (discoveryResult) {
+ trace('Discovery succeeded and found ' + discoveryResult.length + ' OpenID service endpoints.');
+ if (discoveryResult.length > 0) {
+ discoveryResult[0].loginPopup(onSuccess, onLoginFailure);
+ } else {
+ trace("This doesn't look like an OpenID Identifier. Aborting login.");
+ if (onLoginFailure) {
+ onLoginFailure();
+ }
+ }
+ }
+ });
+ };
+
+ /// <summary>Performs discovery and immediately begins checkid_immediate on all discovered endpoints.</summary>
+ this.loginBackground = function(frameManager, onLoginSuccess, onLoginFailure, timeout, onLoginLastFailure) {
+ this.discover(function(discoveryResult) {
+ if (discoveryResult) {
+ trace('Discovery succeeded and found ' + discoveryResult.length + ' OpenID service endpoints.');
+ if (discoveryResult.length > 0) {
+ discoveryResult.loginBackground(frameManager, onLoginSuccess, onLoginFailure, onLoginLastFailure || onLoginFailure, timeout);
+ } else {
+ trace("This doesn't look like an OpenID Identifier. Aborting login.");
+ if (onLoginFailure) {
+ onLoginFailure();
+ }
+ }
+ }
+ });
+ };
+
+ this.toString = function() {
+ return identifier;
+ };
+};
+
+/// <summary>Invoked by RP web server when an authentication has completed.</summary>
+/// <remarks>The duty of this method is to distribute the notification to the appropriate tracking object.</remarks>
+window.dnoa_internal.processAuthorizationResult = function(resultUrl, extensionResponses) {
+ //trace('processAuthorizationResult ' + resultUrl);
+ var resultUri = new window.dnoa_internal.Uri(resultUrl);
+ trace('processing auth result with extensionResponses: ' + extensionResponses);
+ if (extensionResponses) {
+ extensionResponses = eval(extensionResponses);
+ }
+
+ // Find the tracking object responsible for this request.
+ var userSuppliedIdentifier = resultUri.getQueryArgValue('dnoa.userSuppliedIdentifier');
+ if (!userSuppliedIdentifier) {
+ throw 'processAuthorizationResult called but no userSuppliedIdentifier parameter was found. Exiting function.';
+ }
+ var discoveryResult = window.dnoa_internal.discoveryResults[userSuppliedIdentifier];
+ if (!discoveryResult) {
+ throw 'processAuthorizationResult called but no discovery result matching user supplied identifier ' + userSuppliedIdentifier + ' was found. Exiting function.';
+ }
- var left = (screen.width - width) / 2;
- var top = (screen.height - height) / 2;
- self.popup = window.open(self.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
+ var opEndpoint = resultUri.getQueryArgValue("openid.op_endpoint") ? resultUri.getQueryArgValue("openid.op_endpoint") : resultUri.getQueryArgValue("dnoa.op_endpoint");
+ var respondingEndpoint = discoveryResult.findByEndpoint(opEndpoint);
+ trace('Auth result for ' + respondingEndpoint.host + ' received.'); //: ' + resultUrl);
+
+ if (window.dnoa_internal.isAuthSuccessful(resultUri)) {
+ discoveryResult.successAuthData = resultUrl;
+ respondingEndpoint.onAuthSuccess(resultUri, extensionResponses);
+
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(resultUri);
+ if (parsedPositiveAssertion.claimedIdentifier && parsedPositiveAssertion.claimedIdentifier != discoveryResult.claimedIdentifier) {
+ discoveryResult.claimedIdentifier = parsedPositiveAssertion.claimedIdentifier;
+ trace('Authenticated as ' + parsedPositiveAssertion.claimedIdentifier);
+ }
+ } else {
+ respondingEndpoint.onAuthFailed();
+ }
+};
+
+window.dnoa_internal.isAuthSuccessful = function(resultUri) {
+ if (window.dnoa_internal.isOpenID2Response(resultUri)) {
+ return resultUri.getQueryArgValue("openid.mode") == "id_res";
+ } else {
+ return resultUri.getQueryArgValue("openid.mode") == "id_res" && !resultUri.containsQueryArg("openid.user_setup_url");
+ }
+};
- // If the OP supports the UI extension it MAY close its own window
- // for a negative assertion. We must be able to recover from that scenario.
- var localSelf = self;
- self.popupCloseChecker = window.setInterval(function() {
- if (localSelf.popup && localSelf.popup.closed) {
+window.dnoa_internal.isOpenID2Response = function(resultUri) {
+ return resultUri.containsQueryArg("openid.ns");
+};
+
+/// <summary>Instantiates an object that stores discovery results of some identifier.</summary>
+window.dnoa_internal.DiscoveryResult = function(identifier, discoveryInfo) {
+ var thisDiscoveryResult = this;
+
+ /// <summary>
+ /// Instantiates an object that describes an OpenID service endpoint and facilitates
+ /// initiating and tracking an authentication request.
+ /// </summary>
+ function ServiceEndpoint(requestInfo, userSuppliedIdentifier) {
+ this.immediate = requestInfo.immediate ? new window.dnoa_internal.Uri(requestInfo.immediate) : null;
+ this.setup = requestInfo.setup ? new window.dnoa_internal.Uri(requestInfo.setup) : null;
+ this.endpoint = new window.dnoa_internal.Uri(requestInfo.endpoint);
+ this.host = this.endpoint.getHost();
+ this.userSuppliedIdentifier = userSuppliedIdentifier;
+ var thisServiceEndpoint = this; // closure so that delegates have the right instance
+ this.loginPopup = function(onAuthSuccess, onAuthFailed) {
+ thisServiceEndpoint.abort(); // ensure no concurrent attempts
+ window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, thisServiceEndpoint, { background: false });
+ thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
+ thisDiscoveryResult.onAuthFailed = onAuthFailed;
+ var chromeHeight = 55; // estimated height of browser title bar and location bar
+ var bottomMargin = 45; // estimated bottom space on screen likely to include a task bar
+ var width = 1000;
+ var height = 600;
+ if (thisServiceEndpoint.setup.getQueryArgValue("openid.return_to").indexOf("dnoa.popupUISupported") >= 0) {
+ trace('This OP supports the UI extension. Using smaller window size.');
+ width = 500; // spec calls for 450px, but Yahoo needs 500px
+ height = 500;
+ } else {
+ trace("This OP doesn't appear to support the UI extension. Using larger window size.");
+ }
+
+ var left = (screen.width - width) / 2;
+ var top = (screen.height - bottomMargin - height - chromeHeight) / 2;
+ thisServiceEndpoint.popup = window.open(thisServiceEndpoint.setup, 'opLogin', 'status=0,toolbar=0,location=1,resizable=1,scrollbars=1,left=' + left + ',top=' + top + ',width=' + width + ',height=' + height);
+
+ // If the OP supports the UI extension it MAY close its own window
+ // for a negative assertion. We must be able to recover from that scenario.
+ var thisServiceEndpointLocal = thisServiceEndpoint;
+ thisServiceEndpoint.popupCloseChecker = window.setInterval(function() {
+ if (thisServiceEndpointLocal.popup) {
+ try {
+ if (thisServiceEndpointLocal.popup.closed) {
// The window closed, either because the user closed it, canceled at the OP,
// or approved at the OP and the popup window closed itself due to our script.
// If we were graying out the entire page while the child window was up,
// we would probably revert that here.
- window.clearInterval(localSelf.popupCloseChecker);
- localSelf.popup = null;
+ window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
+ thisServiceEndpointLocal.popup = null;
// The popup may have managed to inform us of the result already,
// so check whether the callback method was cleared already, which
// would indicate we've already processed this.
if (window.dnoa_internal.processAuthorizationResult) {
trace('User or OP canceled by closing the window.');
- if (onFailure) {
- onFailure();
+ window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: false });
+ if (thisDiscoveryResult.onAuthFailed) {
+ thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
}
- window.dnoa_internal.processAuthorizationResult = null;
}
}
- }, 250);
- };
+ } catch (e) {
+ // This usually happens because the popup is currently displaying the OP's
+ // page from another domain, which makes the popup temporarily off limits to us.
+ // Just skip this interval and wait for the next callback.
+ }
+ } else {
+ // if there's no popup, there's no reason to keep this timer up.
+ window.clearInterval(thisServiceEndpointLocal.popupCloseChecker);
+ }
+ }, 250);
+ };
+
+ this.loginBackgroundJob = function(iframe, timeout) {
+ thisServiceEndpoint.abort(); // ensure no concurrent attempts
+ if (timeout) {
+ thisServiceEndpoint.timeout = setTimeout(function() { thisServiceEndpoint.onAuthenticationTimedOut(); }, timeout);
+ }
+ window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, thisServiceEndpoint, { background: true });
+ trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now OPENING (timeout ' + timeout + ').');
+ //trace('initiating auth attempt with: ' + thisServiceEndpoint.immediate);
+ thisServiceEndpoint.iframe = iframe;
+ return {
+ url: thisServiceEndpoint.immediate.toString(),
+ onCanceled: function() {
+ thisServiceEndpoint.abort();
+ window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: true });
+ }
};
+ };
+
+ this.busy = function() {
+ return thisServiceEndpoint.iframe || thisServiceEndpoint.popup;
+ };
- this.userSuppliedIdentifier = identifier;
- this.claimedIdentifier = discoveryInfo.claimedIdentifier; // The claimed identifier may be null if the user provided an OP Identifier.
- trace('Discovered claimed identifier: ' + (this.claimedIdentifier ? this.claimedIdentifier : "(directed identity)"));
+ this.completeAttempt = function(successful) {
+ if (!thisServiceEndpoint.busy()) { return false; }
+ window.clearInterval(thisServiceEndpoint.timeout);
+ var background = thisServiceEndpoint.iframe !== null;
+ if (thisServiceEndpoint.iframe) {
+ trace('iframe hosting ' + thisServiceEndpoint.endpoint + ' now CLOSING.');
+ thisDiscoveryResult.frameManager.closeFrame(thisServiceEndpoint.iframe);
+ thisServiceEndpoint.iframe = null;
+ }
+ if (thisServiceEndpoint.popup) {
+ thisServiceEndpoint.popup.close();
+ thisServiceEndpoint.popup = null;
+ }
+ if (thisServiceEndpoint.timeout) {
+ window.clearTimeout(thisServiceEndpoint.timeout);
+ thisServiceEndpoint.timeout = null;
+ }
- if (discoveryInfo) {
- this.length = discoveryInfo.requests.length;
- for (var i = 0; i < discoveryInfo.requests.length; i++) {
- this[i] = new ServiceEndpoint(discoveryInfo.requests[i], identifier);
+ if (!successful && !thisDiscoveryResult.busy() && !thisDiscoveryResult.findSuccessfulRequest()) {
+ // fire the failed event with NO service endpoint indicating the entire auth attempt has failed.
+ window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, null, { background: background });
+ if (thisDiscoveryResult.onLastAttemptFailed) {
+ thisDiscoveryResult.onLastAttemptFailed(thisDiscoveryResult);
}
- } else {
- this.length = 0;
}
- };
- /// <summary>Receives the results of a successful discovery (even if it yielded 0 results).</summary>
- function successCallback(discoveryResult, identifier) {
- trace('Discovery completed for: ' + identifier);
+ return true;
+ };
- // Deserialize the JSON object and store the result if it was a successful discovery.
- discoveryResult = eval('(' + discoveryResult + ')');
+ this.onAuthenticationTimedOut = function() {
+ var background = thisServiceEndpoint.iframe !== null;
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " timed out");
+ thisServiceEndpoint.result = window.dnoa_internal.timedOut;
+ }
+ window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: background });
+ };
- // Add behavior for later use.
- discoveryResult = new DiscoveryResult(identifier, discoveryResult);
- window.dnoa_internal.discoveryResults[identifier] = discoveryResult;
+ this.onAuthSuccess = function(authUri, extensionResponses) {
+ var background = thisServiceEndpoint.iframe !== null;
+ if (thisServiceEndpoint.completeAttempt(true)) {
+ trace(thisServiceEndpoint.host + " authenticated!");
+ thisServiceEndpoint.result = window.dnoa_internal.authSuccess;
+ thisServiceEndpoint.successReceived = new Date();
+ thisServiceEndpoint.claimedIdentifier = authUri.getQueryArgValue('openid.claimed_id');
+ thisServiceEndpoint.response = authUri;
+ thisServiceEndpoint.extensionResponses = extensionResponses;
+ thisDiscoveryResult.abortAll();
+ if (thisDiscoveryResult.onAuthSuccess) {
+ thisDiscoveryResult.onAuthSuccess(thisDiscoveryResult, thisServiceEndpoint, extensionResponses);
+ }
+ window.dnoa_internal.fireAuthSuccess(thisDiscoveryResult, thisServiceEndpoint, extensionResponses, { background: background });
+ }
+ };
- if (onCompleted) {
- onCompleted(discoveryResult);
+ this.onAuthFailed = function() {
+ var background = thisServiceEndpoint.iframe !== null;
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " failed authentication");
+ thisServiceEndpoint.result = window.dnoa_internal.authRefused;
+ window.dnoa_internal.fireAuthFailed(thisDiscoveryResult, thisServiceEndpoint, { background: background });
+ if (thisDiscoveryResult.onAuthFailed) {
+ thisDiscoveryResult.onAuthFailed(thisDiscoveryResult, thisServiceEndpoint);
+ }
}
};
- /// <summary>Receives the discovery failure notification.</summary>
- failureCallback = function(message, userSuppliedIdentifier) {
- trace('Discovery failed for: ' + identifier);
+ this.abort = function() {
+ if (thisServiceEndpoint.completeAttempt()) {
+ trace(thisServiceEndpoint.host + " aborted");
+ // leave the result as whatever it was before.
+ }
+ };
- if (onCompleted) {
- onCompleted();
+ this.clear = function() {
+ thisServiceEndpoint.result = null;
+ thisServiceEndpoint.extensionResponses = null;
+ thisServiceEndpoint.successReceived = null;
+ thisServiceEndpoint.claimedIdentifier = null;
+ thisServiceEndpoint.response = null;
+ if (this.onCleared) {
+ this.onCleared(thisServiceEndpoint, thisDiscoveryResult);
}
+ if (thisDiscoveryResult.onCleared) {
+ thisDiscoveryResult.onCleared(thisDiscoveryResult, thisServiceEndpoint);
+ }
+ window.dnoa_internal.fireAuthCleared(thisDiscoveryResult, thisServiceEndpoint);
};
- if (window.dnoa_internal.discoveryResults[identifier]) {
- trace("We've already discovered " + identifier + " so we're skipping it this time.");
- onCompleted(window.dnoa_internal.discoveryResults[identifier]);
+ this.toString = function() {
+ return "[ServiceEndpoint: " + thisServiceEndpoint.host + "]";
+ };
+ }
+
+ this.cloneWithOneServiceEndpoint = function(serviceEndpoint) {
+ var clone = window.dnoa_internal.clone(this);
+ clone.userSuppliedIdentifier = serviceEndpoint.claimedIdentifier;
+
+ // Erase all SEPs except the given one, and put it into first position.
+ clone.length = 1;
+ for (var i = 0; i < this.length; i++) {
+ if (clone[i].endpoint.toString() == serviceEndpoint.endpoint.toString()) {
+ var tmp = clone[i];
+ clone[i] = null;
+ clone[0] = tmp;
+ } else {
+ clone[i] = null;
+ }
}
- trace('starting discovery on ' + identifier);
- window.dnoa_internal.callbackAsync(identifier, successCallback, failureCallback);
+ return clone;
};
- /// <summary>Performs discovery and immediately begins checkid_setup to authenticate the user using a given identifier.</summary>
- this.login = function(onSuccess, onFailure) {
- this.discover(function(discoveryResult) {
- if (discoveryResult) {
- trace('Discovery succeeded and found ' + discoveryResult.length + ' OpenID service endpoints.');
- if (discoveryResult.length > 0) {
- discoveryResult[0].loginPopup(onSuccess, onFailure);
- } else {
- trace("This doesn't look like an OpenID Identifier. Aborting login.");
- if (onFailure) {
- onFailure();
- }
+ this.userSuppliedIdentifier = identifier;
+ this.error = discoveryInfo.error;
+
+ if (discoveryInfo) {
+ this.claimedIdentifier = discoveryInfo.claimedIdentifier; // The claimed identifier may be null if the user provided an OP Identifier.
+ this.length = discoveryInfo.requests.length;
+ for (var i = 0; i < discoveryInfo.requests.length; i++) {
+ this[i] = new ServiceEndpoint(discoveryInfo.requests[i], identifier);
+ }
+ } else {
+ this.length = 0;
+ }
+
+ if (this.length === 0) {
+ trace('Discovery completed, but yielded no service endpoints.');
+ } else {
+ trace('Discovered claimed identifier: ' + (this.claimedIdentifier ? this.claimedIdentifier : "(directed identity)"));
+ }
+
+ // Add extra tracking bits and behaviors.
+ this.findByEndpoint = function(opEndpoint) {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].endpoint == opEndpoint) {
+ return thisDiscoveryResult[i];
+ }
+ }
+ };
+
+ this.busy = function() {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].busy()) {
+ return true;
+ }
+ }
+ };
+
+ // Add extra tracking bits and behaviors.
+ this.findSuccessfulRequest = function() {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ if (thisDiscoveryResult[i].result === window.dnoa_internal.authSuccess) {
+ return thisDiscoveryResult[i];
+ }
+ }
+ };
+
+ this.abortAll = function() {
+ if (thisDiscoveryResult.frameManager) {
+ // Abort all other asynchronous authentication attempts that may be in progress
+ // for this particular claimed identifier.
+ thisDiscoveryResult.frameManager.cancelAllWork();
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ thisDiscoveryResult[i].abort();
+ }
+ } else {
+ trace('abortAll called without a frameManager being previously set.');
+ }
+ };
+
+ /// <summary>Initiates an asynchronous checkid_immediate login attempt against all possible service endpoints for an Identifier.</summary>
+ /// <param name="frameManager">The work queue for authentication iframes.</param>
+ /// <param name="onAuthSuccess">Fired when an endpoint responds affirmatively.</param>
+ /// <param name="onAuthFailed">Fired when an endpoint responds negatively.</param>
+ /// <param name="onLastAuthFailed">Fired when all authentication attempts have responded negatively or timed out.</param>
+ /// <param name="timeout">Timeout for an individual service endpoint to respond before the iframe closes.</param>
+ this.loginBackground = function(frameManager, onAuthSuccess, onAuthFailed, onLastAuthFailed, timeout) {
+ if (!frameManager) {
+ throw "No frameManager specified.";
+ }
+ var priorSuccessRespondingEndpoint = thisDiscoveryResult.findSuccessfulRequest();
+ if (priorSuccessRespondingEndpoint) {
+ // In this particular case, we do not fire an AuthStarted event.
+ window.dnoa_internal.fireAuthSuccess(thisDiscoveryResult, priorSuccessRespondingEndpoint, priorSuccessRespondingEndpoint.extensionResponses, { background: true });
+ if (onAuthSuccess) {
+ onAuthSuccess(thisDiscoveryResult, priorSuccessRespondingEndpoint);
+ }
+ } else {
+ if (thisDiscoveryResult.busy()) {
+ trace('Warning: DiscoveryResult.loginBackground invoked while a login attempt is already in progress. Discarding second login request.', 'red');
+ return;
+ }
+ thisDiscoveryResult.frameManager = frameManager;
+ thisDiscoveryResult.onAuthSuccess = onAuthSuccess;
+ thisDiscoveryResult.onAuthFailed = onAuthFailed;
+ thisDiscoveryResult.onLastAttemptFailed = onLastAuthFailed;
+ // Notify listeners that general authentication is beginning. Individual ServiceEndpoints
+ // will fire their own events as each of them begin their iframe 'job'.
+ window.dnoa_internal.fireAuthStarted(thisDiscoveryResult, null, { background: true });
+ if (thisDiscoveryResult.length > 0) {
+ for (var i = 0; i < thisDiscoveryResult.length; i++) {
+ thisDiscoveryResult.frameManager.enqueueWork(thisDiscoveryResult[i].loginBackgroundJob, timeout);
}
}
- });
+ }
+ };
+
+ this.toString = function() {
+ return "[DiscoveryResult: " + thisDiscoveryResult.userSuppliedIdentifier + "]";
};
};
+/// <summary>
+/// Called in a page had an AJAX control that had already obtained a positive assertion
+/// when a postback occurred, and now that control wants to restore its 'authenticated' state.
+/// </summary>
+/// <param name="positiveAssertion">The string form of the URI that contains the positive assertion.</param>
+window.dnoa_internal.deserializePreviousAuthentication = function(positiveAssertion) {
+ if (!positiveAssertion || positiveAssertion.length === 0) {
+ return;
+ }
+
+ trace('Revitalizing an old positive assertion from a prior postback.');
+
+ // The control ensures that we ALWAYS have an OpenID 2.0-style claimed_id attribute, even against
+ // 1.0 Providers via the return_to URL mechanism.
+ var parsedPositiveAssertion = new window.dnoa_internal.PositiveAssertion(positiveAssertion);
+
+ // We weren't given a full discovery history, but we can spoof this much from the
+ // authentication assertion.
+ trace('Deserialized claimed_id: ' + parsedPositiveAssertion.claimedIdentifier + ' and endpoint: ' + parsedPositiveAssertion.endpoint);
+ var discoveryInfo = {
+ claimedIdentifier: parsedPositiveAssertion.claimedIdentifier,
+ requests: [{ endpoint: parsedPositiveAssertion.endpoint}]
+ };
+
+ discoveryResult = new window.dnoa_internal.DiscoveryResult(parsedPositiveAssertion.userSuppliedIdentifier, discoveryInfo);
+ window.dnoa_internal.discoveryResults[parsedPositiveAssertion.userSuppliedIdentifier] = discoveryResult;
+ discoveryResult[0].result = window.dnoa_internal.authSuccess;
+ discoveryResult.successAuthData = positiveAssertion;
+
+ // restore old state from before postback
+ window.dnoa_internal.fireAuthSuccess(discoveryResult, discoveryResult[0], null, { background: true, deserialized: true });
+};
+
+window.dnoa_internal.PositiveAssertion = function(uri) {
+ uri = new window.dnoa_internal.Uri(uri.toString());
+ this.endpoint = new window.dnoa_internal.Uri(uri.getQueryArgValue("dnoa.op_endpoint"));
+ this.userSuppliedIdentifier = uri.getQueryArgValue('dnoa.userSuppliedIdentifier');
+ this.claimedIdentifier = uri.getQueryArgValue('openid.claimed_id');
+ if (!this.claimedIdentifier) {
+ this.claimedIdentifier = uri.getQueryArgValue('dnoa.claimed_id');
+ }
+ this.toString = function() { return uri.toString(); };
+};
+
+window.dnoa_internal.clone = function(obj) {
+ if (obj === null || typeof (obj) != 'object') {
+ return obj;
+ }
+
+ var temp = {};
+ for (var key in obj) {
+ temp[key] = window.dnoa_internal.clone(obj[key]);
+ }
+
+ return temp;
+};
+
+// Deserialized the preloaded discovery results
+window.dnoa_internal.loadPreloadedDiscoveryResults = function(preloadedDiscoveryResults) {
+ trace('found ' + preloadedDiscoveryResults.length + ' preloaded discovery results.');
+ for (var i = 0; i < preloadedDiscoveryResults.length; i++) {
+ var result = preloadedDiscoveryResults[i];
+ if (!window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier]) {
+ window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier] = new window.dnoa_internal.DiscoveryResult(result.userSuppliedIdentifier, result.discoveryResult);
+ trace('Preloaded discovery on: ' + window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier].userSuppliedIdentifier);
+ } else {
+ trace('Skipped preloaded discovery on: ' + window.dnoa_internal.discoveryResults[result.userSuppliedIdentifier].userSuppliedIdentifier + ' because we have a cached discovery result on it.');
+ }
+ }
+};
+
+window.dnoa_internal.clearExpiredPositiveAssertions = function() {
+ for (identifier in window.dnoa_internal.discoveryResults) {
+ var discoveryResult = window.dnoa_internal.discoveryResults[identifier];
+ if (typeof (discoveryResult) != 'object') { continue; } // skip functions
+ for (var i = 0; i < discoveryResult.length; i++) {
+ if (discoveryResult[i].result === window.dnoa_internal.authSuccess) {
+ if (new Date() - discoveryResult[i].successReceived > window.dnoa_internal.maxPositiveAssertionLifetime) {
+ // This positive assertion is too old, and may eventually be rejected by DNOA during verification.
+ // Let's clear out the positive assertion so it can be renewed.
+ trace('Clearing out expired positive assertion from ' + discoveryResult[i].host);
+ discoveryResult[i].clear();
+ }
+ }
+ }
+ }
+};
+
+window.setInterval(window.dnoa_internal.clearExpiredPositiveAssertions, 1000);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
index 0efabd2..5040f74 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs
@@ -27,15 +27,69 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using DotNetOpenAuth.OpenId.Extensions.UI;
/// <summary>
+ /// Methods of indicating to the rest of the web site that the user has logged in.
+ /// </summary>
+ [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "OnSite", Justification = "Two words intended.")]
+ public enum LogOnSiteNotification {
+ /// <summary>
+ /// The rest of the web site is unaware that the user just completed an OpenID login.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// After the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event is fired
+ /// the control automatically calls <see cref="System.Web.Security.FormsAuthentication.RedirectFromLoginPage(string, bool)"/>
+ /// with the <see cref="IAuthenticationResponse.ClaimedIdentifier"/> as the username
+ /// unless the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event handler sets
+ /// <see cref="OpenIdEventArgs.Cancel"/> property to true.
+ /// </summary>
+ FormsAuthentication,
+ }
+
+ /// <summary>
+ /// How an OpenID user session should be persisted across visits.
+ /// </summary>
+ public enum LogOnPersistence {
+ /// <summary>
+ /// The user should only be logged in as long as the browser window remains open.
+ /// Nothing is persisted to help the user on a return visit. Public kiosk mode.
+ /// </summary>
+ Session,
+
+ /// <summary>
+ /// The user should only be logged in as long as the browser window remains open.
+ /// The OpenID Identifier is persisted to help expedite re-authentication when
+ /// the user visits the next time.
+ /// </summary>
+ SessionAndPersistentIdentifier,
+
+ /// <summary>
+ /// The user is issued a persistent authentication ticket so that no login is
+ /// necessary on their return visit.
+ /// </summary>
+ PersistentAuthentication,
+ }
+
+ /// <summary>
/// A common base class for OpenID Relying Party controls.
/// </summary>
[DefaultProperty("Identifier"), ValidationProperty("Identifier")]
- public abstract class OpenIdRelyingPartyControlBase : Control {
+ public abstract class OpenIdRelyingPartyControlBase : Control, IPostBackEventHandler, IDisposable {
/// <summary>
/// The manifest resource name of the javascript file to include on the hosting page.
/// </summary>
internal const string EmbeddedJavascriptResource = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdRelyingPartyControlBase.js";
+ /// <summary>
+ /// The cookie used to persist the Identifier the user logged in with.
+ /// </summary>
+ internal const string PersistentIdentifierCookieName = OpenIdUtilities.CustomParameterPrefix + "OpenIDIdentifier";
+
+ /// <summary>
+ /// The callback parameter name to use to store which control initiated the auth request.
+ /// </summary>
+ internal const string ReturnToReceivingControlId = OpenIdUtilities.CustomParameterPrefix + "receiver";
+
#region Property category constants
/// <summary>
@@ -55,6 +109,31 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
+ #region Callback parameter names
+
+ /// <summary>
+ /// The callback parameter to use for recognizing when the callback is in a popup window or hidden iframe.
+ /// </summary>
+ protected const string UIPopupCallbackKey = OpenIdUtilities.CustomParameterPrefix + "uipopup";
+
+ /// <summary>
+ /// The parameter name to include in the formulated auth request so that javascript can know whether
+ /// the OP advertises support for the UI extension.
+ /// </summary>
+ protected const string PopupUISupportedJSHint = OpenIdUtilities.CustomParameterPrefix + "popupUISupported";
+
+ /// <summary>
+ /// The callback parameter for use with persisting the <see cref="UsePersistentCookie"/> property.
+ /// </summary>
+ private const string UsePersistentCookieCallbackKey = OpenIdUtilities.CustomParameterPrefix + "UsePersistentCookie";
+
+ /// <summary>
+ /// The callback parameter to use for recognizing when the callback is in the parent window.
+ /// </summary>
+ private const string UIPopupCallbackParentKey = OpenIdUtilities.CustomParameterPrefix + "uipopupParent";
+
+ #endregion
+
#region Property default values
/// <summary>
@@ -70,7 +149,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Default value of <see cref="UsePersistentCookie"/>.
/// </summary>
- private const bool UsePersistentCookieDefault = false;
+ private const LogOnPersistence UsePersistentCookieDefault = LogOnPersistence.Session;
+
+ /// <summary>
+ /// Default value of <see cref="LogOnMode"/>.
+ /// </summary>
+ private const LogOnSiteNotification LogOnModeDefault = LogOnSiteNotification.FormsAuthentication;
/// <summary>
/// The default value for the <see cref="RealmUrl"/> property.
@@ -102,6 +186,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string UsePersistentCookieViewStateKey = "UsePersistentCookie";
/// <summary>
+ /// The viewstate key to use for the <see cref="LogOnMode"/> property.
+ /// </summary>
+ private const string LogOnModeViewStateKey = "LogOnMode";
+
+ /// <summary>
/// The viewstate key to use for the <see cref="RealmUrl"/> property.
/// </summary>
private const string RealmUrlViewStateKey = "RealmUrl";
@@ -128,40 +217,21 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
- #region Callback parameter names
-
- /// <summary>
- /// The callback parameter for use with persisting the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieCallbackKey = OpenIdUtilities.CustomParameterPrefix + "UsePersistentCookie";
-
- /// <summary>
- /// The callback parameter to use for recognizing when the callback is in a popup window.
- /// </summary>
- private const string UIPopupCallbackKey = OpenIdUtilities.CustomParameterPrefix + "uipopup";
-
/// <summary>
- /// The callback parameter to use for recognizing when the callback is in the parent window.
+ /// The lifetime of the cookie used to persist the Identifier the user logged in with.
/// </summary>
- private const string UIPopupCallbackParentKey = OpenIdUtilities.CustomParameterPrefix + "uipopupParent";
+ private static readonly TimeSpan PersistentIdentifierTimeToLiveDefault = TimeSpan.FromDays(14);
/// <summary>
- /// The callback parameter name to use to store which control initiated the auth request.
+ /// Backing field for the <see cref="RelyingParty"/> property.
/// </summary>
- private const string ReturnToReceivingControlId = OpenIdUtilities.CustomParameterPrefix + "receiver";
+ private OpenIdRelyingParty relyingParty;
/// <summary>
- /// The parameter name to include in the formulated auth request so that javascript can know whether
- /// the OP advertises support for the UI extension.
+ /// A value indicating whether the <see cref="relyingParty"/> field contains
+ /// an instance that we own and should Dispose.
/// </summary>
- private const string PopupUISupportedJsHint = "dotnetopenid.popupUISupported";
-
- #endregion
-
- /// <summary>
- /// Backing field for the <see cref="RelyingParty"/> property.
- /// </summary>
- private OpenIdRelyingParty relyingParty;
+ private bool relyingPartyOwned;
/// <summary>
/// Initializes a new instance of the <see cref="OpenIdRelyingPartyControlBase"/> class.
@@ -172,11 +242,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#region Events
/// <summary>
- /// Fired after the user clicks the log in button, but before the authentication
- /// process begins. Offers a chance for the web application to disallow based on
- /// OpenID URL before redirecting the user to the OpenID Provider.
+ /// Fired when the user has typed in their identifier, discovery was successful
+ /// and a login attempt is about to begin.
/// </summary>
- [Description("Fired after the user clicks the log in button, but before the authentication process begins. Offers a chance for the web application to disallow based on OpenID URL before redirecting the user to the OpenID Provider."), Category(OpenIdCategory)]
+ [Description("Fired when the user has typed in their identifier, discovery was successful and a login attempt is about to begin."), Category(OpenIdCategory)]
public event EventHandler<OpenIdEventArgs> LoggingIn;
/// <summary>
@@ -197,6 +266,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Description("Fired when an authentication attempt is canceled at the OpenID Provider."), Category(OpenIdCategory)]
public event EventHandler<OpenIdEventArgs> Canceled;
+ /// <summary>
+ /// Occurs when the <see cref="Identifier"/> property is changed.
+ /// </summary>
+ protected event EventHandler IdentifierChanged;
+
#endregion
/// <summary>
@@ -215,12 +289,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
get {
if (this.relyingParty == null) {
this.relyingParty = this.CreateRelyingParty();
+ this.relyingPartyOwned = true;
}
return this.relyingParty;
}
set {
+ if (this.relyingPartyOwned && this.relyingParty != null) {
+ this.relyingParty.Dispose();
+ }
+
this.relyingParty = value;
+ this.relyingPartyOwned = false;
}
}
@@ -306,12 +386,22 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Bindable(true), DefaultValue(UsePersistentCookieDefault), Category(BehaviorCategory)]
[Description("Whether to send a persistent cookie upon successful " +
"login so the user does not have to log in upon returning to this site.")]
- public virtual bool UsePersistentCookie {
- get { return (bool)(this.ViewState[UsePersistentCookieViewStateKey] ?? UsePersistentCookieDefault); }
+ public virtual LogOnPersistence UsePersistentCookie {
+ get { return (LogOnPersistence)(this.ViewState[UsePersistentCookieViewStateKey] ?? UsePersistentCookieDefault); }
set { this.ViewState[UsePersistentCookieViewStateKey] = value; }
}
/// <summary>
+ /// Gets or sets the way a completed login is communicated to the rest of the web site.
+ /// </summary>
+ [Bindable(true), DefaultValue(LogOnModeDefault), Category(BehaviorCategory)]
+ [Description("The way a completed login is communicated to the rest of the web site.")]
+ public virtual LogOnSiteNotification LogOnMode {
+ get { return (LogOnSiteNotification)(this.ViewState[LogOnModeViewStateKey] ?? LogOnModeDefault); }
+ set { this.ViewState[LogOnModeViewStateKey] = value; }
+ }
+
+ /// <summary>
/// Gets or sets a value indicating when to use a popup window to complete the login experience.
/// </summary>
/// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
@@ -334,15 +424,20 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Gets or sets the URL to your privacy policy page that describes how
- /// claims will be used and/or shared.
+ /// Gets or sets the Identifier that will be used to initiate login.
/// </summary>
[Bindable(true), Category(OpenIdCategory)]
[Description("The OpenID Identifier that this button will use to initiate login.")]
[TypeConverter(typeof(IdentifierConverter))]
- public Identifier Identifier {
- get { return (Identifier)ViewState[IdentifierViewStateKey]; }
- set { ViewState[IdentifierViewStateKey] = value; }
+ public virtual Identifier Identifier {
+ get {
+ return (Identifier)ViewState[IdentifierViewStateKey];
+ }
+
+ set {
+ ViewState[IdentifierViewStateKey] = value;
+ this.OnIdentifierChanged();
+ }
}
/// <summary>
@@ -351,11 +446,30 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
internal AssociationPreference AssociationPreference { get; set; }
/// <summary>
+ /// Clears any cookie set by this control to help the user on a returning visit next time.
+ /// </summary>
+ public static void LogOff() {
+ HttpContext.Current.Response.SetCookie(CreateIdentifierPersistingCookie(null));
+ }
+
+ /// <summary>
/// Immediately redirects to the OpenID Provider to verify the Identifier
/// provided in the text box.
/// </summary>
public void LogOn() {
IAuthenticationRequest request = this.CreateRequests().FirstOrDefault();
+ ErrorUtilities.VerifyProtocol(request != null, OpenIdStrings.OpenIdEndpointNotFound);
+ this.LogOn(request);
+ }
+
+ /// <summary>
+ /// Immediately redirects to the OpenID Provider to verify the Identifier
+ /// provided in the text box.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ public void LogOn(IAuthenticationRequest request) {
+ Contract.Requires<ArgumentNullException>(request != null);
+
if (this.IsPopupAppropriate(request)) {
this.ScriptPopupWindow(request);
} else {
@@ -363,14 +477,71 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
}
+ #region IPostBackEventHandler Members
+
+ /// <summary>
+ /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
+ /// </summary>
+ /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
+ void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
+ this.RaisePostBackEvent(eventArgument);
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Enables a server control to perform final clean up before it is released from memory.
+ /// </summary>
+ [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Base class doesn't implement virtual Dispose(bool), so we must call its Dispose() method.")]
+ public sealed override void Dispose() {
+ this.Dispose(true);
+ base.Dispose();
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources
+ /// </summary>
+ /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing) {
+ if (disposing) {
+ if (this.relyingPartyOwned && this.relyingParty != null) {
+ this.relyingParty.Dispose();
+ this.relyingParty = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
+ /// </summary>
+ /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")]
+ protected virtual void RaisePostBackEvent(string eventArgument) {
+ }
+
+ /// <summary>
+ /// Creates the authentication requests for the value set in the <see cref="Identifier"/> property.
+ /// </summary>
+ /// <returns>
+ /// A sequence of authentication requests, any one of which may be
+ /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
+ /// </returns>
+ protected IEnumerable<IAuthenticationRequest> CreateRequests() {
+ Contract.Requires<InvalidOperationException>(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
+ return this.CreateRequests(this.Identifier);
+ }
+
/// <summary>
/// Creates the authentication requests for a given user-supplied Identifier.
/// </summary>
- /// <returns>A sequence of authentication requests, any one of which may be
- /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.</returns>
- protected virtual IEnumerable<IAuthenticationRequest> CreateRequests() {
- Contract.Requires(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
- ErrorUtilities.VerifyOperation(this.Identifier != null, OpenIdStrings.NoIdentifierSet);
+ /// <param name="identifier">The identifier to create a request for.</param>
+ /// <returns>
+ /// A sequence of authentication requests, any one of which may be
+ /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
+ /// </returns>
+ protected virtual IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
+ Contract.Requires<ArgumentNullException>(identifier != null);
IEnumerable<IAuthenticationRequest> requests;
// Approximate the returnTo (either based on the customize property or the page URL)
@@ -389,11 +560,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// might slip through our validator control if it is disabled.
Realm typedRealm = new Realm(realm);
if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- requests = this.RelyingParty.CreateRequests(this.Identifier, typedRealm);
+ requests = this.RelyingParty.CreateRequests(identifier, typedRealm);
} else {
// Since the user actually gave us a return_to value,
// the "approximation" is exactly what we want.
- requests = this.RelyingParty.CreateRequests(this.Identifier, typedRealm, returnToApproximation);
+ requests = this.RelyingParty.CreateRequests(identifier, typedRealm, returnToApproximation);
}
// Some OPs may be listed multiple times (one with HTTPS and the other with HTTP, for example).
@@ -404,31 +575,31 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// Configure each generated request.
foreach (var req in requests) {
if (this.IsPopupAppropriate(req)) {
- // Inform the OP that we'll be using a popup window.
- req.AddExtension(new UIRequest());
-
// Inform ourselves in return_to that we're in a popup.
- req.AddCallbackArguments(UIPopupCallbackKey, "1");
+ req.SetUntrustedCallbackArgument(UIPopupCallbackKey, "1");
if (req.Provider.IsExtensionSupported<UIRequest>()) {
+ // Inform the OP that we'll be using a popup window consistent with the UI extension.
+ req.AddExtension(new UIRequest());
+
// Provide a hint for the client javascript about whether the OP supports the UI extension.
// This is so the window can be made the correct size for the extension.
// If the OP doesn't advertise support for the extension, the javascript will use
// a bigger popup window.
- req.AddCallbackArguments(PopupUISupportedJsHint, "1");
+ req.SetUntrustedCallbackArgument(PopupUISupportedJSHint, "1");
}
}
// Add state that needs to survive across the redirect.
if (!this.Stateless) {
- req.AddCallbackArguments(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString(CultureInfo.InvariantCulture));
- req.AddCallbackArguments(ReturnToReceivingControlId, this.ClientID);
+ req.SetUntrustedCallbackArgument(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString());
+ req.SetUntrustedCallbackArgument(ReturnToReceivingControlId, this.ClientID);
}
((AuthenticationRequest)req).AssociationPreference = this.AssociationPreference;
- this.OnLoggingIn(req);
-
- yield return req;
+ if (this.OnLoggingIn(req)) {
+ yield return req;
+ }
}
}
@@ -444,12 +615,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
return;
}
+ if (this.Identifier == null) {
+ this.TryPresetIdentifierWithCookie();
+ }
+
// Take an unreliable sneek peek to see if we're in a popup and an OpenID
// assertion is coming in. We shouldn't process assertions in a popup window.
if (this.Page.Request.QueryString[UIPopupCallbackKey] == "1" && this.Page.Request.QueryString[UIPopupCallbackParentKey] == null) {
// We're in a popup window. We need to close it and pass the
// message back to the parent window for processing.
- this.ScriptClosingPopup();
+ this.ScriptClosingPopupOrIFrame();
return; // don't do any more processing on it now
}
@@ -458,33 +633,51 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
string receiver = this.Page.Request.QueryString[ReturnToReceivingControlId] ?? this.Page.Request.Form[ReturnToReceivingControlId];
if (receiver == null || receiver == this.ClientID) {
var response = this.RelyingParty.GetResponse();
- if (response != null) {
- string persistentString = response.GetUntrustedCallbackArgument(UsePersistentCookieCallbackKey);
- bool persistentBool;
- if (persistentString != null && bool.TryParse(persistentString, out persistentBool)) {
- this.UsePersistentCookie = persistentBool;
- }
+ this.ProcessResponse(response);
+ }
+ }
- switch (response.Status) {
- case AuthenticationStatus.Authenticated:
- this.OnLoggedIn(response);
- break;
- case AuthenticationStatus.Canceled:
- this.OnCanceled(response);
- break;
- case AuthenticationStatus.Failed:
- this.OnFailed(response);
- break;
- case AuthenticationStatus.SetupRequired:
- case AuthenticationStatus.ExtensionsOnly:
- default:
- // The NotApplicable (extension-only assertion) is NOT one that we support
- // in this control because that scenario is primarily interesting to RPs
- // that are asking a specific OP, and it is not user-initiated as this textbox
- // is designed for.
- throw new InvalidOperationException(MessagingStrings.UnexpectedMessageReceivedOfMany);
- }
- }
+ /// <summary>
+ /// Called when the <see cref="Identifier"/> property is changed.
+ /// </summary>
+ protected virtual void OnIdentifierChanged() {
+ var identifierChanged = this.IdentifierChanged;
+ if (identifierChanged != null) {
+ identifierChanged(this, EventArgs.Empty);
+ }
+ }
+
+ /// <summary>
+ /// Processes the response.
+ /// </summary>
+ /// <param name="response">The response.</param>
+ protected virtual void ProcessResponse(IAuthenticationResponse response) {
+ if (response == null) {
+ return;
+ }
+ string persistentString = response.GetUntrustedCallbackArgument(UsePersistentCookieCallbackKey);
+ if (persistentString != null) {
+ this.UsePersistentCookie = (LogOnPersistence)Enum.Parse(typeof(LogOnPersistence), persistentString);
+ }
+
+ switch (response.Status) {
+ case AuthenticationStatus.Authenticated:
+ this.OnLoggedIn(response);
+ break;
+ case AuthenticationStatus.Canceled:
+ this.OnCanceled(response);
+ break;
+ case AuthenticationStatus.Failed:
+ this.OnFailed(response);
+ break;
+ case AuthenticationStatus.SetupRequired:
+ case AuthenticationStatus.ExtensionsOnly:
+ default:
+ // The NotApplicable (extension-only assertion) is NOT one that we support
+ // in this control because that scenario is primarily interesting to RPs
+ // that are asking a specific OP, and it is not user-initiated as this textbox
+ // is designed for.
+ throw new InvalidOperationException(MessagingStrings.UnexpectedMessageReceivedOfMany);
}
}
@@ -503,10 +696,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnLoggedIn(IAuthenticationResponse response) {
- Contract.Requires(response != null);
- Contract.Requires(response.Status == AuthenticationStatus.Authenticated);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Authenticated, "Firing OnLoggedIn event without an authenticated response.");
+ Contract.Requires<ArgumentNullException>(response != null);
+ Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Authenticated);
var loggedIn = this.LoggedIn;
OpenIdEventArgs args = new OpenIdEventArgs(response);
@@ -515,7 +706,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
if (!args.Cancel) {
- FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie);
+ if (this.UsePersistentCookie == LogOnPersistence.SessionAndPersistentIdentifier) {
+ Page.Response.SetCookie(CreateIdentifierPersistingCookie(response));
+ }
+
+ switch (this.LogOnMode) {
+ case LogOnSiteNotification.FormsAuthentication:
+ FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie == LogOnPersistence.PersistentAuthentication);
+ break;
+ case LogOnSiteNotification.None:
+ default:
+ break;
+ }
}
}
@@ -527,8 +729,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Returns whether the login should proceed. False if some event handler canceled the request.
/// </returns>
protected virtual bool OnLoggingIn(IAuthenticationRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
EventHandler<OpenIdEventArgs> loggingIn = this.LoggingIn;
@@ -545,10 +746,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnCanceled(IAuthenticationResponse response) {
- Contract.Requires(response != null);
- Contract.Requires(response.Status == AuthenticationStatus.Canceled);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Canceled, "Firing Canceled event for the wrong response type.");
+ Contract.Requires<ArgumentNullException>(response != null);
+ Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Canceled);
var canceled = this.Canceled;
if (canceled != null) {
@@ -561,10 +760,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnFailed(IAuthenticationResponse response) {
- Contract.Requires(response != null);
- Contract.Requires(response.Status == AuthenticationStatus.Failed);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Failed, "Firing Failed event for the wrong response type.");
+ Contract.Requires<ArgumentNullException>(response != null);
+ Contract.Requires<ArgumentException>(response.Status == AuthenticationStatus.Failed);
var failed = this.Failed;
if (failed != null) {
@@ -577,8 +774,20 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <returns>The instantiated relying party.</returns>
protected virtual OpenIdRelyingParty CreateRelyingParty() {
+ return this.CreateRelyingParty(true);
+ }
+
+ /// <summary>
+ /// Creates the relying party instance used to generate authentication requests.
+ /// </summary>
+ /// <param name="verifySignature">
+ /// A value indicating whether message protections should be applied to the processed messages.
+ /// Use <c>false</c> to postpone verification to a later time without invalidating nonces.
+ /// </param>
+ /// <returns>The instantiated relying party.</returns>
+ protected virtual OpenIdRelyingParty CreateRelyingParty(bool verifySignature) {
IRelyingPartyApplicationStore store = this.Stateless ? null : DotNetOpenAuthSection.Configuration.OpenId.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore);
- var rp = new OpenIdRelyingParty(store);
+ var rp = verifySignature ? new OpenIdRelyingParty(store) : OpenIdRelyingParty.CreateNonVerifying();
// Only set RequireSsl to true, as we don't want to override
// a .config setting of true with false.
@@ -597,8 +806,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <c>true</c> if a popup should be used; <c>false</c> otherwise.
/// </returns>
protected virtual bool IsPopupAppropriate(IAuthenticationRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
switch (this.Popup) {
case PopupBehavior.Never:
@@ -620,10 +828,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="request">The outgoing authentication request.</param>
/// <param name="windowStatus">The text to try to display in the status bar on mouse hover.</param>
protected void RenderOpenIdMessageTransmissionAsAnchorAttributes(HtmlTextWriter writer, IAuthenticationRequest request, string windowStatus) {
- Contract.Requires(writer != null);
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(writer, "writer");
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(writer != null);
+ Contract.Requires<ArgumentNullException>(request != null);
// We render a standard HREF attribute for non-javascript browsers.
writer.AddAttribute(HtmlTextWriterAttribute.Href, request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel).AbsoluteUri);
@@ -639,13 +845,63 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
+ /// Wires the popup window to close itself and pass the authentication result to the parent window.
+ /// </summary>
+ protected virtual void ScriptClosingPopupOrIFrame() {
+ StringBuilder startupScript = new StringBuilder();
+ startupScript.AppendLine("window.opener.dnoa_internal.processAuthorizationResult(document.URL);");
+ startupScript.AppendLine("window.close();");
+
+ this.Page.ClientScript.RegisterStartupScript(typeof(OpenIdRelyingPartyControlBase), "loginPopupClose", startupScript.ToString(), true);
+
+ // TODO: alternately we should probably take over rendering this page here to avoid
+ // a lot of unnecessary work on the server and possible momentary display of the
+ // page in the popup window.
+ }
+
+ /// <summary>
+ /// Creates the identifier-persisting cookie, either for saving or deleting.
+ /// </summary>
+ /// <param name="response">The positive authentication response; or <c>null</c> to clear the cookie.</param>
+ /// <returns>An persistent cookie.</returns>
+ private static HttpCookie CreateIdentifierPersistingCookie(IAuthenticationResponse response) {
+ HttpCookie cookie = new HttpCookie(PersistentIdentifierCookieName);
+ bool clearingCookie = false;
+
+ // We'll try to store whatever it was the user originally typed in, but fallback
+ // to the final claimed_id.
+ if (response != null && response.Status == AuthenticationStatus.Authenticated) {
+ var positiveResponse = (PositiveAuthenticationResponse)response;
+
+ // We must escape the value because XRIs start with =, and any leading '=' gets dropped (by ASP.NET?)
+ cookie.Value = Uri.EscapeDataString(positiveResponse.Endpoint.UserSuppliedIdentifier ?? response.ClaimedIdentifier);
+ } else {
+ clearingCookie = true;
+ cookie.Value = string.Empty;
+ if (HttpContext.Current.Request.Browser["supportsEmptyStringInCookieValue"] == "false") {
+ cookie.Value = "NoCookie";
+ }
+ }
+
+ if (clearingCookie) {
+ // mark the cookie has having already expired to cause the user agent to delete
+ // the old persisted cookie.
+ cookie.Expires = DateTime.Now.Subtract(TimeSpan.FromDays(1));
+ } else {
+ // Make the cookie persistent by setting an expiration date
+ cookie.Expires = DateTime.Now + PersistentIdentifierTimeToLiveDefault;
+ }
+
+ return cookie;
+ }
+
+ /// <summary>
/// Gets the javascript to executee to redirect or POST an OpenID message to a remote party.
/// </summary>
/// <param name="request">The authentication request to send.</param>
/// <returns>The javascript that should execute.</returns>
private string CreateGetOrPostAHrefValue(IAuthenticationRequest request) {
- Contract.Requires(request != null);
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
Uri directUri = request.RedirectingResponse.GetDirectUriRequest(this.RelyingParty.Channel);
return "window.dnoa_internal.GetOrPost(" + MessagingUtilities.GetSafeJavascriptValue(directUri.AbsoluteUri) + ");";
@@ -656,37 +912,40 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="request">The request.</param>
private void ScriptPopupWindow(IAuthenticationRequest request) {
- Contract.Requires(request != null);
- Contract.Requires(this.RelyingParty != null);
+ Contract.Requires<ArgumentNullException>(request != null);
+ Contract.Requires<InvalidOperationException>(this.RelyingParty != null);
StringBuilder startupScript = new StringBuilder();
// Add a callback function that the popup window can call on this, the
// parent window, to pass back the authentication result.
- startupScript.AppendLine("window.dnoa_internal = new Object();");
+ startupScript.AppendLine("window.dnoa_internal = {};");
startupScript.AppendLine("window.dnoa_internal.processAuthorizationResult = function(uri) { window.location = uri; };");
startupScript.AppendLine("window.dnoa_internal.popupWindow = function() {");
- startupScript.AppendFormat(
- @"\tvar openidPopup = {0}",
- UIUtilities.GetWindowPopupScript(this.RelyingParty, request, "openidPopup"));
+ startupScript.AppendFormat(
+ @"\tvar openidPopup = {0}",
+ UIUtilities.GetWindowPopupScript(this.RelyingParty, request, "openidPopup"));
startupScript.AppendLine("};");
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "loginPopup", startupScript.ToString(), true);
}
/// <summary>
- /// Wires the popup window to close itself and pass the authentication result to the parent window.
+ /// Tries to preset the <see cref="Identifier"/> property based on a persistent
+ /// cookie on the browser.
/// </summary>
- private void ScriptClosingPopup() {
- StringBuilder startupScript = new StringBuilder();
- startupScript.AppendLine("window.opener.dnoa_internal.processAuthorizationResult(document.URL + '&" + UIPopupCallbackParentKey + "=1');");
- startupScript.AppendLine("window.close();");
-
- this.Page.ClientScript.RegisterStartupScript(typeof(OpenIdRelyingPartyControlBase), "loginPopupClose", startupScript.ToString(), true);
+ /// <returns>
+ /// A value indicating whether the <see cref="Identifier"/> property was
+ /// successfully preset to some non-empty value.
+ /// </returns>
+ private bool TryPresetIdentifierWithCookie() {
+ HttpCookie cookie = this.Page.Request.Cookies[PersistentIdentifierCookieName];
+ if (cookie != null) {
+ this.Identifier = Uri.UnescapeDataString(cookie.Value);
+ return true;
+ }
- // TODO: alternately we should probably take over rendering this page here to avoid
- // a lot of unnecessary work on the server and possible momentary display of the
- // page in the popup window.
+ return false;
}
/// <summary>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js
index 3a17b7b..58b283d 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.js
@@ -1,6 +1,8 @@
//-----------------------------------------------------------------------
// <copyright file="OpenIdRelyingPartyControlBase.js" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
+// This file may be used and redistributed under the terms of the
+// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
// </copyright>
//-----------------------------------------------------------------------
@@ -8,13 +10,14 @@
//window.openid_visible_iframe = true; // causes the hidden iframe to show up
//window.openid_trace = true; // causes lots of messages
-trace = function(msg) {
+trace = function(msg, color) {
if (window.openid_trace) {
if (!window.openid_tracediv) {
window.openid_tracediv = document.createElement("ol");
document.body.appendChild(window.openid_tracediv);
}
var el = document.createElement("li");
+ if (color) { el.style.color = color; }
el.appendChild(document.createTextNode(msg));
window.openid_tracediv.appendChild(el);
//alert(msg);
@@ -22,13 +25,8 @@ trace = function(msg) {
};
if (window.dnoa_internal === undefined) {
- window.dnoa_internal = new Object();
-};
-
-// The possible authentication results
-window.dnoa_internal.authSuccess = new Object();
-window.dnoa_internal.authRefused = new Object();
-window.dnoa_internal.timedOut = new Object();
+ window.dnoa_internal = {};
+}
/// <summary>Instantiates an object that provides string manipulation services for URIs.</summary>
window.dnoa_internal.Uri = function(url) {
@@ -41,20 +39,20 @@ window.dnoa_internal.Uri = function(url) {
this.getAuthority = function() {
var authority = this.getScheme() + "://" + this.getHost();
return authority;
- }
+ };
this.getHost = function() {
var hostStartIdx = this.originalUri.indexOf("://") + 3;
var hostEndIndex = this.originalUri.indexOf("/", hostStartIdx);
- if (hostEndIndex < 0) hostEndIndex = this.originalUri.length;
+ if (hostEndIndex < 0) { hostEndIndex = this.originalUri.length; }
var host = this.originalUri.substr(hostStartIdx, hostEndIndex - hostStartIdx);
return host;
- }
+ };
this.getScheme = function() {
var schemeStartIdx = this.indexOf("://");
return this.originalUri.substr(this.originalUri, schemeStartIdx);
- }
+ };
this.trimFragment = function() {
var hashmark = this.originalUri.indexOf('#');
@@ -76,13 +74,13 @@ window.dnoa_internal.Uri = function(url) {
function KeyValuePair(key, value) {
this.key = key;
this.value = value;
- };
+ }
- this.pairs = new Array();
+ this.pairs = [];
var queryBeginsAt = this.originalUri.indexOf('?');
if (queryBeginsAt >= 0) {
- this.queryString = url.substr(queryBeginsAt + 1);
+ this.queryString = this.originalUri.substr(queryBeginsAt + 1);
var queryStringPairs = this.queryString.split('&');
for (var i = 0; i < queryStringPairs.length; i++) {
@@ -91,7 +89,7 @@ window.dnoa_internal.Uri = function(url) {
right = (equalsAt >= 0) ? queryStringPairs[i].substring(equalsAt + 1) : queryStringPairs[i];
this.pairs.push(new KeyValuePair(unescape(left), unescape(right)));
}
- };
+ }
this.getQueryArgValue = function(key) {
for (var i = 0; i < this.pairs.length; i++) {
@@ -103,7 +101,7 @@ window.dnoa_internal.Uri = function(url) {
this.getPairs = function() {
return this.pairs;
- }
+ };
this.containsQueryArg = function(key) {
return this.getQueryArgValue(key);
@@ -141,7 +139,7 @@ window.dnoa_internal.createHiddenIFrame = function() {
}
return iframe;
-}
+};
/// <summary>Redirects the current window/frame to the given URI,
/// either using a GET or a POST as required by the length of the URL.</summary>
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.cs
new file mode 100644
index 0000000..7ffc931
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.cs
@@ -0,0 +1,351 @@
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdSelector.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName, "text/javascript")]
+[assembly: System.Web.UI.WebResource(DotNetOpenAuth.OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName, "text/css")]
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+ using System.ComponentModel;
+ using System.Diagnostics.Contracts;
+ using System.Globalization;
+ using System.IdentityModel.Claims;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.HtmlControls;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ComponentModel;
+ using DotNetOpenAuth.InfoCard;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// An ASP.NET control that provides a user-friendly way of logging into a web site using OpenID.
+ /// </summary>
+ [ToolboxData("<{0}:OpenIdSelector runat=\"server\"></{0}:OpenIdSelector>")]
+ [ParseChildren(true), PersistChildren(false)]
+ public class OpenIdSelector : OpenIdRelyingPartyAjaxControlBase {
+ /// <summary>
+ /// The name of the manifest stream containing the OpenIdButtonPanel.js file.
+ /// </summary>
+ internal const string EmbeddedScriptResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdSelector.js";
+
+ /// <summary>
+ /// The name of the manifest stream containing the OpenIdButtonPanel.css file.
+ /// </summary>
+ internal const string EmbeddedStylesheetResourceName = Util.DefaultNamespace + ".OpenId.RelyingParty.OpenIdSelector.css";
+
+ #region ViewState keys
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="Buttons"/> property.
+ /// </summary>
+ private const string ButtonsViewStateKey = "Buttons";
+
+ /// <summary>
+ /// The viewstate key to use for storing the value of the <see cref="AuthenticatedAsToolTip"/> property.
+ /// </summary>
+ private const string AuthenticatedAsToolTipViewStateKey = "AuthenticatedAsToolTip";
+
+ #endregion
+
+ #region Property defaults
+
+ /// <summary>
+ /// The default value for the <see cref="AuthenticatedAsToolTip"/> property.
+ /// </summary>
+ private const string AuthenticatedAsToolTipDefault = "We recognize you!";
+
+ #endregion
+
+ /// <summary>
+ /// The OpenIdAjaxTextBox that remains hidden until the user clicks the OpenID button.
+ /// </summary>
+ private OpenIdAjaxTextBox textBox;
+
+ /// <summary>
+ /// The hidden field that will transmit the positive assertion to the RP.
+ /// </summary>
+ private HiddenField positiveAssertionField;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OpenIdSelector"/> class.
+ /// </summary>
+ public OpenIdSelector() {
+ }
+
+ /// <summary>
+ /// Occurs when an InfoCard has been submitted and decoded.
+ /// </summary>
+ public event EventHandler<ReceivedTokenEventArgs> ReceivedToken;
+
+ /// <summary>
+ /// Occurs when [token processing error].
+ /// </summary>
+ public event EventHandler<TokenProcessingErrorEventArgs> TokenProcessingError;
+
+ /// <summary>
+ /// Gets or sets the tool tip text that appears on the green checkmark when authentication succeeds.
+ /// </summary>
+ [Bindable(true), DefaultValue(AuthenticatedAsToolTipDefault), Localizable(true), Category(AppearanceCategory)]
+ [Description("The tool tip text that appears on the green checkmark when authentication succeeds.")]
+ public string AuthenticatedAsToolTip {
+ get { return (string)(this.ViewState[AuthenticatedAsToolTipViewStateKey] ?? AuthenticatedAsToolTipDefault); }
+ set { this.ViewState[AuthenticatedAsToolTipViewStateKey] = value ?? string.Empty; }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether the Yahoo! User Interface Library (YUI)
+ /// will be downloaded in order to provide a login split button.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> to use a split button; otherwise, <c>false</c> to use a standard HTML button
+ /// or a split button by downloading the YUI library yourself on the hosting web page.
+ /// </value>
+ /// <remarks>
+ /// The split button brings in about 180KB of YUI javascript dependencies.
+ /// </remarks>
+ [Bindable(true), DefaultValue(OpenIdAjaxTextBox.DownloadYahooUILibraryDefault), Category(BehaviorCategory)]
+ [Description("Whether a split button will be used for the \"log in\" when the user provides an identifier that delegates to more than one Provider.")]
+ public bool DownloadYahooUILibrary {
+ get {
+ this.EnsureChildControls();
+ return this.textBox.DownloadYahooUILibrary;
+ }
+
+ set {
+ this.EnsureChildControls();
+ this.textBox.DownloadYahooUILibrary = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the collection of buttons this selector should render to the browser.
+ /// </summary>
+ [PersistenceMode(PersistenceMode.InnerProperty)]
+ public Collection<SelectorButton> Buttons {
+ get {
+ if (this.ViewState[ButtonsViewStateKey] == null) {
+ var providers = new Collection<SelectorButton>();
+ this.ViewState[ButtonsViewStateKey] = providers;
+ return providers;
+ } else {
+ return (Collection<SelectorButton>)this.ViewState[ButtonsViewStateKey];
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a <see cref="T:System.Web.UI.ControlCollection"/> object that represents the child controls for a specified server control in the UI hierarchy.
+ /// </summary>
+ /// <returns>
+ /// The collection of child controls for the specified server control.
+ /// </returns>
+ public override ControlCollection Controls {
+ get {
+ this.EnsureChildControls();
+ return base.Controls;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the InfoCard selector which may be displayed alongside the OP buttons.
+ /// </summary>
+ internal InfoCardSelector InfoCardSelector { get; set; }
+
+ /// <summary>
+ /// Gets the name of the open id auth data form key (for the value as stored at the user agent as a FORM field).
+ /// </summary>
+ /// <value>
+ /// Usually a concatenation of the control's name and <c>"_openidAuthData"</c>.
+ /// </value>
+ protected override string OpenIdAuthDataFormKey {
+ get { return this.ClientID + "_openidAuthData"; }
+ }
+
+ /// <summary>
+ /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
+ /// </summary>
+ protected override void CreateChildControls() {
+ base.CreateChildControls();
+
+ this.InfoCardSelector = new InfoCardSelector();
+ this.InfoCardSelector.ClaimsRequested.Add(new ClaimType { Name = ClaimTypes.PPID });
+ this.InfoCardSelector.ImageSize = InfoCardImageSize.Size60x42;
+ this.InfoCardSelector.ReceivedToken += this.InfoCardSelector_ReceivedToken;
+ this.InfoCardSelector.TokenProcessingError += this.InfoCardSelector_TokenProcessingError;
+ this.Controls.Add(this.InfoCardSelector);
+
+ this.textBox = new OpenIdAjaxTextBox();
+ this.textBox.ID = "openid_identifier";
+ this.textBox.HookFormSubmit = false;
+ this.textBox.ShowLogOnPostBackButton = true;
+ this.Controls.Add(this.textBox);
+
+ this.positiveAssertionField = new HiddenField();
+ this.positiveAssertionField.ID = this.OpenIdAuthDataFormKey;
+ this.Controls.Add(this.positiveAssertionField);
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
+ /// </summary>
+ /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
+ protected override void OnInit(EventArgs e) {
+ base.OnInit(e);
+
+ // We force child control creation here so that they can get postback events.
+ EnsureChildControls();
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
+ /// </summary>
+ /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
+ protected override void OnPreRender(EventArgs e) {
+ base.OnPreRender(e);
+
+ this.EnsureValidButtons();
+
+ var css = new HtmlLink();
+ css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName);
+ css.Attributes["rel"] = "stylesheet";
+ css.Attributes["type"] = "text/css";
+ ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer);
+ this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override
+
+ // Import the .js file where most of the code is.
+ this.Page.ClientScript.RegisterClientScriptResource(typeof(OpenIdSelector), EmbeddedScriptResourceName);
+
+ // Provide javascript with a way to post the login assertion.
+ const string PostLoginAssertionMethodName = "postLoginAssertion";
+ const string PositiveAssertionParameterName = "positiveAssertion";
+ const string ScriptFormat = @"window.{2} = function({0}) {{
+ $('#{3}')[0].setAttribute('value', {0});
+ {1};
+}};";
+ string script = string.Format(
+ CultureInfo.InvariantCulture,
+ ScriptFormat,
+ PositiveAssertionParameterName,
+ this.Page.ClientScript.GetPostBackEventReference(this, null, false),
+ PostLoginAssertionMethodName,
+ this.positiveAssertionField.ClientID);
+ this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Postback", script, true);
+
+ this.PreloadDiscovery(this.Buttons.OfType<SelectorProviderButton>().Select(op => op.OPIdentifier).Where(id => id != null));
+ }
+
+ /// <summary>
+ /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
+ /// </summary>
+ /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
+ protected override void Render(HtmlTextWriter writer) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIdProviders");
+ writer.RenderBeginTag(HtmlTextWriterTag.Ul);
+
+ foreach (var button in this.Buttons) {
+ button.RenderLeadingAttributes(writer);
+
+ writer.RenderBeginTag(HtmlTextWriterTag.Li);
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Href, "#");
+ writer.RenderBeginTag(HtmlTextWriterTag.A);
+
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+
+ button.RenderButtonContent(writer, this);
+
+ writer.RenderEndTag(); // </div>
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "ui-widget-overlay");
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+ writer.RenderEndTag();
+
+ writer.RenderEndTag(); // </div>
+ writer.RenderEndTag(); // </a>
+ writer.RenderEndTag(); // </li>
+ }
+
+ writer.RenderEndTag(); // </ul>
+
+ writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, "OpenIDForm");
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+
+ this.textBox.RenderControl(writer);
+
+ writer.RenderEndTag(); // </div>
+
+ this.positiveAssertionField.RenderControl(writer);
+ }
+
+ /// <summary>
+ /// Fires the <see cref="ReceivedToken"/> event.
+ /// </summary>
+ /// <param name="e">The token, if it was decrypted.</param>
+ protected virtual void OnReceivedToken(ReceivedTokenEventArgs e) {
+ Contract.Requires(e != null);
+ ErrorUtilities.VerifyArgumentNotNull(e, "e");
+
+ var receivedInfoCard = this.ReceivedToken;
+ if (receivedInfoCard != null) {
+ receivedInfoCard(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Raises the <see cref="E:TokenProcessingError"/> event.
+ /// </summary>
+ /// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.TokenProcessingErrorEventArgs"/> instance containing the event data.</param>
+ protected virtual void OnTokenProcessingError(TokenProcessingErrorEventArgs e) {
+ Contract.Requires(e != null);
+ ErrorUtilities.VerifyArgumentNotNull(e, "e");
+
+ var tokenProcessingError = this.TokenProcessingError;
+ if (tokenProcessingError != null) {
+ tokenProcessingError(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Handles the ReceivedToken event of the infoCardSelector control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.ReceivedTokenEventArgs"/> instance containing the event data.</param>
+ private void InfoCardSelector_ReceivedToken(object sender, ReceivedTokenEventArgs e) {
+ this.Page.Response.SetCookie(new HttpCookie("openid_identifier", "infocard") {
+ Path = this.Page.Request.ApplicationPath,
+ });
+ this.OnReceivedToken(e);
+ }
+
+ /// <summary>
+ /// Handles the TokenProcessingError event of the infoCardSelector control.
+ /// </summary>
+ /// <param name="sender">The source of the event.</param>
+ /// <param name="e">The <see cref="DotNetOpenAuth.InfoCard.TokenProcessingErrorEventArgs"/> instance containing the event data.</param>
+ private void InfoCardSelector_TokenProcessingError(object sender, TokenProcessingErrorEventArgs e) {
+ this.OnTokenProcessingError(e);
+ }
+
+ /// <summary>
+ /// Ensures the <see cref="Buttons"/> collection has a valid set of buttons.
+ /// </summary>
+ private void EnsureValidButtons() {
+ foreach (var button in this.Buttons) {
+ button.EnsureValid();
+ }
+
+ // Also make sure that there are appropriate numbers of each type of button.
+ // TODO: code here
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.css b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.css
new file mode 100644
index 0000000..e7eafc7
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.css
@@ -0,0 +1,109 @@
+ul.OpenIdProviders
+{
+ padding: 0;
+ margin: 0px 0px 0px 0px;
+ list-style-type: none;
+ text-align: center;
+}
+
+ul.OpenIdProviders li
+{
+ background-color: White;
+ display: inline-block;
+ border: 1px solid #DDD;
+ margin: 0px 2px 4px 2px;
+ height: 50px;
+ width: 100px;
+ text-align: center;
+ vertical-align: middle;
+}
+
+ul.OpenIdProviders li div
+{
+ margin: 0;
+ padding: 0;
+ height: 50px;
+ width: 100px;
+ text-align: center;
+ display: table;
+ position: relative;
+ overflow: hidden;
+}
+
+ul.OpenIdProviders li div div
+{
+ margin: 0;
+ padding: 0;
+ top: 50%;
+ display: table-cell;
+ vertical-align: middle;
+ position: static;
+}
+
+ul.OpenIdProviders li img
+{
+}
+
+ul.OpenIdProviders li a img
+{
+ border-width: 0;
+}
+
+ul.OpenIdProviders li img.loginSuccess
+{
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ display: none;
+}
+
+ul.OpenIdProviders li.loginSuccess img.loginSuccess
+{
+ display: inline;
+}
+
+ul.OpenIdProviders li a
+{
+ display: block; /* Chrome needs this for proper position of grayed out overlay */
+ position: relative;
+}
+
+ul.OpenIdProviders li div.ui-widget-overlay
+{
+ display: none;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ bottom: 0;
+}
+
+ul.OpenIdProviders li.grayedOut div.ui-widget-overlay
+{
+ display: block;
+}
+
+ul.OpenIdProviders li.focused
+{
+ border: solid 2px yellow;
+}
+
+ul.OpenIdProviders li.infocard
+{
+ display: none; /* default to hiding InfoCard until the user agent determines it's supported */
+ cursor: pointer;
+}
+
+#openid_identifier
+{
+ width: 298px;
+}
+
+#OpenIDForm
+{
+ text-align: center;
+}
+
+#openid_login_button
+{
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.js b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.js
new file mode 100644
index 0000000..2041618
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdSelector.js
@@ -0,0 +1,179 @@
+//-----------------------------------------------------------------------
+// <copyright file="OpenIdSelector.js" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// This file may be used and redistributed under the terms of the
+// Microsoft Public License (Ms-PL) http://opensource.org/licenses/ms-pl.html
+// </copyright>
+//-----------------------------------------------------------------------
+
+$(function() {
+ var hint = $.cookie('openid_identifier') || '';
+
+ var ajaxbox = $('#openid_identifier')[0];
+ if (hint != 'infocard') {
+ ajaxbox.setValue(hint);
+ }
+
+ if (document.infoCard.isSupported()) {
+ $('ul.OpenIdProviders li.infocard')[0].style.display = 'inline-block';
+ }
+
+ if (hint.length > 0) {
+ var ops = $('ul.OpenIdProviders li');
+ ops.addClass('grayedOut');
+ var matchFound = false;
+ ops.each(function(i, li) {
+ if (li.id == hint || (hint == 'infocard' && $(li).hasClass('infocard'))) {
+ $(li)
+ .removeClass('grayedOut')
+ .addClass('focused');
+ matchFound = true;
+ }
+ });
+ if (!matchFound) {
+ $('#OpenIDButton')
+ .removeClass('grayedOut')
+ .addClass('focused');
+ $('#OpenIDForm').show('slow', function() {
+ $('#openid_identifier').focus();
+ });
+ }
+ }
+
+ function showLoginSuccess(userSuppliedIdentifier, success) {
+ var li = document.getElementById(userSuppliedIdentifier);
+ if (li) {
+ if (success) {
+ $(li).addClass('loginSuccess');
+ } else {
+ $(li).removeClass('loginSuccess');
+ }
+ }
+ }
+
+ window.dnoa_internal.addAuthSuccess(function(discoveryResult, serviceEndpoint, extensionResponses, state) {
+ showLoginSuccess(discoveryResult.userSuppliedIdentifier, true);
+ });
+
+ window.dnoa_internal.addAuthCleared(function(discoveryResult, serviceEndpoint) {
+ showLoginSuccess(discoveryResult.userSuppliedIdentifier, false);
+
+ // If this is an OP button, renew the positive assertion.
+ var li = document.getElementById(discoveryResult.userSuppliedIdentifier);
+ if (li) {
+ li.loginBackground();
+ }
+ });
+
+ ajaxbox.onStateChanged = function(state) {
+ if (state == "authenticated") {
+ showLoginSuccess('OpenIDButton', true);
+ } else {
+ showLoginSuccess('OpenIDButton', false); // hide checkmark
+ }
+ };
+
+ function checkidSetup(identifier, timerBased) {
+ var openid = new window.OpenIdIdentifier(identifier);
+ if (!openid) { throw 'checkidSetup called without an identifier.'; }
+ openid.login(function(discoveryResult, respondingEndpoint, extensionResponses) {
+ doLogin(discoveryResult, respondingEndpoint);
+ });
+ }
+
+ // Sends the positive assertion we've collected to the server and actually logs the user into the RP.
+ function doLogin(discoveryResult, respondingEndpoint) {
+ var retain = true; //!$('#NotMyComputer')[0].selected;
+ $.cookie('openid_identifier', retain ? discoveryResult.userSuppliedIdentifier : null, { path: window.aspnetapppath });
+ window.postLoginAssertion(respondingEndpoint.response.toString(), window.parent.location.href);
+ }
+
+ // take over how the text box does postbacks.
+ ajaxbox.dnoi_internal.postback = doLogin;
+
+ // This FrameManager will be used for background logins for the OP buttons
+ // and the last used identifier. It is NOT the frame manager used by the
+ // OpenIdAjaxTextBox, as it has its own.
+ var backgroundTimeout = 3000;
+
+ $(document).ready(function() {
+ var ops = $('ul.OpenIdProviders li');
+ ops.each(function(i, li) {
+ if ($(li).hasClass('OPButton')) {
+ li.authenticationIFrames = new window.dnoa_internal.FrameManager(1/*throttle*/);
+ var openid = new window.OpenIdIdentifier(li.id);
+ var authFrames = li.authenticationIFrames;
+ if ($(li).hasClass('NoAsyncAuth')) {
+ li.loginBackground = function() { };
+ } else {
+ li.loginBackground = function() {
+ openid.loginBackground(authFrames, null, null, backgroundTimeout);
+ };
+ }
+ li.loginBackground();
+ }
+ });
+ });
+
+ $('ul.OpenIdProviders li').click(function() {
+ var lastFocus = $('.focused')[0];
+ if (lastFocus != $(this)[0]) {
+ $('ul.OpenIdProviders li').removeClass('focused');
+ $(this).addClass('focused');
+ }
+
+ // Make sure we're not graying out any OPs if the user clicked on a gray button.
+ var wasGrayedOut = false;
+ if ($(this).hasClass('grayedOut')) {
+ wasGrayedOut = true;
+ $('ul.OpenIdProviders li').removeClass('grayedOut');
+ }
+
+ // Be sure to hide the openid_identifier text box unless the OpenID button is selected.
+ if ($(this)[0] != $('#OpenIDButton')[0] && $('#OpenIDForm').is(':visible')) {
+ $('#OpenIDForm').hide('slow');
+ }
+
+ var relevantUserSuppliedIdentifier = null;
+ // Don't immediately login if the user clicked OpenID and he can't see the identifier box.
+ if ($(this)[0].id != 'OpenIDButton') {
+ relevantUserSuppliedIdentifier = $(this)[0].id;
+ } else if ($('#OpenIDForm').is(':visible')) {
+ relevantUserSuppliedIdentifier = ajaxbox.value;
+ }
+
+ var discoveryResult = window.dnoa_internal.discoveryResults[relevantUserSuppliedIdentifier];
+ var respondingEndpoint = discoveryResult ? discoveryResult.findSuccessfulRequest() : null;
+
+ // If the user clicked on a button that has the "we're ready to log you in immediately",
+ // then log them in!
+ if (respondingEndpoint) {
+ doLogin(discoveryResult, respondingEndpoint);
+ } else if ($(this).hasClass('OPButton')) {
+ checkidSetup($(this)[0].id);
+ } else if ($(this).hasClass('infocard') && wasGrayedOut) {
+ // we need to forward the click onto the InfoCard image so it is handled, since our
+ // gray overlaying div captured the click event.
+ $('img', this)[0].click();
+ }
+ });
+ $('#OpenIDButton').click(function() {
+ if ($('#OpenIDForm').is(':hidden')) {
+ $('#OpenIDForm').show('slow', function() {
+ $('#openid_identifier').focus();
+ });
+ } else {
+ $('#openid_identifier').focus();
+ }
+ });
+
+ // Make popup window close on escape (the dialog style is already taken care of)
+ $(document).keydown(function(e) {
+ if (e.keyCode == $.ui.keyCode.ESCAPE) {
+ window.close();
+ } else if (e.keyCode == $.ui.keyCode.ENTER) {
+ // we do NOT want to submit the form on ENTER.
+ e.preventDefault();
+ }
+ });
+}); \ No newline at end of file
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdTextBox.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdTextBox.cs
index 0723f55..b5266a9 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdTextBox.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdTextBox.cs
@@ -40,7 +40,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
[DefaultProperty("Text"), ValidationProperty("Text")]
[ToolboxData("<{0}:OpenIdTextBox runat=\"server\" />")]
- public class OpenIdTextBox : CompositeControl, IEditableTextControl, ITextControl {
+ public class OpenIdTextBox : OpenIdRelyingPartyControlBase, IEditableTextControl, ITextControl, IPostBackDataHandler {
/// <summary>
/// The name of the manifest stream containing the
/// OpenID logo that is placed inside the text box.
@@ -52,38 +52,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
protected const short TabIndexDefault = 0;
- /// <summary>
- /// Default value of <see cref="UsePersistentCookie"/>.
- /// </summary>
- protected const bool UsePersistentCookieDefault = false;
-
#region Property category constants
/// <summary>
- /// The "Appearance" category for properties.
- /// </summary>
- private const string AppearanceCategory = "Appearance";
-
- /// <summary>
/// The "Simple Registration" category for properties.
/// </summary>
private const string ProfileCategory = "Simple Registration";
- /// <summary>
- /// The "Behavior" category for properties.
- /// </summary>
- private const string BehaviorCategory = "Behavior";
-
#endregion
#region Property viewstate keys
/// <summary>
- /// The viewstate key to use for the <see cref="Popup"/> property.
- /// </summary>
- private const string PopupViewStateKey = "Popup";
-
- /// <summary>
/// The viewstate key to use for the <see cref="RequestEmail"/> property.
/// </summary>
private const string RequestEmailViewStateKey = "RequestEmail";
@@ -104,11 +84,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string RequestCountryViewStateKey = "RequestCountry";
/// <summary>
- /// The viewstate key to use for the <see cref="RequireSsl"/> property.
- /// </summary>
- private const string RequireSslViewStateKey = "RequireSsl";
-
- /// <summary>
/// The viewstate key to use for the <see cref="RequestLanguage"/> property.
/// </summary>
private const string RequestLanguageViewStateKey = "RequestLanguage";
@@ -144,43 +119,53 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string ShowLogoViewStateKey = "ShowLogo";
/// <summary>
- /// The viewstate key to use for the <see cref="UsePersistentCookie"/> property.
+ /// The viewstate key to use for the <see cref="RequestGender"/> property.
/// </summary>
- private const string UsePersistentCookieViewStateKey = "UsePersistentCookie";
+ private const string RequestGenderViewStateKey = "RequestGender";
/// <summary>
- /// The viewstate key to use for the <see cref="RequestGender"/> property.
+ /// The viewstate key to use for the <see cref="RequestBirthDate"/> property.
/// </summary>
- private const string RequestGenderViewStateKey = "RequestGender";
+ private const string RequestBirthDateViewStateKey = "RequestBirthDate";
/// <summary>
- /// The viewstate key to use for the <see cref="ReturnToUrl"/> property.
+ /// The viewstate key to use for the <see cref="CssClass"/> property.
/// </summary>
- private const string ReturnToUrlViewStateKey = "ReturnToUrl";
+ private const string CssClassViewStateKey = "CssClass";
/// <summary>
- /// The viewstate key to use for the <see cref="Stateless"/> property.
+ /// The viewstate key to use for the <see cref="MaxLength"/> property.
/// </summary>
- private const string StatelessViewStateKey = "Stateless";
+ private const string MaxLengthViewStateKey = "MaxLength";
/// <summary>
- /// The viewstate key to use for the <see cref="RequestBirthDate"/> property.
+ /// The viewstate key to use for the <see cref="Columns"/> property.
/// </summary>
- private const string RequestBirthDateViewStateKey = "RequestBirthDate";
+ private const string ColumnsViewStateKey = "Columns";
/// <summary>
- /// The viewstate key to use for the <see cref="RealmUrl"/> property.
+ /// The viewstate key to use for the <see cref="TabIndex"/> property.
/// </summary>
- private const string RealmUrlViewStateKey = "RealmUrl";
+ private const string TabIndexViewStateKey = "TabIndex";
- #endregion
+ /// <summary>
+ /// The viewstate key to use for the <see cref="Enabled"/> property.
+ /// </summary>
+ private const string EnabledViewStateKey = "Enabled";
- #region Property defaults
+ /// <summary>
+ /// The viewstate key to use for the <see cref="Name"/> property.
+ /// </summary>
+ private const string NameViewStateKey = "Name";
/// <summary>
- /// The default value for the <see cref="Popup"/> property.
+ /// The viewstate key to use for the <see cref="Text"/> property.
/// </summary>
- private const PopupBehavior PopupDefault = PopupBehavior.Never;
+ private const string TextViewStateKey = "Text";
+
+ #endregion
+
+ #region Property defaults
/// <summary>
/// The default value for the <see cref="Columns"/> property.
@@ -193,19 +178,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const int MaxLengthDefault = 40;
/// <summary>
- /// The default value for the <see cref="EnableRequestProfile"/> property.
- /// </summary>
- private const bool EnableRequestProfileDefault = true;
-
- /// <summary>
- /// The default value for the <see cref="RequireSsl"/> property.
+ /// The default value for the <see cref="Name"/> property.
/// </summary>
- private const bool RequireSslDefault = false;
+ private const string NameDefault = "openid_identifier";
/// <summary>
- /// The default value for the <see cref="Stateless"/> property.
+ /// The default value for the <see cref="EnableRequestProfile"/> property.
/// </summary>
- private const bool StatelessDefault = false;
+ private const bool EnableRequestProfileDefault = true;
/// <summary>
/// The default value for the <see cref="ShowLogo"/> property.
@@ -228,21 +208,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private const string CssClassDefault = "openid";
/// <summary>
- /// The default value for the <see cref="ReturnToUrl"/> property.
- /// </summary>
- private const string ReturnToUrlDefault = "";
-
- /// <summary>
/// The default value for the <see cref="Text"/> property.
/// </summary>
private const string TextDefault = "";
/// <summary>
- /// The default value for the <see cref="RealmUrl"/> property.
- /// </summary>
- private const string RealmUrlDefault = "~/";
-
- /// <summary>
/// The default value for the <see cref="RequestEmail"/> property.
/// </summary>
private const DemandLevel RequestEmailDefault = DemandLevel.NoRequest;
@@ -290,79 +260,22 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
/// <summary>
- /// The callback parameter to use for recognizing when the callback is in a popup window.
- /// </summary>
- private const string UIPopupCallbackKey = OpenIdUtilities.CustomParameterPrefix + "uipopup";
-
- /// <summary>
- /// The callback parameter to use for recognizing when the callback is in the parent window.
- /// </summary>
- private const string UIPopupCallbackParentKey = OpenIdUtilities.CustomParameterPrefix + "uipopupParent";
-
- /// <summary>
- /// The callback parameter for use with persisting the <see cref="UsePersistentCookie"/> property.
- /// </summary>
- private const string UsePersistentCookieCallbackKey = "OpenIdTextBox_UsePersistentCookie";
-
- /// <summary>
- /// The text in the text box before the text box is instantiated.
+ /// An empty sreg request, used to compare with others to see if they too are empty.
/// </summary>
- private string text = TextDefault;
-
- /// <summary>
- /// The text box itself.
- /// </summary>
- private TextBox wrappedTextBox;
-
- /// <summary>
- /// Backing field for the <see cref="RelyingParty"/> property.
- /// </summary>
- private OpenIdRelyingParty relyingParty;
+ private static readonly ClaimsRequest EmptyClaimsRequest = new ClaimsRequest();
/// <summary>
/// Initializes a new instance of the <see cref="OpenIdTextBox"/> class.
/// </summary>
public OpenIdTextBox() {
- this.InitializeControls();
}
- #region Events
-
- /// <summary>
- /// Fired upon completion of a successful login.
- /// </summary>
- [Description("Fired upon completion of a successful login.")]
- public event EventHandler<OpenIdEventArgs> LoggedIn;
-
- /// <summary>
- /// Fired when a login attempt fails.
- /// </summary>
- [Description("Fired when a login attempt fails.")]
- public event EventHandler<OpenIdEventArgs> Failed;
-
- /// <summary>
- /// Fired when an authentication attempt is canceled at the OpenID Provider.
- /// </summary>
- [Description("Fired when an authentication attempt is canceled at the OpenID Provider.")]
- public event EventHandler<OpenIdEventArgs> Canceled;
-
- /// <summary>
- /// Fired when an Immediate authentication attempt fails, and the Provider suggests using non-Immediate mode.
- /// </summary>
- [Description("Fired when an Immediate authentication attempt fails, and the Provider suggests using non-Immediate mode.")]
- public event EventHandler<OpenIdEventArgs> SetupRequired;
-
- #endregion
-
#region IEditableTextControl Members
/// <summary>
/// Occurs when the content of the text changes between posts to the server.
/// </summary>
- public event EventHandler TextChanged {
- add { this.WrappedTextBox.TextChanged += value; }
- remove { this.WrappedTextBox.TextChanged -= value; }
- }
+ public event EventHandler TextChanged;
#endregion
@@ -375,101 +288,32 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Description("The content of the text box.")]
public string Text {
get {
- return this.WrappedTextBox != null ? this.WrappedTextBox.Text : this.text;
- }
-
- set {
- this.text = value;
- if (this.WrappedTextBox != null) {
- this.WrappedTextBox.Text = value;
- }
- }
- }
-
- /// <summary>
- /// Gets or sets the OpenID <see cref="Realm"/> of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "DotNetOpenAuth.OpenId.Realm", Justification = "Using ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(RealmUrlDefault), Category(BehaviorCategory)]
- [Description("The OpenID Realm of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string RealmUrl {
- get {
- return (string)(ViewState[RealmUrlViewStateKey] ?? RealmUrlDefault);
- }
-
- set {
- if (Page != null && !DesignMode) {
- // Validate new value by trying to construct a Realm object based on it.
- new Realm(OpenIdUtilities.GetResolvedRealm(this.Page, value, this.RelyingParty.Channel.GetRequestFromContext())); // throws an exception on failure.
- } else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value.Replace("*.", string.Empty)); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
- }
- ViewState[RealmUrlViewStateKey] = value;
- }
- }
-
- /// <summary>
- /// Gets or sets the OpenID ReturnTo of the relying party web site.
- /// </summary>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Bindable property must be simple type")]
- [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "System.Uri", Justification = "Using Uri.ctor for validation.")]
- [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Bindable property must be simple type")]
- [Bindable(true), DefaultValue(ReturnToUrlDefault), Category(BehaviorCategory)]
- [Description("The OpenID ReturnTo of the relying party web site.")]
- [UrlProperty, Editor("System.Web.UI.Design.UrlEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
- public string ReturnToUrl {
- get {
- return (string)(this.ViewState[ReturnToUrlViewStateKey] ?? ReturnToUrlDefault);
+ return this.Identifier != null ? this.Identifier.OriginalString : (this.ViewState[TextViewStateKey] as string ?? string.Empty);
}
set {
- if (this.Page != null && !this.DesignMode) {
- // Validate new value by trying to construct a Uri based on it.
- new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(value)); // throws an exception on failure.
+ // Try to store it as a validated identifier,
+ // but failing that at least store the text.
+ Identifier id;
+ if (Identifier.TryParse(value, out id)) {
+ this.Identifier = id;
} else {
- // We can't fully test it, but it should start with either ~/ or a protocol.
- if (Regex.IsMatch(value, @"^https?://")) {
- new Uri(value); // make sure it's fully-qualified, but ignore wildcards
- } else if (value.StartsWith("~/", StringComparison.Ordinal)) {
- // this is valid too
- } else {
- throw new UriFormatException();
- }
+ // Be sure to set the viewstate AFTER setting the Identifier,
+ // since setting the Identifier clears the viewstate in OnIdentifierChanged.
+ this.Identifier = null;
+ this.ViewState[TextViewStateKey] = value;
}
-
- this.ViewState[ReturnToUrlViewStateKey] = value;
}
}
/// <summary>
- /// Gets or sets a value indicating when to use a popup window to complete the login experience.
+ /// Gets or sets the form name to use for this input field.
/// </summary>
- /// <value>The default value is <see cref="PopupBehavior.Never"/>.</value>
- [Bindable(true), DefaultValue(PopupDefault), Category(BehaviorCategory)]
- [Description("When to use a popup window to complete the login experience.")]
- public PopupBehavior Popup {
- get { return (PopupBehavior)(ViewState[PopupViewStateKey] ?? PopupDefault); }
- set { ViewState[PopupViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether stateless mode is used.
- /// </summary>
- [Bindable(true), DefaultValue(StatelessDefault), Category(BehaviorCategory)]
- [Description("Controls whether stateless mode is used.")]
- public bool Stateless {
- get { return (bool)(ViewState[StatelessViewStateKey] ?? StatelessDefault); }
- set { ViewState[StatelessViewStateKey] = value; }
+ [Bindable(true), DefaultValue(NameDefault), Category(BehaviorCategory)]
+ [Description("The form name of this input field.")]
+ public string Name {
+ get { return (string)(this.ViewState[NameViewStateKey] ?? NameDefault); }
+ set { this.ViewState[NameViewStateKey] = value; }
}
/// <summary>
@@ -477,9 +321,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
[Bindable(true), DefaultValue(CssClassDefault), Category(AppearanceCategory)]
[Description("The CSS class assigned to the text box.")]
- public override string CssClass {
- get { return this.WrappedTextBox.CssClass; }
- set { this.WrappedTextBox.CssClass = value; }
+ public string CssClass {
+ get { return (string)this.ViewState[CssClassViewStateKey]; }
+ set { this.ViewState[CssClassViewStateKey] = value; }
}
/// <summary>
@@ -503,25 +347,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
}
/// <summary>
- /// Gets or sets a value indicating whether to send a persistent cookie upon successful
- /// login so the user does not have to log in upon returning to this site.
- /// </summary>
- [Bindable(true), DefaultValue(UsePersistentCookieDefault), Category(BehaviorCategory)]
- [Description("Whether to send a persistent cookie upon successful " +
- "login so the user does not have to log in upon returning to this site.")]
- public virtual bool UsePersistentCookie {
- get { return (bool)(this.ViewState[UsePersistentCookieViewStateKey] ?? UsePersistentCookieDefault); }
- set { this.ViewState[UsePersistentCookieViewStateKey] = value; }
- }
-
- /// <summary>
/// Gets or sets the width of the text box in characters.
/// </summary>
[Bindable(true), DefaultValue(ColumnsDefault), Category(AppearanceCategory)]
[Description("The width of the text box in characters.")]
public int Columns {
- get { return this.WrappedTextBox.Columns; }
- set { this.WrappedTextBox.Columns = value; }
+ get { return (int)(this.ViewState[ColumnsViewStateKey] ?? ColumnsDefault); }
+ set { this.ViewState[ColumnsViewStateKey] = value; }
}
/// <summary>
@@ -530,8 +362,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[Bindable(true), DefaultValue(MaxLengthDefault), Category(AppearanceCategory)]
[Description("The maximum number of characters the browser should allow.")]
public int MaxLength {
- get { return this.WrappedTextBox.MaxLength; }
- set { this.WrappedTextBox.MaxLength = value; }
+ get { return (int)(this.ViewState[MaxLengthViewStateKey] ?? MaxLengthDefault); }
+ set { this.ViewState[MaxLengthViewStateKey] = value; }
}
/// <summary>
@@ -546,9 +378,21 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </exception>
[Bindable(true), DefaultValue(TabIndexDefault), Category(BehaviorCategory)]
[Description("The tab index of the text box control.")]
- public override short TabIndex {
- get { return this.WrappedTextBox.TabIndex; }
- set { this.WrappedTextBox.TabIndex = value; }
+ public virtual short TabIndex {
+ get { return (short)(this.ViewState[TabIndexViewStateKey] ?? TabIndexDefault); }
+ set { this.ViewState[TabIndexViewStateKey] = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="OpenIdTextBox"/> is enabled
+ /// in the browser for editing and will respond to incoming OpenID messages.
+ /// </summary>
+ /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
+ [Bindable(true), DefaultValue(true), Category(BehaviorCategory)]
+ [Description("Whether the control is editable in the browser and will respond to OpenID messages.")]
+ public bool Enabled {
+ get { return (bool)(this.ViewState[EnabledViewStateKey] ?? true); }
+ set { this.ViewState[EnabledViewStateKey] = value; }
}
/// <summary>
@@ -673,344 +517,45 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
set { ViewState[EnableRequestProfileViewStateKey] = value; }
}
- /// <summary>
- /// Gets or sets a value indicating whether to enforce on high security mode,
- /// which requires the full authentication pipeline to be protected by SSL.
- /// </summary>
- [Bindable(true), DefaultValue(RequireSslDefault), Category(BehaviorCategory)]
- [Description("Turns on high security mode, requiring the full authentication pipeline to be protected by SSL.")]
- public bool RequireSsl {
- get { return (bool)(ViewState[RequireSslViewStateKey] ?? RequireSslDefault); }
- set { ViewState[RequireSslViewStateKey] = value; }
- }
-
- /// <summary>
- /// Gets or sets the type of the custom application store to use, or <c>null</c> to use the default.
- /// </summary>
- /// <remarks>
- /// If set, this property must be set in each Page Load event
- /// as it is not persisted across postbacks.
- /// </remarks>
- public IRelyingPartyApplicationStore CustomApplicationStore { get; set; }
-
#endregion
- #region Properties to hide
-
- /// <summary>
- /// Gets or sets the foreground color (typically the color of the text) of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the foreground color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color ForeColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the background color of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the background color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>, which indicates that this property is not set.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color BackColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the border color of the Web control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Drawing.Color"/> that represents the border color of the control. The default is <see cref="F:System.Drawing.Color.Empty"/>, which indicates that this property is not set.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override System.Drawing.Color BorderColor {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
+ #region IPostBackDataHandler Members
/// <summary>
- /// Gets or sets the border width of the Web server control.
+ /// When implemented by a class, processes postback data for an ASP.NET server control.
/// </summary>
+ /// <param name="postDataKey">The key identifier for the control.</param>
+ /// <param name="postCollection">The collection of all incoming name values.</param>
/// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the border width of a Web server control. The default value is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>, which indicates that this property is not set.
+ /// true if the server control's state changes as a result of the postback; otherwise, false.
/// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The specified border width is a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit BorderWidth {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
+ bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) {
+ return this.LoadPostData(postDataKey, postCollection);
}
/// <summary>
- /// Gets or sets the border style of the Web server control.
+ /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
/// </summary>
- /// <returns>
- /// One of the <see cref="T:System.Web.UI.WebControls.BorderStyle"/> enumeration values. The default is NotSet.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override BorderStyle BorderStyle {
- get { return BorderStyle.None; }
- set { throw new NotSupportedException(); }
+ void IPostBackDataHandler.RaisePostDataChangedEvent() {
+ this.RaisePostDataChangedEvent();
}
- /// <summary>
- /// Gets the font properties associated with the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.FontInfo"/> that represents the font properties of the Web server control.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override FontInfo Font {
- get { return null; }
- }
-
- /// <summary>
- /// Gets or sets the height of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the height of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The height was set to a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit Height {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the width of the Web server control.
- /// </summary>
- /// <returns>
- /// A <see cref="T:System.Web.UI.WebControls.Unit"/> that represents the width of the control. The default is <see cref="F:System.Web.UI.WebControls.Unit.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The width of the Web server control was set to a negative value.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override Unit Width {
- get { return Unit.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets the text displayed when the mouse pointer hovers over the Web server control.
- /// </summary>
- /// <returns>
- /// The text displayed when the mouse pointer hovers over the Web server control. The default is <see cref="F:System.String.Empty"/>.
- /// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override string ToolTip {
- get { return string.Empty; }
- set { throw new NotSupportedException(); }
- }
+ #endregion
/// <summary>
- /// Gets or sets the skin to apply to the control.
+ /// Creates the authentication requests for a given user-supplied Identifier.
/// </summary>
+ /// <param name="identifier">The identifier to create a request for.</param>
/// <returns>
- /// The name of the skin to apply to the control. The default is <see cref="F:System.String.Empty"/>.
- /// </returns>
- /// <exception cref="T:System.ArgumentException">
- /// The skin specified in the <see cref="P:System.Web.UI.WebControls.WebControl.SkinID"/> property does not exist in the theme.
- /// </exception>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override string SkinID {
- get { return string.Empty; }
- set { throw new NotSupportedException(); }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether themes apply to this control.
- /// </summary>
- /// <returns>true to use themes; otherwise, false. The default is false.
+ /// A sequence of authentication requests, any one of which may be
+ /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
/// </returns>
- [Obsolete("This property does not do anything."), Browsable(false), Bindable(false)]
- public override bool EnableTheming {
- get { return false; }
- set { throw new NotSupportedException(); }
- }
-
- #endregion
-
- /// <summary>
- /// Gets or sets the <see cref="OpenIdRelyingParty"/> instance to use.
- /// </summary>
- /// <value>The default value is an <see cref="OpenIdRelyingParty"/> instance initialized according to the web.config file.</value>
- /// <remarks>
- /// A performance optimization would be to store off the
- /// instance as a static member in your web site and set it
- /// to this property in your <see cref="Control.Load">Page.Load</see>
- /// event since instantiating these instances can be expensive on
- /// heavily trafficked web pages.
- /// </remarks>
- public OpenIdRelyingParty RelyingParty {
- get {
- if (this.relyingParty == null) {
- this.relyingParty = this.CreateRelyingParty();
- }
- return this.relyingParty;
- }
-
- set {
- this.relyingParty = value;
- }
- }
-
- /// <summary>
- /// Gets the <see cref="TextBox"/> control that this control wraps.
- /// </summary>
- protected TextBox WrappedTextBox {
- get { return this.wrappedTextBox; }
- }
-
- /// <summary>
- /// Gets or sets a value indicating whether the text box should
- /// receive input focus when the web page appears.
- /// </summary>
- protected bool ShouldBeFocused { get; set; }
-
- /// <summary>
- /// Gets or sets the OpenID authentication request that is about to be sent.
- /// </summary>
- protected IAuthenticationRequest Request { get; set; }
+ protected override IEnumerable<IAuthenticationRequest> CreateRequests(Identifier identifier) {
+ ErrorUtilities.VerifyArgumentNotNull(identifier, "identifier");
- /// <summary>
- /// Sets the input focus to start on the text box when the page appears
- /// in the user's browser.
- /// </summary>
- public override void Focus() {
- if (Controls.Count == 0) {
- this.ShouldBeFocused = true;
- } else {
- this.WrappedTextBox.Focus();
- }
- }
-
- /// <summary>
- /// Constructs the authentication request and returns it.
- /// </summary>
- /// <returns>The instantiated authentication request.</returns>
- /// <remarks>
- /// <para>This method need not be called before calling the <see cref="LogOn"/> method,
- /// but is offered in the event that adding extensions to the request is desired.</para>
- /// <para>The Simple Registration extension arguments are added to the request
- /// before returning if <see cref="EnableRequestProfile"/> is set to true.</para>
- /// </remarks>
- [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")]
- public IAuthenticationRequest CreateRequest() {
- ErrorUtilities.VerifyOperation(this.Request == null, OpenIdStrings.CreateRequestAlreadyCalled);
- ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Text), OpenIdStrings.OpenIdTextBoxEmpty);
-
- try {
- // Approximate the returnTo (either based on the customize property or the page URL)
- // so we can use it to help with Realm resolution.
- var requestContext = this.RelyingParty.Channel.GetRequestFromContext();
- Uri returnToApproximation = this.ReturnToUrl != null ? new Uri(requestContext.UrlBeforeRewriting, this.ReturnToUrl) : this.Page.Request.Url;
-
- // Resolve the trust root, and swap out the scheme and port if necessary to match the
- // return_to URL, since this match is required by OpenId, and the consumer app
- // may be using HTTP at some times and HTTPS at others.
- UriBuilder realm = OpenIdUtilities.GetResolvedRealm(this.Page, this.RealmUrl, this.RelyingParty.Channel.GetRequestFromContext());
- realm.Scheme = returnToApproximation.Scheme;
- realm.Port = returnToApproximation.Port;
-
- // Initiate openid request
- // We use TryParse here to avoid throwing an exception which
- // might slip through our validator control if it is disabled.
- Identifier userSuppliedIdentifier;
- if (Identifier.TryParse(this.Text, out userSuppliedIdentifier)) {
- Realm typedRealm = new Realm(realm);
- if (string.IsNullOrEmpty(this.ReturnToUrl)) {
- this.Request = this.RelyingParty.CreateRequest(userSuppliedIdentifier, typedRealm);
- } else {
- // Since the user actually gave us a return_to value,
- // the "approximation" is exactly what we want.
- this.Request = this.RelyingParty.CreateRequest(userSuppliedIdentifier, typedRealm, returnToApproximation);
- }
-
- if (this.EnableRequestProfile) {
- this.AddProfileArgs(this.Request);
- }
-
- if (this.IsPopupAppropriate()) {
- // Inform the OP that it will appear in a popup window.
- this.Request.AddExtension(new UIRequest());
- }
-
- // Add state that needs to survive across the redirect.
- if (!this.Stateless) {
- this.Request.AddCallbackArguments(UsePersistentCookieCallbackKey, this.UsePersistentCookie.ToString(CultureInfo.InvariantCulture));
- }
- } else {
- Logger.OpenId.WarnFormat("An invalid identifier was entered ({0}), but not caught by any validation routine.", this.Text);
- this.Request = null;
- }
- } catch (ProtocolException ex) {
- this.OnFailed(new FailedAuthenticationResponse(ex));
- }
-
- return this.Request;
- }
-
- /// <summary>
- /// Immediately redirects to the OpenID Provider to verify the Identifier
- /// provided in the text box.
- /// </summary>
- public void LogOn() {
- if (this.Request == null) {
- this.CreateRequest(); // sets this.Request
- }
-
- if (this.Request != null) {
- if (this.IsPopupAppropriate()) {
- this.ScriptPopupWindow();
- } else {
- this.Request.RedirectToProvider();
- }
- }
- }
-
- /// <summary>
- /// Enables a server control to perform final clean up before it is released from memory.
- /// </summary>
- [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Base class doesn't implement virtual Dispose(bool), so we must call its Dispose() method.")]
- public sealed override void Dispose() {
- this.Dispose(true);
- base.Dispose();
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// Creates the text box control.
- /// </summary>
- protected override void CreateChildControls() {
- base.CreateChildControls();
-
- this.Controls.Add(this.wrappedTextBox);
- if (this.ShouldBeFocused) {
- this.WrappedTextBox.Focus();
- }
- }
-
- /// <summary>
- /// Initializes the text box control.
- /// </summary>
- protected virtual void InitializeControls() {
- this.wrappedTextBox = new TextBox();
- this.wrappedTextBox.ID = "wrappedTextBox";
- this.wrappedTextBox.CssClass = CssClassDefault;
- this.wrappedTextBox.Columns = ColumnsDefault;
- this.wrappedTextBox.Text = this.text;
- this.wrappedTextBox.TabIndex = TabIndexDefault;
+ // We delegate all our logic to another method, since invoking base. methods
+ // within an iterator method results in unverifiable code.
+ return this.CreateRequestsCore(base.CreateRequests(identifier));
}
/// <summary>
@@ -1018,165 +563,125 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
protected override void OnLoad(EventArgs e) {
- base.OnLoad(e);
-
- if (!Enabled || Page.IsPostBack) {
+ if (!this.Enabled) {
return;
}
- // Take an unreliable sneek peek to see if we're in a popup and an OpenID
- // assertion is coming in. We shouldn't process assertions in a popup window.
- if (this.Page.Request.QueryString[UIPopupCallbackKey] == "1" && this.Page.Request.QueryString[UIPopupCallbackParentKey] == null) {
- // We're in a popup window. We need to close it and pass the
- // message back to the parent window for processing.
- this.ScriptClosingPopup();
- return; // don't do any more processing on it now
- }
-
- var response = this.RelyingParty.GetResponse();
- if (response != null) {
- string persistentString = response.GetUntrustedCallbackArgument(UsePersistentCookieCallbackKey);
- bool persistentBool;
- if (persistentString != null && bool.TryParse(persistentString, out persistentBool)) {
- this.UsePersistentCookie = persistentBool;
- }
-
- switch (response.Status) {
- case AuthenticationStatus.Canceled:
- this.OnCanceled(response);
- break;
- case AuthenticationStatus.Authenticated:
- this.OnLoggedIn(response);
- break;
- case AuthenticationStatus.SetupRequired:
- this.OnSetupRequired(response);
- break;
- case AuthenticationStatus.Failed:
- this.OnFailed(response);
- break;
- case AuthenticationStatus.ExtensionsOnly:
- default:
- // The NotApplicable (extension-only assertion) is NOT one that we support
- // in this control because that scenario is primarily interesting to RPs
- // that are asking a specific OP, and it is not user-initiated as this textbox
- // is designed for.
- throw new InvalidOperationException(MessagingStrings.UnexpectedMessageReceivedOfMany);
- }
- }
+ this.Page.RegisterRequiresPostBack(this);
+ base.OnLoad(e);
}
/// <summary>
- /// Prepares the text box to be rendered.
+ /// Called when the <see cref="Identifier"/> property is changed.
/// </summary>
- /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
- protected override void OnPreRender(EventArgs e) {
- base.OnPreRender(e);
+ protected override void OnIdentifierChanged() {
+ this.ViewState.Remove(TextViewStateKey);
+ base.OnIdentifierChanged();
+ }
+ /// <summary>
+ /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client.
+ /// </summary>
+ /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param>
+ protected override void Render(HtmlTextWriter writer) {
if (this.ShowLogo) {
string logoUrl = Page.ClientScript.GetWebResourceUrl(
typeof(OpenIdTextBox), EmbeddedLogoResourceName);
- this.WrappedTextBox.Style[HtmlTextWriterStyle.BackgroundImage] = string.Format(
- CultureInfo.InvariantCulture, "url({0})", HttpUtility.HtmlEncode(logoUrl));
- this.WrappedTextBox.Style["background-repeat"] = "no-repeat";
- this.WrappedTextBox.Style["background-position"] = "0 50%";
- this.WrappedTextBox.Style[HtmlTextWriterStyle.PaddingLeft] = "18px";
+ writer.AddStyleAttribute(
+ HtmlTextWriterStyle.BackgroundImage,
+ string.Format(CultureInfo.InvariantCulture, "url({0})", HttpUtility.HtmlEncode(logoUrl)));
+ writer.AddStyleAttribute("background-repeat", "no-repeat");
+ writer.AddStyleAttribute("background-position", "0 50%");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "18px");
}
if (this.PresetBorder) {
- this.WrappedTextBox.Style[HtmlTextWriterStyle.BorderStyle] = "solid";
- this.WrappedTextBox.Style[HtmlTextWriterStyle.BorderWidth] = "1px";
- this.WrappedTextBox.Style[HtmlTextWriterStyle.BorderColor] = "lightgray";
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
+ writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "lightgray");
}
- }
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool disposing) {
- if (disposing) {
- if (this.relyingParty != null) {
- this.relyingParty.Dispose();
- this.relyingParty = null;
- }
+ if (!string.IsNullOrEmpty(this.CssClass)) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
}
- }
- #region Events
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
+ writer.AddAttribute(HtmlTextWriterAttribute.Name, HttpUtility.HtmlEncode(this.Name));
+ writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
+ writer.AddAttribute(HtmlTextWriterAttribute.Size, this.Columns.ToString(CultureInfo.InvariantCulture));
+ writer.AddAttribute(HtmlTextWriterAttribute.Value, HttpUtility.HtmlEncode(this.Text));
+ writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, this.TabIndex.ToString(CultureInfo.CurrentCulture));
+
+ writer.RenderBeginTag(HtmlTextWriterTag.Input);
+ writer.RenderEndTag();
+ }
/// <summary>
- /// Fires the <see cref="LoggedIn"/> event.
+ /// When implemented by a class, processes postback data for an ASP.NET server control.
/// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnLoggedIn(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Authenticated, "Firing OnLoggedIn event without an authenticated response.");
-
- var loggedIn = this.LoggedIn;
- OpenIdEventArgs args = new OpenIdEventArgs(response);
- if (loggedIn != null) {
- loggedIn(this, args);
+ /// <param name="postDataKey">The key identifier for the control.</param>
+ /// <param name="postCollection">The collection of all incoming name values.</param>
+ /// <returns>
+ /// true if the server control's state changes as a result of the postback; otherwise, false.
+ /// </returns>
+ protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
+ // If the control was temporarily hidden, it won't be in the Form data,
+ // and we'll just implicitly keep the last Text setting.
+ if (postCollection[this.Name] != null) {
+ this.Text = postCollection[this.Name];
+ return true;
}
- if (!args.Cancel) {
- FormsAuthentication.RedirectFromLoginPage(response.ClaimedIdentifier, this.UsePersistentCookie);
- }
+ return false;
}
/// <summary>
- /// Fires the <see cref="Failed"/> event.
+ /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed.
/// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnFailed(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Failed, "Firing Failed event for the wrong response type.");
-
- var failed = this.Failed;
- if (failed != null) {
- failed(this, new OpenIdEventArgs(response));
- }
+ [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Preserve signature of interface we're implementing.")]
+ protected virtual void RaisePostDataChangedEvent() {
+ this.OnTextChanged();
}
/// <summary>
- /// Fires the <see cref="Canceled"/> event.
+ /// Called on a postback when the Text property has changed.
/// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnCanceled(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.Canceled, "Firing Canceled event for the wrong response type.");
-
- var canceled = this.Canceled;
- if (canceled != null) {
- canceled(this, new OpenIdEventArgs(response));
+ protected virtual void OnTextChanged() {
+ EventHandler textChanged = this.TextChanged;
+ if (textChanged != null) {
+ textChanged(this, EventArgs.Empty);
}
}
/// <summary>
- /// Fires the <see cref="SetupRequired"/> event.
+ /// Creates the authentication requests for a given user-supplied Identifier.
/// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnSetupRequired(IAuthenticationResponse response) {
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
- ErrorUtilities.VerifyInternal(response.Status == AuthenticationStatus.SetupRequired, "Firing SetupRequired event for the wrong response type.");
+ /// <param name="requests">The authentication requests to prepare.</param>
+ /// <returns>
+ /// A sequence of authentication requests, any one of which may be
+ /// used to determine the user's control of the <see cref="IAuthenticationRequest.ClaimedIdentifier"/>.
+ /// </returns>
+ private IEnumerable<IAuthenticationRequest> CreateRequestsCore(IEnumerable<IAuthenticationRequest> requests) {
+ Contract.Requires(requests != null);
+
+ foreach (var request in requests) {
+ if (this.EnableRequestProfile) {
+ this.AddProfileArgs(request);
+ }
- // Why are we firing Failed when we're OnSetupRequired? Backward compatibility.
- var setupRequired = this.SetupRequired;
- if (setupRequired != null) {
- setupRequired(this, new OpenIdEventArgs(response));
+ yield return request;
}
}
- #endregion
-
/// <summary>
/// Adds extensions to a given authentication request to ask the Provider
/// for user profile data.
/// </summary>
/// <param name="request">The authentication request to add the extensions to.</param>
private void AddProfileArgs(IAuthenticationRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
+ Contract.Requires<ArgumentNullException>(request != null);
- request.AddExtension(new ClaimsRequest() {
+ var sreg = new ClaimsRequest() {
Nickname = this.RequestNickname,
Email = this.RequestEmail,
FullName = this.RequestFullName,
@@ -1188,84 +693,12 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
TimeZone = this.RequestTimeZone,
PolicyUrl = string.IsNullOrEmpty(this.PolicyUrl) ?
null : new Uri(this.RelyingParty.Channel.GetRequestFromContext().UrlBeforeRewriting, this.Page.ResolveUrl(this.PolicyUrl)),
- });
- }
+ };
- /// <summary>
- /// Creates the relying party instance used to generate authentication requests.
- /// </summary>
- /// <returns>The instantiated relying party.</returns>
- private OpenIdRelyingParty CreateRelyingParty() {
- // If we're in stateful mode, first use the explicitly given one on this control if there
- // is one. Then try the configuration file specified one. Finally, use the default
- // in-memory one that's built into OpenIdRelyingParty.
- IRelyingPartyApplicationStore store = this.Stateless ? null :
- (this.CustomApplicationStore ?? DotNetOpenAuthSection.Configuration.OpenId.RelyingParty.ApplicationStore.CreateInstance(OpenIdRelyingParty.HttpApplicationStore));
- var rp = new OpenIdRelyingParty(store);
-
- // Only set RequireSsl to true, as we don't want to override
- // a .config setting of true with false.
- if (this.RequireSsl) {
- rp.SecuritySettings.RequireSsl = true;
+ // Only actually add the extension request if fields are actually being requested.
+ if (!sreg.Equals(EmptyClaimsRequest)) {
+ request.AddExtension(sreg);
}
- return rp;
- }
-
- /// <summary>
- /// Detects whether a popup window should be used to show the Provider's UI
- /// and applies the UI extension to the request when appropriate.
- /// </summary>
- /// <returns><c>true</c> if a popup should be used; <c>false</c> otherwise.</returns>
- private bool IsPopupAppropriate() {
- Contract.Requires(this.Request != null);
-
- switch (this.Popup) {
- case PopupBehavior.Never:
- return false;
- case PopupBehavior.Always:
- return true;
- case PopupBehavior.IfProviderSupported:
- return this.Request.Provider.IsExtensionSupported<UIRequest>();
- default:
- throw new InternalErrorException();
- }
- }
-
- /// <summary>
- /// Wires the return page to immediately display a popup window with the Provider in it.
- /// </summary>
- private void ScriptPopupWindow() {
- Contract.Requires(this.Request != null);
- Contract.Requires(this.RelyingParty != null);
-
- this.Request.AddCallbackArguments(UIPopupCallbackKey, "1");
-
- StringBuilder startupScript = new StringBuilder();
-
- // Add a callback function that the popup window can call on this, the
- // parent window, to pass back the authentication result.
- startupScript.AppendLine("window.dnoa_internal = new Object();");
- startupScript.AppendLine("window.dnoa_internal.processAuthorizationResult = function(uri) { window.location = uri; };");
-
- // Open the popup window.
- startupScript.AppendFormat(
- @"var openidPopup = {0}",
- UIUtilities.GetWindowPopupScript(this.RelyingParty, this.Request, "openidPopup"));
-
- this.Page.ClientScript.RegisterStartupScript(this.GetType(), "loginPopup", startupScript.ToString(), true);
- }
-
- /// <summary>
- /// Wires the popup window to close itself and pass the authentication result to the parent window.
- /// </summary>
- private void ScriptClosingPopup() {
- StringBuilder startupScript = new StringBuilder();
- startupScript.AppendLine("window.opener.dnoa_internal.processAuthorizationResult(document.URL + '&" + UIPopupCallbackParentKey + "=1');");
- startupScript.AppendLine("window.close();");
-
- // We're referencing the OpenIdRelyingPartyControlBase type here to avoid double-registering this script
- // if the other control exists on the page.
- this.Page.ClientScript.RegisterStartupScript(typeof(OpenIdRelyingPartyControlBase), "loginPopupClose", startupScript.ToString(), true);
}
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs
index baf30da..1bc306c 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAnonymousResponse.cs
@@ -33,8 +33,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </summary>
/// <param name="response">The response message.</param>
protected internal PositiveAnonymousResponse(IndirectSignedResponse response) {
- Contract.Requires(response != null);
- ErrorUtilities.VerifyArgumentNotNull(response, "response");
+ Contract.Requires<ArgumentNullException>(response != null);
this.response = response;
if (response.ProviderEndpoint != null && response.Version != null) {
@@ -272,7 +271,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// have not been tampered with since the Provider sent the message.</para>
/// </remarks>
public IOpenIdMessageExtension GetExtension(Type extensionType) {
- ErrorUtilities.VerifyArgumentNotNull(extensionType, "extensionType");
return this.response.SignedExtensions.OfType<IOpenIdMessageExtension>().Where(ext => extensionType.IsInstanceOfType(ext)).FirstOrDefault();
}
@@ -322,7 +320,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// have not been tampered with since the Provider sent the message.</para>
/// </remarks>
public IOpenIdMessageExtension GetUntrustedExtension(Type extensionType) {
- ErrorUtilities.VerifyArgumentNotNull(extensionType, "extensionType");
return this.response.Extensions.OfType<IOpenIdMessageExtension>().Where(ext => extensionType.IsInstanceOfType(ext)).FirstOrDefault();
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs
index 69a6eaa..e809205 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponse.cs
@@ -5,6 +5,7 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Linq;
@@ -19,27 +20,15 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
[DebuggerDisplay("Status: {Status}, ClaimedIdentifier: {ClaimedIdentifier}")]
internal class PositiveAuthenticationResponse : PositiveAnonymousResponse {
/// <summary>
- /// The OpenID service endpoint reconstructed from the assertion message.
- /// </summary>
- /// <remarks>
- /// This information is straight from the Provider, and therefore must not
- /// be trusted until verified as matching the discovery information for
- /// the claimed identifier to avoid a Provider asserting an Identifier
- /// for which it has no authority.
- /// </remarks>
- private readonly ServiceEndpoint endpoint;
-
- /// <summary>
/// Initializes a new instance of the <see cref="PositiveAuthenticationResponse"/> class.
/// </summary>
/// <param name="response">The positive assertion response that was just received by the Relying Party.</param>
/// <param name="relyingParty">The relying party.</param>
internal PositiveAuthenticationResponse(PositiveAssertionResponse response, OpenIdRelyingParty relyingParty)
: base(response) {
- Contract.Requires(relyingParty != null);
- ErrorUtilities.VerifyArgumentNotNull(relyingParty, "relyingParty");
+ Contract.Requires<ArgumentNullException>(relyingParty != null);
- this.endpoint = ServiceEndpoint.CreateForClaimedIdentifier(
+ this.Endpoint = ServiceEndpoint.CreateForClaimedIdentifier(
this.Response.ClaimedIdentifier,
this.Response.GetReturnToArgument(AuthenticationRequest.UserSuppliedIdentifierParameterName),
this.Response.LocalIdentifier,
@@ -69,7 +58,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </para>
/// </remarks>
public override Identifier ClaimedIdentifier {
- get { return this.endpoint.ClaimedIdentifier; }
+ get { return this.Endpoint.ClaimedIdentifier; }
}
/// <summary>
@@ -102,7 +91,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </para>
/// </remarks>
public override string FriendlyIdentifierForDisplay {
- get { return this.endpoint.FriendlyIdentifierForDisplay; }
+ get { return this.Endpoint.FriendlyIdentifierForDisplay; }
}
/// <summary>
@@ -115,6 +104,17 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
#endregion
/// <summary>
+ /// Gets the OpenID service endpoint reconstructed from the assertion message.
+ /// </summary>
+ /// <remarks>
+ /// This information is straight from the Provider, and therefore must not
+ /// be trusted until verified as matching the discovery information for
+ /// the claimed identifier to avoid a Provider asserting an Identifier
+ /// for which it has no authority.
+ /// </remarks>
+ internal ServiceEndpoint Endpoint { get; private set; }
+
+ /// <summary>
/// Gets the positive assertion response message.
/// </summary>
protected internal new PositiveAssertionResponse Response {
@@ -155,9 +155,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
// is merely a hint that must be verified by performing discovery again here.
var discoveryResults = claimedId.Discover(relyingParty.WebRequestHandler);
ErrorUtilities.VerifyProtocol(
- discoveryResults.Contains(this.endpoint),
+ discoveryResults.Contains(this.Endpoint),
OpenIdStrings.IssuedAssertionFailsIdentifierDiscovery,
- this.endpoint,
+ this.Endpoint,
discoveryResults.ToStringDeferred(true));
}
}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationResponseSnapshot.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs
index 973687f..32c8af9 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationResponseSnapshot.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PositiveAuthenticationResponseSnapshot.cs
@@ -1,5 +1,5 @@
//-----------------------------------------------------------------------
-// <copyright file="AuthenticationResponseSnapshot.cs" company="Andrew Arnott">
+// <copyright file="PositiveAuthenticationResponseSnapshot.cs" company="Andrew Arnott">
// Copyright (c) Andrew Arnott. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Text;
using System.Web;
using DotNetOpenAuth.Messaging;
@@ -16,7 +17,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// A serializable snapshot of a verified authentication message.
/// </summary>
[Serializable]
- internal class AuthenticationResponseSnapshot : IAuthenticationResponse {
+ internal class PositiveAuthenticationResponseSnapshot : IAuthenticationResponse {
/// <summary>
/// The callback arguments that came with the authentication response.
/// </summary>
@@ -28,11 +29,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
private IDictionary<string, string> untrustedCallbackArguments;
/// <summary>
- /// Initializes a new instance of the <see cref="AuthenticationResponseSnapshot"/> class.
+ /// Initializes a new instance of the <see cref="PositiveAuthenticationResponseSnapshot"/> class.
/// </summary>
/// <param name="copyFrom">The authentication response to copy from.</param>
- internal AuthenticationResponseSnapshot(IAuthenticationResponse copyFrom) {
- ErrorUtilities.VerifyArgumentNotNull(copyFrom, "copyFrom");
+ internal PositiveAuthenticationResponseSnapshot(IAuthenticationResponse copyFrom) {
+ Contract.Requires<ArgumentNullException>(copyFrom != null);
this.ClaimedIdentifier = copyFrom.ClaimedIdentifier;
this.FriendlyIdentifierForDisplay = copyFrom.FriendlyIdentifierForDisplay;
@@ -266,8 +267,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <para>Note that these values are NOT protected against tampering in transit.</para>
/// </remarks>
public string GetCallbackArgument(string key) {
- ErrorUtilities.VerifyArgumentNotNull(key, "key");
-
string value;
this.callbackArguments.TryGetValue(key, out value);
return value;
@@ -288,8 +287,6 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// used to make a security-sensitive decision.
/// </remarks>
public string GetUntrustedCallbackArgument(string key) {
- ErrorUtilities.VerifyArgumentNotNull(key, "key");
-
string value;
this.untrustedCallbackArguments.TryGetValue(key, out value);
return value;
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs
index 0895d77..6d55e39 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/PrivateSecretManager.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Configuration;
using DotNetOpenAuth.Messaging;
@@ -43,8 +44,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="securitySettings">The security settings.</param>
/// <param name="store">The association store.</param>
internal PrivateSecretManager(RelyingPartySecuritySettings securitySettings, IAssociationStore<Uri> store) {
- ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
- ErrorUtilities.VerifyArgumentNotNull(store, "store");
+ Contract.Requires<ArgumentNullException>(securitySettings != null);
+ Contract.Requires<ArgumentNullException>(store != null);
this.securitySettings = securitySettings;
this.store = store;
@@ -74,8 +75,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <exception cref="ProtocolException">Thrown when an association with the given handle could not be found.
/// This most likely happens if the association was near the end of its life and the user took too long to log in.</exception>
internal byte[] Sign(byte[] buffer, string handle) {
- ErrorUtilities.VerifyArgumentNotNull(buffer, "buffer");
- ErrorUtilities.VerifyNonZeroLength(handle, "handle");
+ Contract.Requires<ArgumentNullException>(buffer != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(handle));
Association association = this.store.GetAssociation(SecretUri, handle);
ErrorUtilities.VerifyProtocol(association != null, OpenIdStrings.PrivateRPSecretNotFound, handle);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButton.cs
new file mode 100644
index 0000000..0be3a5f
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButton.cs
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------
+// <copyright file="SelectorButton.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Web.UI;
+
+ /// <summary>
+ /// A button that would appear in the <see cref="OpenIdSelector"/> control via its <see cref="OpenIdSelector.Buttons"/> collection.
+ /// </summary>
+ [ContractClass(typeof(SelectorButtonContract))]
+ public abstract class SelectorButton {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SelectorButton"/> class.
+ /// </summary>
+ protected SelectorButton() {
+ }
+
+ /// <summary>
+ /// Ensures that this button has been initialized to a valid state.
+ /// </summary>
+ /// <remarks>
+ /// This is "internal" -- NOT "protected internal" deliberately. It makes it impossible
+ /// to derive from this class outside the assembly, which suits our purposes since the
+ /// <see cref="OpenIdSelector"/> control is not designed for an extensible set of button types.
+ /// </remarks>
+ internal abstract void EnsureValid();
+
+ /// <summary>
+ /// Renders the leading attributes for the LI tag.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ protected internal abstract void RenderLeadingAttributes(HtmlTextWriter writer);
+
+ /// <summary>
+ /// Renders the content of the button.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="selector">The containing selector control.</param>
+ protected internal abstract void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector);
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButtonContract.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButtonContract.cs
new file mode 100644
index 0000000..c70218a
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorButtonContract.cs
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------
+// <copyright file="SelectorButtonContract.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Web.UI;
+
+ /// <summary>
+ /// The contract class for the <see cref="SelectorButton"/> class.
+ /// </summary>
+ [ContractClassFor(typeof(SelectorButton))]
+ internal abstract class SelectorButtonContract : SelectorButton {
+ /// <summary>
+ /// Ensures that this button has been initialized to a valid state.
+ /// </summary>
+ /// <remarks>
+ /// This is "internal" -- NOT "protected internal" deliberately. It makes it impossible
+ /// to derive from this class outside the assembly, which suits our purposes since the
+ /// <see cref="OpenIdSelector"/> control is not designed for an extensible set of button types.
+ /// </remarks>
+ internal override void EnsureValid() {
+ }
+
+ /// <summary>
+ /// Renders the leading attributes for the LI tag.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
+ Contract.Requires<ArgumentNullException>(writer != null);
+ }
+
+ /// <summary>
+ /// Renders the content of the button.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="selector">The containing selector control.</param>
+ protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
+ Contract.Requires<ArgumentNullException>(writer != null);
+ Contract.Requires<ArgumentNullException>(selector != null);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorInfoCardButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorInfoCardButton.cs
new file mode 100644
index 0000000..8fac58f
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorInfoCardButton.cs
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------
+// <copyright file="SelectorInfoCardButton.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System.Web.UI;
+
+ /// <summary>
+ /// A button that appears in the <see cref="OpenIdSelector"/> control that
+ /// activates the Information Card selector on the browser, if one is available.
+ /// </summary>
+ public class SelectorInfoCardButton : SelectorButton {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SelectorInfoCardButton"/> class.
+ /// </summary>
+ public SelectorInfoCardButton() {
+ }
+
+ /// <summary>
+ /// Ensures that this button has been initialized to a valid state.
+ /// </summary>
+ internal override void EnsureValid() {
+ }
+
+ /// <summary>
+ /// Renders the leading attributes for the LI tag.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "infocard");
+ }
+
+ /// <summary>
+ /// Renders the content of the button.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="selector">The containing selector control.</param>
+ protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
+ selector.InfoCardSelector.RenderControl(writer);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorOpenIdButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorOpenIdButton.cs
new file mode 100644
index 0000000..3e499af
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorOpenIdButton.cs
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------
+// <copyright file="SelectorOpenIdButton.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System.Diagnostics.Contracts;
+ using System.Web.UI;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// A button that appears in the <see cref="OpenIdSelector"/> control that
+ /// allows the user to type in a user-supplied identifier.
+ /// </summary>
+ public class SelectorOpenIdButton : SelectorButton {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SelectorOpenIdButton"/> class.
+ /// </summary>
+ public SelectorOpenIdButton() {
+ }
+
+ /// <summary>
+ /// Gets or sets the path to the image to display on the button's surface.
+ /// </summary>
+ /// <value>The virtual path to the image.</value>
+ public string Image { get; set; }
+
+ /// <summary>
+ /// Ensures that this button has been initialized to a valid state.
+ /// </summary>
+ internal override void EnsureValid() {
+ Contract.Ensures(!string.IsNullOrEmpty(this.Image));
+
+ // Every button must have an image.
+ ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Image), OpenIdStrings.PropertyNotSet, "SelectorButton.Image");
+ }
+
+ /// <summary>
+ /// Renders the leading attributes for the LI tag.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, "OpenIDButton");
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIDButton");
+ }
+
+ /// <summary>
+ /// Renders the content of the button.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="selector">The containing selector control.</param>
+ protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Image);
+ writer.RenderBeginTag(HtmlTextWriterTag.Img);
+ writer.RenderEndTag();
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ClientScript.GetWebResourceUrl(typeof(OpenIdAjaxTextBox), OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, selector.AuthenticatedAsToolTip);
+ writer.RenderBeginTag(HtmlTextWriterTag.Img);
+ writer.RenderEndTag();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorProviderButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorProviderButton.cs
new file mode 100644
index 0000000..6818d57
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/SelectorProviderButton.cs
@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------
+// <copyright file="SelectorProviderButton.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.RelyingParty {
+ using System.ComponentModel;
+ using System.Diagnostics.Contracts;
+ using System.Web.UI;
+ using DotNetOpenAuth.ComponentModel;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// A button that appears in the <see cref="OpenIdSelector"/> control that
+ /// provides one-click access to a popular OpenID Provider.
+ /// </summary>
+ public class SelectorProviderButton : SelectorButton {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SelectorProviderButton"/> class.
+ /// </summary>
+ public SelectorProviderButton() {
+ }
+
+ /// <summary>
+ /// Gets or sets the path to the image to display on the button's surface.
+ /// </summary>
+ /// <value>The virtual path to the image.</value>
+ public string Image { get; set; }
+
+ /// <summary>
+ /// Gets or sets the OP Identifier represented by the button.
+ /// </summary>
+ /// <value>
+ /// The OP identifier, which may be provided in the easiest "user-supplied identifier" form,
+ /// but for security should be provided with a leading https:// if possible.
+ /// For example: "yahoo.com" or "https://me.yahoo.com/".
+ /// </value>
+ [TypeConverter(typeof(IdentifierConverter))]
+ public Identifier OPIdentifier { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this Provider doesn't handle
+ /// checkid_immediate messages correctly and background authentication
+ /// should not be attempted.
+ /// </summary>
+ public bool SkipBackgroundAuthentication { get; set; }
+
+ /// <summary>
+ /// Ensures that this button has been initialized to a valid state.
+ /// </summary>
+ internal override void EnsureValid() {
+ Contract.Ensures(!string.IsNullOrEmpty(this.Image));
+ Contract.Ensures(this.OPIdentifier != null);
+
+ // Every button must have an image.
+ ErrorUtilities.VerifyOperation(!string.IsNullOrEmpty(this.Image), OpenIdStrings.PropertyNotSet, "SelectorButton.Image");
+
+ // Every button must have exactly one purpose.
+ ErrorUtilities.VerifyOperation(this.OPIdentifier != null, OpenIdStrings.PropertyNotSet, "SelectorButton.OPIdentifier");
+ }
+
+ /// <summary>
+ /// Renders the leading attributes for the LI tag.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ protected internal override void RenderLeadingAttributes(HtmlTextWriter writer) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, this.OPIdentifier);
+
+ string style = "OPButton";
+ if (this.SkipBackgroundAuthentication) {
+ style += " NoAsyncAuth";
+ }
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, style);
+ }
+
+ /// <summary>
+ /// Renders the content of the button.
+ /// </summary>
+ /// <param name="writer">The writer.</param>
+ /// <param name="selector">The containing selector control.</param>
+ protected internal override void RenderButtonContent(HtmlTextWriter writer, OpenIdSelector selector) {
+ writer.AddAttribute(HtmlTextWriterAttribute.Src, this.Image);
+ writer.RenderBeginTag(HtmlTextWriterTag.Img);
+ writer.RenderEndTag();
+
+ writer.AddAttribute(HtmlTextWriterAttribute.Src, selector.Page.ClientScript.GetWebResourceUrl(typeof(OpenIdAjaxTextBox), OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName));
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess");
+ writer.AddAttribute(HtmlTextWriterAttribute.Title, selector.AuthenticatedAsToolTip);
+ writer.RenderBeginTag(HtmlTextWriterTag.Img);
+ writer.RenderEndTag();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
index 88264f5..8cf445d 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/ServiceEndpoint.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
+ using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -57,8 +58,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <param name="servicePriority">The service priority.</param>
/// <param name="uriPriority">The URI priority.</param>
private ServiceEndpoint(ProviderEndpointDescription providerEndpoint, Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, int? servicePriority, int? uriPriority) {
- ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
+ Contract.Requires<ArgumentNullException>(claimedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
this.ProviderDescription = providerEndpoint;
this.ClaimedIdentifier = claimedIdentifier;
this.UserSuppliedIdentifier = userSuppliedIdentifier;
@@ -79,10 +80,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// Used for deserializing <see cref="ServiceEndpoint"/> from authentication responses.
/// </remarks>
private ServiceEndpoint(Uri providerEndpoint, Identifier claimedIdentifier, Identifier userSuppliedIdentifier, Identifier providerLocalIdentifier, Protocol protocol) {
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
- ErrorUtilities.VerifyArgumentNotNull(claimedIdentifier, "claimedIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(providerLocalIdentifier, "providerLocalIdentifier");
- ErrorUtilities.VerifyArgumentNotNull(protocol, "protocol");
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
+ Contract.Requires<ArgumentNullException>(claimedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(providerLocalIdentifier != null);
+ Contract.Requires<ArgumentNullException>(protocol != null);
this.ClaimedIdentifier = claimedIdentifier;
this.UserSuppliedIdentifier = userSuppliedIdentifier;
@@ -427,13 +428,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// <summary>
/// Creates a <see cref="ServiceEndpoint"/> instance to represent some OP Identifier.
/// </summary>
- /// <param name="providerIdentifier">The provider identifier.</param>
+ /// <param name="providerIdentifier">The provider identifier (actually the user-supplied identifier).</param>
/// <param name="providerEndpoint">The provider endpoint.</param>
/// <param name="servicePriority">The service priority.</param>
/// <param name="uriPriority">The URI priority.</param>
/// <returns>The created <see cref="ServiceEndpoint"/> instance</returns>
internal static ServiceEndpoint CreateForProviderIdentifier(Identifier providerIdentifier, ProviderEndpointDescription providerEndpoint, int? servicePriority, int? uriPriority) {
- ErrorUtilities.VerifyArgumentNotNull(providerEndpoint, "providerEndpoint");
+ Contract.Requires<ArgumentNullException>(providerEndpoint != null);
Protocol protocol = Protocol.Detect(providerEndpoint.Capabilities);
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/WellKnownProviders.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/WellKnownProviders.cs
index 2e2ab61..ad1a11a 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/WellKnownProviders.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/WellKnownProviders.cs
@@ -30,6 +30,20 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
public static readonly Identifier MyOpenId = "https://www.myopenid.com/";
/// <summary>
+ /// The Verisign OP Identifier.
+ /// </summary>
+ [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Verisign", Justification = "The spelling is correct.")]
+ [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Immutable type")]
+ public static readonly Identifier Verisign = "https://pip.verisignlabs.com/";
+
+ /// <summary>
+ /// The MyVidoop OP Identifier.
+ /// </summary>
+ [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Vidoop", Justification = "The spelling is correct.")]
+ [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Immutable type")]
+ public static readonly Identifier MyVidoop = "https://myvidoop.com/";
+
+ /// <summary>
/// Prevents a default instance of the <see cref="WellKnownProviders"/> class from being created.
/// </summary>
private WellKnownProviders() {
diff --git a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
index 6b82966..279ca30 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs
@@ -7,6 +7,7 @@
namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
+ using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using DotNetOpenAuth.Messaging;
@@ -26,8 +27,8 @@ namespace DotNetOpenAuth.OpenId {
/// The Type URIs of supported services advertised on a relying party's XRDS document.
/// </param>
internal RelyingPartyEndpointDescription(Uri returnTo, string[] supportedServiceTypeUris) {
- ErrorUtilities.VerifyArgumentNotNull(returnTo, "returnTo");
- ErrorUtilities.VerifyArgumentNotNull(supportedServiceTypeUris, "supportedServiceTypeUris");
+ Contract.Requires<ArgumentNullException>(returnTo != null);
+ Contract.Requires<ArgumentNullException>(supportedServiceTypeUris != null);
this.ReturnToEndpoint = returnTo;
this.Protocol = GetProtocolFromServices(supportedServiceTypeUris);
diff --git a/src/DotNetOpenAuth/OpenId/SecuritySettings.cs b/src/DotNetOpenAuth/OpenId/SecuritySettings.cs
index d4df697..26f6d2a 100644
--- a/src/DotNetOpenAuth/OpenId/SecuritySettings.cs
+++ b/src/DotNetOpenAuth/OpenId/SecuritySettings.cs
@@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OpenId {
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
+ using System.Diagnostics.Contracts;
using DotNetOpenAuth.Messaging;
/// <summary>
@@ -87,7 +88,7 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the association is permitted given the security requirements; otherwise, <c>false</c>.
/// </returns>
internal bool IsAssociationInPermittedRange(Association association) {
- ErrorUtilities.VerifyArgumentNotNull(association, "association");
+ Contract.Requires<ArgumentNullException>(association != null);
return association.HashBitLength >= this.MinimumHashBitLength && association.HashBitLength <= this.MaximumHashBitLength;
}
}
diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
index 512200d..28d8b37 100644
--- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs
@@ -35,6 +35,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="uri">The value this identifier will represent.</param>
internal UriIdentifier(string uri)
: this(uri, false) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(uri));
}
/// <summary>
@@ -43,8 +44,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="uri">The value this identifier will represent.</param>
/// <param name="requireSslDiscovery">if set to <c>true</c> [require SSL discovery].</param>
internal UriIdentifier(string uri, bool requireSslDiscovery)
- : base(requireSslDiscovery) {
- ErrorUtilities.VerifyNonZeroLength(uri, "uri");
+ : base(uri, requireSslDiscovery) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(uri));
Uri canonicalUri;
bool schemePrepended;
if (!TryCanonicalize(uri, out canonicalUri, requireSslDiscovery, out schemePrepended)) {
@@ -70,8 +71,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="uri">The value this identifier will represent.</param>
/// <param name="requireSslDiscovery">if set to <c>true</c> [require SSL discovery].</param>
internal UriIdentifier(Uri uri, bool requireSslDiscovery)
- : base(requireSslDiscovery) {
- ErrorUtilities.VerifyArgumentNotNull(uri, "uri");
+ : base(uri != null ? uri.OriginalString : null, requireSslDiscovery) {
+ Contract.Requires<ArgumentNullException>(uri != null);
if (!TryCanonicalize(new UriBuilder(uri), out uri)) {
throw new UriFormatException();
}
@@ -416,8 +417,7 @@ namespace DotNetOpenAuth.OpenId {
/// require network access are also done, such as lower-casing the hostname in the URI.
/// </remarks>
private static bool TryCanonicalize(string uri, out Uri canonicalUri, bool forceHttpsDefaultScheme, out bool schemePrepended) {
- Contract.Requires(!string.IsNullOrEmpty(uri));
- ErrorUtilities.VerifyNonZeroLength(uri, "uri");
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(uri));
uri = uri.Trim();
canonicalUri = null;
@@ -462,6 +462,7 @@ namespace DotNetOpenAuth.OpenId {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
private void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
index c659982..9bcb9cf 100644
--- a/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
+++ b/src/DotNetOpenAuth/OpenId/XriIdentifier.cs
@@ -62,7 +62,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="xri">The string value of the XRI.</param>
internal XriIdentifier(string xri)
: this(xri, false) {
- Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri));
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(xri));
+ Contract.Requires<FormatException>(IsValidXri(xri), OpenIdStrings.InvalidXri);
}
/// <summary>
@@ -74,9 +75,9 @@ namespace DotNetOpenAuth.OpenId {
/// only succeed if it can be done entirely using SSL.
/// </param>
internal XriIdentifier(string xri, bool requireSsl)
- : base(requireSsl) {
- Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri));
- ErrorUtilities.VerifyFormat(IsValidXri(xri), OpenIdStrings.InvalidXri, xri);
+ : base(xri, requireSsl) {
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(xri));
+ Contract.Requires<FormatException>(IsValidXri(xri), OpenIdStrings.InvalidXri);
Contract.Assume(xri != null); // Proven by IsValidXri
this.xriResolverProxy = XriResolverProxyTemplate;
if (requireSsl) {
@@ -167,8 +168,7 @@ namespace DotNetOpenAuth.OpenId {
/// <c>true</c> if the given string constitutes a valid XRI; otherwise, <c>false</c>.
/// </returns>
internal static bool IsValidXri(string xri) {
- Contract.Requires((xri != null && xri.Length > 0) || !string.IsNullOrEmpty(xri));
- ErrorUtilities.VerifyNonZeroLength(xri, "xri");
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(xri));
xri = xri.Trim();
// TODO: better validation code here
@@ -196,8 +196,8 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="userSuppliedIdentifier">The user supplied identifier, which may differ from this XRI instance due to multiple discovery steps.</param>
/// <returns>A list of service endpoints offered for this identifier.</returns>
internal IEnumerable<ServiceEndpoint> Discover(IDirectWebRequestHandler requestHandler, XriIdentifier userSuppliedIdentifier) {
- Contract.Requires(requestHandler != null);
- Contract.Requires(userSuppliedIdentifier != null);
+ Contract.Requires<ArgumentNullException>(requestHandler != null);
+ Contract.Requires<ArgumentNullException>(userSuppliedIdentifier != null);
return this.DownloadXrds(requestHandler).CreateServiceEndpoints(userSuppliedIdentifier);
}
@@ -243,7 +243,7 @@ namespace DotNetOpenAuth.OpenId {
/// <returns>The canonicalized form of the XRI.</returns>
/// <remarks>The canonical form, per the OpenID spec, is no scheme and no whitespace on either end.</remarks>
private static string CanonicalizeXri(string xri) {
- Contract.Requires(xri != null);
+ Contract.Requires<ArgumentNullException>(xri != null);
Contract.Ensures(Contract.Result<string>() != null);
xri = xri.Trim();
if (xri.StartsWith(XriScheme, StringComparison.OrdinalIgnoreCase)) {
@@ -259,7 +259,7 @@ namespace DotNetOpenAuth.OpenId {
/// <param name="requestHandler">The request handler.</param>
/// <returns>The XRDS document.</returns>
private XrdsDocument DownloadXrds(IDirectWebRequestHandler requestHandler) {
- Contract.Requires(requestHandler != null);
+ Contract.Requires<ArgumentNullException>(requestHandler != null);
Contract.Ensures(Contract.Result<XrdsDocument>() != null);
XrdsDocument doc;
using (var xrdsResponse = Yadis.Request(requestHandler, this.XrdsUrl, this.IsDiscoverySecureEndToEnd)) {
@@ -273,6 +273,7 @@ namespace DotNetOpenAuth.OpenId {
/// <summary>
/// Verifies conditions that should be true for any valid state of this object.
/// </summary>
+ [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Called by code contracts.")]
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")]
[ContractInvariantMethod]
private void ObjectInvariant() {
diff --git a/src/DotNetOpenAuth/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth/Properties/AssemblyInfo.cs
index 69d4dc4..51d146c 100644
--- a/src/DotNetOpenAuth/Properties/AssemblyInfo.cs
+++ b/src/DotNetOpenAuth/Properties/AssemblyInfo.cs
@@ -58,7 +58,7 @@ using System.Web.UI;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7d73990c-47c0-4256-9f20-a893add9e289")]
-[assembly: ContractVerification(false)]
+[assembly: ContractVerification(true)]
#if StrongNameSigned
// See comment at top of this file. We need this so that strong-naming doesn't
diff --git a/src/DotNetOpenAuth/Strings.sr.resx b/src/DotNetOpenAuth/Strings.sr.resx
new file mode 100644
index 0000000..5112265
--- /dev/null
+++ b/src/DotNetOpenAuth/Strings.sr.resx
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="ConfigurationTypeMustBePublic" xml:space="preserve">
+ <value>Konfiguraciono zavisni tip {0} mora biti javan, a on to nije.</value>
+ </data>
+ <data name="ConfigurationXamlReferenceRequiresHttpContext" xml:space="preserve">
+ <value>Konfiguraciona XAML referenca na {0} zahteva da se trenutni HttpContext razreši.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/UriUtil.cs b/src/DotNetOpenAuth/UriUtil.cs
index d04491d..819c406 100644
--- a/src/DotNetOpenAuth/UriUtil.cs
+++ b/src/DotNetOpenAuth/UriUtil.cs
@@ -30,8 +30,7 @@ namespace DotNetOpenAuth {
/// </returns>
[ContractVerification(false)] // bugs/limitations in CC static analysis
internal static bool QueryStringContainPrefixedParameters(this Uri uri, string prefix) {
- Contract.Requires(prefix != null && prefix.Length > 0);
- ErrorUtilities.VerifyNonZeroLength(prefix, "prefix");
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(prefix));
if (uri == null) {
return false;
}
@@ -49,10 +48,7 @@ namespace DotNetOpenAuth {
/// <c>true</c> if the URI represents an encrypted request; otherwise, <c>false</c>.
/// </returns>
internal static bool IsTransportSecure(this Uri uri) {
- if (uri == null) {
- throw new ArgumentNullException("uri");
- }
-
+ Contract.Requires<ArgumentNullException>(uri != null);
return string.Equals(uri.Scheme, "https", StringComparison.OrdinalIgnoreCase);
}
@@ -63,9 +59,8 @@ namespace DotNetOpenAuth {
/// <param name="builder">The UriBuilder to render as a string.</param>
/// <returns>The string version of the Uri.</returns>
internal static string ToStringWithImpliedPorts(this UriBuilder builder) {
- Contract.Requires(builder != null);
+ Contract.Requires<ArgumentNullException>(builder != null);
Contract.Ensures(Contract.Result<string>() != null);
- ErrorUtilities.VerifyArgumentNotNull(builder, "builder");
// We only check for implied ports on HTTP and HTTPS schemes since those
// are the only ones supported by OpenID anyway.
diff --git a/src/DotNetOpenAuth/Util.cs b/src/DotNetOpenAuth/Util.cs
index 1a67966..9f8b30c 100644
--- a/src/DotNetOpenAuth/Util.cs
+++ b/src/DotNetOpenAuth/Util.cs
@@ -11,6 +11,7 @@ namespace DotNetOpenAuth {
using System.Net;
using System.Reflection;
using System.Text;
+ using DotNetOpenAuth.Messaging;
/// <summary>
/// A grab-bag utility class.
@@ -74,7 +75,8 @@ namespace DotNetOpenAuth {
return new DelayedToString<IEnumerable<KeyValuePair<K, V>>>(
pairs,
p => {
- Contract.Requires(pairs != null);
+ ////Contract.Requires(pairs != null); // CC: anonymous method can't handle it
+ ErrorUtilities.VerifyArgumentNotNull(pairs, "pairs");
var dictionary = pairs as IDictionary<K, V>;
StringBuilder sb = new StringBuilder(dictionary != null ? dictionary.Count * 40 : 200);
foreach (var pair in pairs) {
@@ -102,13 +104,16 @@ namespace DotNetOpenAuth {
/// <param name="list">The list of elements.</param>
/// <param name="multiLineElements">if set to <c>true</c>, special formatting will be applied to the output to make it clear where one element ends and the next begins.</param>
/// <returns>An object whose ToString method will perform the actual work of generating the string.</returns>
+ [ContractVerification(false)]
internal static object ToStringDeferred<T>(this IEnumerable<T> list, bool multiLineElements) {
return new DelayedToString<IEnumerable<T>>(
list,
l => {
- Contract.Requires(l != null);
+ // Code contracts not allowed in generator methods.
+ ErrorUtilities.VerifyArgumentNotNull(l, "l");
+
string newLine = Environment.NewLine;
- Contract.Assume(newLine != null && newLine.Length > 0);
+ ////Contract.Assume(newLine != null && newLine.Length > 0);
StringBuilder sb = new StringBuilder();
if (multiLineElements) {
sb.AppendLine("[{");
@@ -169,7 +174,7 @@ namespace DotNetOpenAuth {
/// <param name="obj">The object that may be serialized to string form.</param>
/// <param name="toString">The method that will serialize the object if called upon.</param>
public DelayedToString(T obj, Func<T, string> toString) {
- Contract.Requires(toString != null);
+ Contract.Requires<ArgumentNullException>(toString != null);
this.obj = obj;
this.toString = toString;
diff --git a/src/DotNetOpenAuth/Xrds/XrdsNode.cs b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
index e27a1b2..5e7d7e7 100644
--- a/src/DotNetOpenAuth/Xrds/XrdsNode.cs
+++ b/src/DotNetOpenAuth/Xrds/XrdsNode.cs
@@ -5,6 +5,8 @@
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Xrds {
+ using System;
+ using System.Diagnostics.Contracts;
using System.Xml;
using System.Xml.XPath;
using DotNetOpenAuth.Messaging;
@@ -29,8 +31,8 @@ namespace DotNetOpenAuth.Xrds {
/// <param name="node">The node represented by this instance.</param>
/// <param name="parentNode">The parent node.</param>
protected XrdsNode(XPathNavigator node, XrdsNode parentNode) {
- ErrorUtilities.VerifyArgumentNotNull(node, "node");
- ErrorUtilities.VerifyArgumentNotNull(parentNode, "parentNode");
+ Contract.Requires<ArgumentNullException>(node != null);
+ Contract.Requires<ArgumentNullException>(parentNode != null);
this.Node = node;
this.ParentNode = parentNode;
@@ -42,7 +44,7 @@ namespace DotNetOpenAuth.Xrds {
/// </summary>
/// <param name="document">The document's root node, which this instance represents.</param>
protected XrdsNode(XPathNavigator document) {
- ErrorUtilities.VerifyArgumentNotNull(document, "document");
+ Contract.Requires<ArgumentNullException>(document != null);
this.Node = document;
this.XmlNamespaceResolver = new XmlNamespaceManager(document.NameTable);
diff --git a/src/DotNetOpenAuth/Xrds/XrdsStrings.sr.resx b/src/DotNetOpenAuth/Xrds/XrdsStrings.sr.resx
new file mode 100644
index 0000000..8e2d09a
--- /dev/null
+++ b/src/DotNetOpenAuth/Xrds/XrdsStrings.sr.resx
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="CIDVerificationFailed" xml:space="preserve">
+ <value>XRI CanonicalID provera neuspešna.</value>
+ </data>
+ <data name="InvalidXRDSDocument" xml:space="preserve">
+ <value>Greška u obradi XRDS dokumenta.</value>
+ </data>
+ <data name="MissingCanonicalIDElement" xml:space="preserve">
+ <value>XRDS dokumentu za XRI {0} nedostaje neophodni CanonicalID element.</value>
+ </data>
+ <data name="XriResolutionStatusMissing" xml:space="preserve">
+ <value>Ne može se pronaći XRI resolution Status tag ili je code attribute neispravan.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/DotNetOpenAuth/Yadis/HtmlParser.cs b/src/DotNetOpenAuth/Yadis/HtmlParser.cs
index 406cb4b..a6b64c1 100644
--- a/src/DotNetOpenAuth/Yadis/HtmlParser.cs
+++ b/src/DotNetOpenAuth/Yadis/HtmlParser.cs
@@ -98,8 +98,8 @@ namespace DotNetOpenAuth.Yadis {
/// <param name="attribute">The attribute.</param>
/// <returns>A filtered sequence of attributes.</returns>
internal static IEnumerable<T> WithAttribute<T>(this IEnumerable<T> sequence, string attribute) where T : HtmlControl {
- Contract.Requires(sequence != null);
- Contract.Requires(!String.IsNullOrEmpty(attribute));
+ Contract.Requires<ArgumentNullException>(sequence != null);
+ Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(attribute));
return sequence.Where(tag => tag.Attributes[attribute] != null);
}
diff --git a/src/DotNetOpenAuth/Yadis/Yadis.cs b/src/DotNetOpenAuth/Yadis/Yadis.cs
index 14aea62..a9a573b 100644
--- a/src/DotNetOpenAuth/Yadis/Yadis.cs
+++ b/src/DotNetOpenAuth/Yadis/Yadis.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.Yadis {
using System;
+ using System.Diagnostics.Contracts;
using System.IO;
using System.Net;
using System.Net.Cache;
@@ -132,8 +133,8 @@ namespace DotNetOpenAuth.Yadis {
/// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param>
/// <returns>The HTTP response retrieved from the request.</returns>
internal static IncomingWebResponse Request(IDirectWebRequestHandler requestHandler, Uri uri, bool requireSsl, params string[] acceptTypes) {
- ErrorUtilities.VerifyArgumentNotNull(requestHandler, "requestHandler");
- ErrorUtilities.VerifyArgumentNotNull(uri, "uri");
+ Contract.Requires<ArgumentNullException>(requestHandler != null);
+ Contract.Requires<ArgumentNullException>(uri != null);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.CachePolicy = IdentifierDiscoveryCachePolicy;
diff --git a/src/official-build-key.pub b/src/official-build-key.pub
new file mode 100644
index 0000000..6e68f53
--- /dev/null
+++ b/src/official-build-key.pub
Binary files differ
diff --git a/src/version.txt b/src/version.txt
index b347b11..15a2799 100644
--- a/src/version.txt
+++ b/src/version.txt
@@ -1 +1 @@
-3.2.3
+3.3.0
diff --git a/tools/DotNetOpenAuth.Common.Settings.targets b/tools/DotNetOpenAuth.Common.Settings.targets
index 3257583..363fd27 100644
--- a/tools/DotNetOpenAuth.Common.Settings.targets
+++ b/tools/DotNetOpenAuth.Common.Settings.targets
@@ -1,11 +1,24 @@
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="InitializeProps">
<PropertyGroup>
<ProductName>DotNetOpenAuth</ProductName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)</ProjectRoot>
- <OutputPath>$(ProjectRoot)\bin\$(Configuration)</OutputPath>
- <DocOutputPath>$(ProjectRoot)\doc</DocOutputPath>
- <IntermediatePath>$(ProjectRoot)\obj\$(Configuration)</IntermediatePath>
- <ToolsDir>$(ProjectRoot)\tools</ToolsDir>
+ <DropsRoot>$(ProjectRoot)\drops\$(Configuration)\</DropsRoot>
+ <OutputPath>$(ProjectRoot)\bin\$(Configuration)\</OutputPath>
+ <DocOutputPath>$(ProjectRoot)\doc\</DocOutputPath>
+ <IntermediatePath>$(ProjectRoot)\obj\$(Configuration)\</IntermediatePath>
+ <ToolsDir>$(ProjectRoot)\tools\</ToolsDir>
+ <PublicKeyFile>$(ProjectRoot)\src\official-build-key.pub</PublicKeyFile>
+ <KeyPairContainer Condition="'$(KeyPairContainer)' == ''">DotNetOpenAuth</KeyPairContainer>
+ <PublicKeyToken>2780CCD10D57B246</PublicKeyToken>
</PropertyGroup>
-</Project> \ No newline at end of file
+
+ <Import Project="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.targets" />
+
+ <Target Name="InitializeProps">
+ <CheckAdminRights>
+ <Output TaskParameter="IsElevated" PropertyName="IsElevated" />
+ </CheckAdminRights>
+ <Message Importance="High" Text="IsElevated = $(IsElevated)" />
+ </Target>
+</Project>
diff --git a/tools/DotNetOpenAuth.Versioning.targets b/tools/DotNetOpenAuth.Versioning.targets
index f4b12b0..65d212c 100644
--- a/tools/DotNetOpenAuth.Versioning.targets
+++ b/tools/DotNetOpenAuth.Versioning.targets
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
- <!-- Import this .targets file to automaticaly generate AssemblyVersion
+ <!-- Import this .targets file to automatically generate AssemblyVersion
attribute according to DotNetOpenAuth convention. -->
<PropertyGroup>
<ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..</ProjectRoot>
diff --git a/tools/JavascriptPacker.targets b/tools/JavascriptPacker.targets
new file mode 100644
index 0000000..e1a3a8c
--- /dev/null
+++ b/tools/JavascriptPacker.targets
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <ProjectRoot Condition="'$(ProjectRoot)' == ''">$(MSBuildProjectDirectory)\..\..</ProjectRoot>
+ </PropertyGroup>
+
+ <Import Project="$(ProjectRoot)\lib\DotNetOpenAuth.BuildTasks.targets" />
+
+ <PropertyGroup>
+ <PackJs Condition="'$(PackJs)' == '' and '$(Configuration)' == 'Release'">true</PackJs>
+ <PrepareResourcesDependsOn Condition="'$(PackJs)' == 'true'">
+ $(PrepareResourcesDependsOn);
+ PackJavascriptResources;
+ </PrepareResourcesDependsOn>
+ <CleanDependsOn>
+ $(CleanDependsOn);
+ CleanPackedJavascriptResources;
+ </CleanDependsOn>
+ </PropertyGroup>
+
+ <!-- We depend on CreateManifestResourceNames because we'll be changing the paths
+ from which resources are embedded, which will alter their names if that target
+ runs after us. -->
+ <Target Name="PackJavascriptResources" DependsOnTargets="CreateManifestResourceNames">
+ <ItemGroup>
+ <JavascriptInputs Include="@(EmbeddedResource)" Condition="'%(Extension)' == '.js'" />
+ <JavascriptOutputs Include="@(JavascriptInputs->'$(IntermediateOutputPath)%(RelativeDir)%(Filename)%(Extension)')" />
+ <EmbeddedResource Remove="@(JavascriptInputs)" />
+ <EmbeddedResource Include="@(JavascriptOutputs)" />
+ </ItemGroup>
+
+ <JsPack Inputs="@(JavascriptInputs)" Outputs="@(JavascriptOutputs)" />
+ </Target>
+
+ <Target Name="CleanPackedJavascriptResources">
+ <ItemGroup>
+ <_JavascriptOutputsToClean
+ Include="@(EmbeddedResource->'$(IntermediateOutputPath)%(RelativeDir)%(Filename)%(Extension)')"
+ Condition="'%(Extension)' == '.js'" />
+ </ItemGroup>
+ <Delete Files="@(_JavascriptOutputsToClean)" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/chm/Test.hhp b/tools/Sandcastle/Presentation/Prototype/chm/Test.hhp
new file mode 100644
index 0000000..e1d3ac6
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/chm/Test.hhp
@@ -0,0 +1,14 @@
+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=Test.chm
+Contents file=Test.hhc
+Display compile progress=No
+Language=0x409 English (United States)
+
+[FILES]
+art\*.gif
+html\*.htm
+scripts\*.js
+styles\*.css
+
+[INFOTYPES]
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/conceptual.config b/tools/Sandcastle/Presentation/Prototype/configuration/conceptual.config
index 0c2beda..36be43c 100644
--- a/tools/Sandcastle/Presentation/Prototype/configuration/conceptual.config
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/conceptual.config
@@ -68,7 +68,14 @@
<!-- transform -->
<component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <transform file="%DXROOT%\Presentation\Prototype\transforms\main_conceptual.xsl" />
+ <transform file="%DXROOT%\Presentation\Prototype\transforms\main_conceptual.xsl" >
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cs" />
+ </argument>
+ </transform>
</component>
<!-- resolve art links -->
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/reference-core.config b/tools/Sandcastle/Presentation/Prototype/configuration/reference-core.config
new file mode 100644
index 0000000..c1a5de2
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/reference-core.config
@@ -0,0 +1,190 @@
+<configuration>
+ <dduetools>
+ <builder>
+
+ <context>
+ <namespace prefix="ddue" uri="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ </context>
+
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\Prototype\transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data files=".\reflection.xml" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="apidata" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="/document/reference/topicdata/@group='api'" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator name="VisualBasic" type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="CSharp" type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="ManagedCPlusPlus" type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/usyntax" />
+ <generators>
+ <generator name="VisualBasic" type="Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base=".\DdueXml" recurse="true" files="*.xml" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" />
+ </component>
+
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples file="%DXROOT%\Data\CodeSnippet.xml" />
+ <colors language="VisualBasic">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(As)|(ByRef)|(ByVal)|(Case)|(Catch)|(Class)|(Const)|(Continue)|(Delegate)|(Dim)|(Each)|(Else)|(ElseIf)|(End)|(Enum)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(Function)|(Get)|(Handles)|(Implements)|(Imports)|(In)|(Inherits)|(Interface)|(Is)|(Loop)|(Me)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(Namespace)|(New)|(Next)|(Nothing)|(NotInheritable)|(NotOverrideable)|(Of)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(RemoveHandler)|(Set)|(Shadows)|(Shared)|(Static)|(Step)|(Structure)|(Sub)|(Then)|(Throw)|(To)|(True)|(Try)|(Until)|(Using)|(When)|(While)|(With)|(WriteOnly))\b" class="keyword" />
+ </colors>
+ <colors language="CSharp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((abstract)|(as)|(base)|(bool)|(break)|(case)|(catch)|(class)|(const)|(continue)|(default)|(delegate)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(foreach)|(get)|(if)|(in)|(interface)|(internal)|(is)|(namespace)|(new)|(null)|(out)|(override)|(params)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sealed)|(set)|(static)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(using)|(virtual)|(volatile)|(void)|(while))\b" class="keyword" />
+ </colors>
+ <colors language="ManagedCPlusPlus">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((abstract)|(array)|(break)|(case)|(catch)|(class)|(const)|(continue)|(delegate)|(delete)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(interface)|(literal)|(namespace)|(new)|(noinline)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(sealed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(throw)|(true)|(try)|(typedef)|(union)|(using)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </colors>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements/element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements/element[@api=$key]/*)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(local-name()='elements')]" target="/document/reference/elements/element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" source="ddue:dduexml/ddue:summary" target="/document/reference/elements/element[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+<!--
+ <component type="Microsoft.Ddue.Tools.DisplayComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <xpath>/</xpath>
+ </component>
+ -->
+
+ <!-- resolve tokens -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <content file="%DXROOT%\Data\tokens.xml" />
+ <replace elements="/document//ddue:token" item="string(.)" />
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\Prototype\transforms\main_reference.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ </argument>
+ </transform>
+ </component>
+
+ <!--
+ <component type="Microsoft.Ddue.Tools.DisplayComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <xpath>/</xpath>
+ </component>
+ -->
+
+ <!-- resolve art links -->
+ <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets input="%DXROOT%\Data\ArtStore" output=".\Output\media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\Prototype\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\Prototype\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\Shared\content\syntax_content.xml" />
+ </component>
+
+ <!-- resolve conceptual links -->
+ <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\XmlComp" type="index"/>
+ </component>
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets files=".\reflection.xml" type="local" />
+ </component>
+
+ <!-- Write out intellisense -->
+ <component type="Microsoft.Ddue.Tools.IntellisenseComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <output directory=".\Intellisense" />
+ <expressions root="/html/body/div[@id='main']"
+ assembly="string(p/span[@sdata='assembly'])"
+ summary="span[@sdata='authoredSummary']"
+ parameters="div[@id='parameters']/div[@class='section']/div[@class='sectionContent']/dl"
+ parameterContent="dd/span[@sdata='authoredParameterSummary']"
+ templates="div[@id='genericParameters']/div[@class='section']/div[@class='sectionContent']/dl"
+ templateContent="dd"
+ returns="div[@id='returns']/div[@class='section']/div[@class='sectionContent']/span[@sdata='authoredValueSummary']"
+ exception="div[@class='section']/div[@class='sectionContent']/table[@class='exceptions']/tr/td[2]"
+ exceptionCref="../td[1]/span[@sdata='cer']"
+ enumeration="div[@id='enumerationSection']/div[@class='section']/div[@class='sectionContent']/table[@class='members']/tr/td[2]"
+ enumerationApi="../td[1]"
+ memberSummary="span[@sdata='memberAuthoredSummary']" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base=".\Output\html" path="concat(/html/head/meta[@name='file']/@content,'.htm')" indent="false" omit-xml-declaration="true" />
+ </component>
+
+ </components>
+
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/reference.config b/tools/Sandcastle/Presentation/Prototype/configuration/reference.config
new file mode 100644
index 0000000..01371ab
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/reference.config
@@ -0,0 +1,175 @@
+<configuration>
+ <dduetools>
+ <builder>
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\Prototype\transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" />
+ <data files=".\reflection.xml" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="apidata" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="/document/reference/topicdata/@group='api'" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/usyntax" />
+ <generators>
+ <generator type="Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base="%DXROOT%\Data\DdueXml" recurse="true" files="*.xml" />
+ <data base=".\DdueXml" recurse="true" files="*.xml" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" />
+ </component>
+
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples file="%DXROOT%\Data\CodeSnippet.xml" />
+ <colors language="VisualBasic">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(As)|(ByRef)|(ByVal)|(Case)|(Catch)|(Class)|(Const)|(Continue)|(Delegate)|(Dim)|(Each)|(Else)|(ElseIf)|(End)|(Enum)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(Function)|(Get)|(Handles)|(Implements)|(Imports)|(In)|(Inherits)|(Interface)|(Is)|(Loop)|(Me)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(Namespace)|(New)|(Next)|(Nothing)|(NotInheritable)|(NotOverrideable)|(Of)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(RemoveHandler)|(Set)|(Shadows)|(Shared)|(Static)|(Step)|(Structure)|(Sub)|(Then)|(Throw)|(To)|(True)|(Try)|(Until)|(Using)|(When)|(While)|(With)|(WriteOnly))\b" class="keyword" />
+ </colors>
+ <colors language="CSharp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((abstract)|(as)|(base)|(bool)|(break)|(case)|(catch)|(class)|(const)|(continue)|(default)|(delegate)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(foreach)|(get)|(if)|(in)|(interface)|(internal)|(is)|(namespace)|(new)|(null)|(out)|(override)|(params)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sealed)|(set)|(static)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(using)|(virtual)|(volatile)|(void)|(while))\b" class="keyword" />
+ </colors>
+ <colors language="ManagedCPlusPlus">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\&#34;.*\&#34;" class="literal" />
+ <color pattern="\b((abstract)|(array)|(break)|(case)|(catch)|(class)|(const)|(continue)|(delegate)|(delete)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(interface)|(literal)|(namespace)|(new)|(noinline)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(sealed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(throw)|(true)|(try)|(typedef)|(union)|(using)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </colors>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements/element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements/element[@api=$key]/*)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(local-name()='elements')]" target="/document/reference/elements/element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements/element[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- resolve tokens -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <content file="%DXROOT%\Presentation\Prototype\content\token_content.xml" />
+ <replace elements="/document//ddue:token" item="string(.)" />
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\Prototype\transforms\main_reference.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cs" />
+ </argument>
+ </transform>
+ </component>
+
+ <!-- resolve art links -->
+ <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets input="%DXROOT%\Data\ArtStore" output=".\Output\media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\Prototype\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\Prototype\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\Shared\content\syntax_content.xml" />
+ </component>
+
+ <!-- resolve conceptual links -->
+ <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\XmlComp" type="index"/>
+ </component>
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" type="index" />
+ <targets files=".\reflection.xml" type="local" />
+ </component>
+
+ <!-- Write out intellisense -->
+ <component type="Microsoft.Ddue.Tools.IntellisenseComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <output directory=".\Intellisense" />
+ <expressions root="/html/body/div[@id='main']"
+ assembly="string(p/span[@sdata='assembly'])"
+ summary="span[@sdata='authoredSummary']"
+ parameters="div[@id='parameters']/div[@class='section']/div[@class='sectionContent']/dl"
+ parameterContent="dd/span[@sdata='authoredParameterSummary']"
+ templates="div[@id='genericParameters']/div[@class='section']/div[@class='sectionContent']/dl"
+ templateContent="dd"
+ returns="div[@id='returns']/div[@class='section']/div[@class='sectionContent']/span[@sdata='authoredValueSummary']"
+ exception="div[@class='section']/div[@class='sectionContent']/table[@class='exceptions']/tr/td[2]"
+ exceptionCref="../td[1]/span[@sdata='cer']"
+ enumeration="div[@id='enumerationSection']/div[@class='section']/div[@class='sectionContent']/table[@class='members']/tr/td[2]"
+ enumerationApi="../td[1]"
+ memberSummary="span[@sdata='memberAuthoredSummary']" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base=".\Output\html" path="concat(/html/head/meta[@name='file']/@content,'.htm')" indent="false" omit-xml-declaration="true" />
+ </component>
+
+ </components>
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle-scbuild.config b/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle-scbuild.config
index 6f7a13f..a18247a 100644
--- a/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle-scbuild.config
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle-scbuild.config
@@ -79,6 +79,7 @@
<language label="CSharp" name="CSharp" style="cs" />
<language label="VisualBasic" name="VisualBasic" style="vb" />
<language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <language label="JavaScript" name="JavaScript" style="cs" />
</argument>
</transform>
</component>
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle.config b/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle.config
index 4e3502f..255179e 100644
--- a/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle.config
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/sandcastle.config
@@ -12,7 +12,7 @@
<!-- Copy in reflection data -->
<component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
- <data base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" />
+ <data base="%FxReflectionData%" recurse="true" files="*.xml" />
<data files=".\reflection.xml" />
</index>
<copy name="reflection" source="*" target="/document/reference" />
@@ -81,6 +81,7 @@
<language label="CSharp" name="CSharp" style="cs" />
<language label="VisualBasic" name="VisualBasic" style="vb" />
<language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <language label="JavaScript" name="JavaScript" style="cs" />
</argument>
</transform>
</component>
@@ -99,7 +100,7 @@
<!-- resolve reference links -->
<component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" type="msdn" />
+ <targets base="%FxReflectionData%" recurse="true" files="*.xml" type="msdn" />
<targets files=".\reflection.xml" type="local" />
</component>
diff --git a/tools/Sandcastle/Presentation/Prototype/configuration/schema.config b/tools/Sandcastle/Presentation/Prototype/configuration/schema.config
new file mode 100644
index 0000000..d67b56f
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/configuration/schema.config
@@ -0,0 +1,27 @@
+<configuration>
+ <dduetools>
+ <builder>
+ <components>
+
+ <!-- Copy in schema data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="schema" value="/schema/elements/element" key="concat(@namespace,'#',@name)" cache="10">
+ <data files="schemadata.xml" />
+ </index>
+ <copy name="schema" source="*" target="/" />
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\Prototype\transforms\main_schema.xsl" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base ="Output\html" path="concat(/html/head/meta[@name='file']/@content,'.htm')" indent="false" omit-xml-declaration="true" />
+ </component>
+
+ </components>
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/Prototype/content/reference_content.xml b/tools/Sandcastle/Presentation/Prototype/content/reference_content.xml
index 655e4b0..2253bfe 100644
--- a/tools/Sandcastle/Presentation/Prototype/content/reference_content.xml
+++ b/tools/Sandcastle/Presentation/Prototype/content/reference_content.xml
@@ -6,6 +6,8 @@
<!-- topic titles -->
<item id="namespacesTopicTitle">Namespaces</item>
+ <item id="rootTopicTitle">Namespaces</item>
+
<item id="namespaceTopicTitle">{0} Namespace</item>
<item id="classTopicTitle">{0} Class</item>
<item id="structureTopicTitle">{0} Structure</item>
@@ -58,7 +60,7 @@
<item id="notesForImplementersTitle">Notes For Implementers</item>
<item id="notesForInheritersTitle">Notes For Inheriters</item>
<item id="exceptionsTitle">Exceptions</item>
- <item id="permissionsTitle">Permissions</item>
+ <item id="permissionsTitle">.NET Framework Security</item>
<item id="namespacesTitle">Namespaces</item>
<item id="typesTitle">Types</item>
<item id="membersTitle">Members</item>
diff --git a/tools/Sandcastle/Presentation/Prototype/content/shared_content.xml b/tools/Sandcastle/Presentation/Prototype/content/shared_content.xml
index ea38519..f27d67b 100644
--- a/tools/Sandcastle/Presentation/Prototype/content/shared_content.xml
+++ b/tools/Sandcastle/Presentation/Prototype/content/shared_content.xml
@@ -31,6 +31,8 @@
<item id="CSharpUsageLabel">C#</item>
<item id="VisualBasicUsageLabel">Visual Basic Usage</item>
<item id="AspNetUsageLabel">ASP.NET</item>
+ <item id="JavaScriptLabel">JavaScript</item>
+ <item id="XAMLLabel">XAML</item>
<!-- product labels -->
<item id="framework">.NET Framework</item>
@@ -47,6 +49,6 @@
<!-- footer -->
<item id="footer"><div id="footer"><include item="copyright"/> </div></item>
- <item id="copyright">2005 Microsoft Corporation. All rights reserved.</item>
+ <item id="copyright">2008 Microsoft Corporation. All rights reserved.</item>
</content> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test.HxC b/tools/Sandcastle/Presentation/Prototype/hxs/test.HxC
new file mode 100644
index 0000000..0469973
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test.HxC
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpCollection SYSTEM "MS-Help://Hx/Resources/HelpCollection.dtd">
+<HelpCollection DTDVersion="1.0" FileVersion="08.00.50720.2102" LangId="1033" Title="Common Scripts" Copyright="© 2005 Microsoft Corporation. All rights reserved.">
+ <CompilerOptions OutputFile="test.HxS" CreateFullTextIndex="Yes" CompileResult="Hxs">
+ <IncludeFile File="test.HxF" />
+ </CompilerOptions>
+ <TOCDef File="test.HxT" />
+ <KeywordIndexDef File="test_A.HxK" />
+ <KeywordIndexDef File="test_K.HxK" />
+ <KeywordIndexDef File="test_F.HxK" />
+ <KeywordIndexDef File="test_N.HxK" />
+ <KeywordIndexDef File="test_S.HxK" />
+ <KeywordIndexDef File="test_B.HxK" />
+ <ItemMoniker Name="!DefaultTOC" ProgId="HxDs.HxHierarchy" InitData="AnyString" />
+ <ItemMoniker Name="!DefaultFullTextSearch" ProgId="HxDs.HxFullTextSearch" InitData="AnyString" />
+ <ItemMoniker Name="!DefaultAssociativeIndex" ProgId="HxDs.HxIndex" InitData="A" />
+ <ItemMoniker Name="!DefaultKeywordIndex" ProgId="HxDs.HxIndex" InitData="K" />
+ <ItemMoniker Name="!DefaultContextWindowIndex" ProgId="HxDs.HxIndex" InitData="F" />
+ <ItemMoniker Name="!DefaultNamedUrlIndex" ProgId="HxDs.HxIndex" InitData="NamedUrl" />
+ <ItemMoniker Name="!DefaultSearchWindowIndex" ProgId="HxDs.HxIndex" InitData="S" />
+ <ItemMoniker Name="!DefaultDynamicLinkIndex" ProgId="HxDs.HxIndex" InitData="B" />
+</HelpCollection>
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test.HxF b/tools/Sandcastle/Presentation/Prototype/hxs/test.HxF
new file mode 100644
index 0000000..7a04fb3
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test.HxF
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpFileList SYSTEM "MS-Help://Hx/Resources/HelpFileList.dtd">
+<HelpFileList DTDVersion="1.0">
+ <File Url="icons\*.gif" />
+ <File Url="scripts\*.js" />
+ <File Url="styles\*.css" />
+ <File Url="html\*.htm" />
+</HelpFileList>
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_A.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_A.HxK
new file mode 100644
index 0000000..4430fba
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_A.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://Hx/Resources/HelpIndex.dtd">
+<HelpIndex Name="A" DTDVersion="1.0" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_B.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_B.HxK
new file mode 100644
index 0000000..dba159d
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_B.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://Hx/Resources/HelpIndex.dtd">
+<HelpIndex Name="B" DTDVersion="1.0" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_F.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_F.HxK
new file mode 100644
index 0000000..1dbf6f4
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_F.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://Hx/Resources/HelpIndex.dtd">
+<HelpIndex Name="F" DTDVersion="1.0" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_K.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_K.HxK
new file mode 100644
index 0000000..fb9a52d
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_K.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://hx/resources/HelpIndex.DTD">
+<HelpIndex Name="K" Visible="Yes" DTDVersion="1.0" FileVersion="1.0" LangId="1033" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_N.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_N.HxK
new file mode 100644
index 0000000..6923ac1
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_N.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://Hx/Resources/HelpIndex.dtd">
+<HelpIndex Name="NamedUrl" DTDVersion="1.0" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/hxs/test_S.HxK b/tools/Sandcastle/Presentation/Prototype/hxs/test_S.HxK
new file mode 100644
index 0000000..646b6de
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/hxs/test_S.HxK
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE HelpIndex SYSTEM "MS-Help://Hx/Resources/HelpIndex.dtd">
+<HelpIndex Name="S" DTDVersion="1.0" /> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/Prototype/scripts/LanguageFilter.js b/tools/Sandcastle/Presentation/Prototype/scripts/LanguageFilter.js
index 6972632..3b56b5f 100644
--- a/tools/Sandcastle/Presentation/Prototype/scripts/LanguageFilter.js
+++ b/tools/Sandcastle/Presentation/Prototype/scripts/LanguageFilter.js
@@ -2,11 +2,15 @@
function LanguageFilterController() {
this.tabCollections = new Array();
this.blockCollections = new Array();
+ this.tabCollectionIds = new Array();
+ this.blockCollectionIds = new Array();
}
-LanguageFilterController.prototype.registerTabbedArea = function(tabCollection, blockCollection) {
+LanguageFilterController.prototype.registerTabbedArea = function(tabCollection, blockCollection, tabCollectionId, blockCollectionId) {
this.tabCollections.push(tabCollection);
this.blockCollections.push(blockCollection);
+ this.tabCollectionIds.push(tabCollectionId);
+ this.blockCollectionIds.push(blockCollectionId);
}
LanguageFilterController.prototype.switchLanguage = function(languageId) {
diff --git a/tools/Sandcastle/Presentation/Prototype/scripts/script_prototype.js b/tools/Sandcastle/Presentation/Prototype/scripts/script_prototype.js
new file mode 100644
index 0000000..0a64fc0
--- /dev/null
+++ b/tools/Sandcastle/Presentation/Prototype/scripts/script_prototype.js
@@ -0,0 +1,189 @@
+window.onload = LoadPage;
+
+var sd;
+var lfc;
+var store;
+var tf;
+var mf;
+var lc;
+var lang = 'CSharp';
+
+function ListController() {
+ this.tabCollections = new Array();
+ this.listCollections = new Array();
+ this.tabCollectionIds = new Array();
+ this.listCollectionIds = new Array();
+}
+
+ListController.prototype.registerTabbedArea = function(tabCollection, listCollection, tabCollectionId, listCollectionId, filter) {
+ this.tabCollections.push(tabCollection);
+ this.listCollections.push(listCollection);
+ this.tabCollectionIds.push(tabCollectionId);
+ this.listCollectionIds.push(listCollectionId);
+}
+
+function LoadPage() {
+ store = new CookieDataStore('docs');
+ registerEventHandler(window, 'load',
+ function() { var ss = new SplitScreen('control','main'); selectLanguage(store.get('lang')); });
+ sd = getStyleDictionary();
+ lfc = new LanguageFilterController();
+ lc = new ListController();
+ tf = new TypeFilter();
+ mf = new MemberFilter();
+
+ setUpLanguage();
+
+ setUpSyntax();
+
+ setUpSnippets();
+
+ setUpType();
+
+ setUpAllMembers();
+}
+
+function setUpLanguage() {
+ var langFilter = document.getElementById('languageFilter');
+ if (langFilter == null) return;
+
+ var options = langFilter.getElementsByTagName('option');
+ if (options == null) return;
+
+ var value = options[0].getAttribute('value');
+ var names = value.split(' ');
+ lang = names[0];
+}
+
+function setUpSnippets() {
+ var divs = document.getElementsByTagName("DIV");
+
+ for (var i = 0; i < divs.length; i++) {
+ var temp = i;
+ var name = divs[i].getAttribute("name");
+ if (name == null || name != "snippetGroup") continue;
+ processSection(divs[i], 'x-lang', lang, true, true, lfc);
+ i= temp + 1;
+ }
+}
+
+function setUpSyntax() {
+ var syntax = document.getElementById('syntaxSection');
+ if (syntax == null) return;
+
+ processSection(syntax, 'x-lang', lang, true, true, lfc);
+
+ var usyntax = document.getElementById('usyntaxSection');
+ if (usyntax == null) return;
+
+ processSection(usyntax, 'x-lang', lang, true, true, lfc);
+}
+
+function setUpType() {
+ var typeSection = document.getElementById('typeSection');
+ if (typeSection == null) return;
+
+ processSection(typeSection, 'value', 'all', true, false, lc);
+}
+
+function setUpAllMembers() {
+ var allMembersSection = document.getElementById('allMembersSection');
+ if (allMembersSection == null) return;
+
+ processSection(allMembersSection, 'value', 'all', true, false, lc);
+}
+
+function processSection(section, attribute, value, toggleClassValue, toggleStyleValue, registerObject) {
+ var nodes = section.childNodes;
+
+ var tabs;
+ var blocks;
+ var tabId;
+ var blockId;
+
+ if(nodes.length != 2) return;
+
+ if(nodes[0].tagName == 'TABLE') {
+ var rows = nodes[0].getElementsByTagName('tr');
+
+ if (rows.length == 0) return;
+
+ tabId = rows[0].getAttribute('id');
+
+ if (tabId == null) return;
+
+ tabs = new ElementCollection(tabId);
+ }
+
+ if(nodes[1].tagName == 'DIV') {
+ blockId = nodes[1].getAttribute('id');
+ if (blockId == null) return;
+
+ blocks = new ElementCollection(blockId);
+ }
+ else if (nodes[1].tagName == 'TABLE') {
+ blockId = nodes[1].getAttribute('id');
+ if (blockId == null) return;
+
+ blocks = new ElementCollection(blockId);
+ }
+
+ if (registerObject != null) registerObject.registerTabbedArea(tabs, blocks, tabId, blockId);
+ if (toggleClassValue) tabs.toggleClass(attribute,value,'activeTab','tab');
+ if (toggleStyleValue) blocks.toggleStyle(attribute,value,'display','block','none');
+}
+
+function toggleClass(id, attributeName, attributeValue, trueClass, falseClass) {
+ for(var i = 0; i < lfc.tabCollections.length; i++) {
+ var tabs = lfc.tabCollections[i];
+
+ if (lfc.tabCollectionIds[i] == id) {
+ tabs.toggleClass(attributeName, attributeValue, trueClass, falseClass);
+ }
+ }
+
+ for(var j = 0; j < lc.tabCollections.length; j++) {
+ var listTabs = lc.tabCollections[j];
+
+ if (lc.tabCollectionIds[j] == id) {
+ listTabs.toggleClass(attributeName, attributeValue, trueClass, falseClass);
+ }
+ }
+}
+
+function toggleStyle(id, attributeName, attributeValue, styleName, trueStyleValue, falseStyleValue) {
+ for (var i = 0; i < lfc.blockCollections.length; i++) {
+
+ var blocks = lfc.blockCollections[i];
+
+ if (lfc.blockCollectionIds[i] == id) {
+ blocks.toggleStyle(attributeName, attributeValue, styleName, trueStyleValue, falseStyleValue);
+ }
+ }
+}
+
+function processList(id, methodName, typeName) {
+ for (var i = 0; i < lc.listCollections.length; i++) {
+ var list = lc.listCollections[i];
+ if (lc.listCollectionIds[i] == id) {
+ if (typeName == 'type') list.process(getInstanceDelegate(tf,methodName));
+ else if (typeName == 'member') list.process(getInstanceDelegate(mf, methodName));
+ }
+ }
+}
+
+function processSubgroup(subgroup, typeName) {
+ if (typeName == 'type' && tf != null) tf.subgroup = subgroup;
+ else if (typeName == 'member' && mf != null) mf.subgroup = subgroup;
+}
+
+function toggleCheckState(visibility, value) {
+ if (mf == null) return;
+ mf[visibility] = value;
+}
+
+function switchLanguage(names, value) {
+ if (lfc != null) lfc.switchLanguage(names[0]);
+ store.set('lang',value);
+ store.save();
+}
diff --git a/tools/Sandcastle/Presentation/Prototype/styles/presentation.css b/tools/Sandcastle/Presentation/Prototype/styles/presentation.css
index 97549db..0366d1b 100644
--- a/tools/Sandcastle/Presentation/Prototype/styles/presentation.css
+++ b/tools/Sandcastle/Presentation/Prototype/styles/presentation.css
@@ -347,6 +347,10 @@ span.cpp {
display: none;
}
+span.fs {
+ display: none;
+}
+
span.nu
{
display: none;
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/main_conceptual.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/main_conceptual.xsl
index 1c172bf..7dffa01 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/main_conceptual.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/main_conceptual.xsl
@@ -9,6 +9,7 @@
<!-- key parameter is the api identifier string -->
<xsl:param name="key" />
+ <xsl:param name="languages">false</xsl:param>
<xsl:template match="/document">
<html>
@@ -19,9 +20,6 @@
<xsl:call-template name="insertMetadata" />
</head>
<body>
- <script type="text/javascript">
- <xsl:text>registerEventHandler(window, 'load', function() { var ss = new SplitScreen('control', 'main'); });</xsl:text>
- </script>
<xsl:call-template name="control"/>
<xsl:call-template name="main"/>
</body>
@@ -37,21 +35,44 @@
</xsl:template>
<xsl:template name="insertScripts">
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>EventUtilities.js</parameter></includeAttribute>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>script_prototype.js</parameter></includeAttribute>
<xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>SplitScreen.js</parameter></includeAttribute>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>EventUtilities.js</parameter></includeAttribute>
<xsl:text> </xsl:text>
</script>
<script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>ElementCollection.js</parameter>
- </includeAttribute>
+ <includeAttribute name="src" item="scriptPath"><parameter>StyleUtilities.js</parameter></includeAttribute>
<xsl:text> </xsl:text>
</script>
- </xsl:template>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>SplitScreen.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>ElementCollection.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>MemberFilter.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>CollapsibleSection.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>LanguageFilter.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>CookieDataStore.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
+
+ </xsl:template>
<xsl:template name="insertMetadata">
<xml>
@@ -127,6 +148,21 @@
<div id="control">
<span class="productTitle"><include item="productTitle" /></span><br/>
<span class="topicTitle"><xsl:call-template name="topicTitle" /></span><br/>
+
+ <xsl:if test="boolean(($languages != 'false') and (count($languages/language) &gt; 0))">
+ <div id="toolbar">
+ <span id="languageFilter">
+ <select id="languageSelector" onchange="var names = this.value.split(' '); toggleVisibleLanguage(names[1]); switchLanguage(names, this.value);">
+ <xsl:for-each select="$languages/language">
+ <option value="{@name} {@style}">
+ <include item="{@label}Label" />
+ </option>
+ </xsl:for-each>
+ </select>
+ </span>
+ </div>
+ </xsl:if>
+
<!--
<div id="toolbar">
<span class="chickenFeet"><xsl:call-template name="chickenFeet" /></span>
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/main_reference.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/main_reference.xsl
index f993a90..71bd6d8 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/main_reference.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/main_reference.xsl
@@ -23,7 +23,7 @@
<p><include item="hostProtectionAttributeLong" /></p>
</xsl:if>
<!-- summary -->
- <span data="authoredSummary">
+ <span sdata="authoredSummary">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:summary" />
</span>
<!-- syntax -->
@@ -37,7 +37,7 @@
<xsl:apply-templates select="/document/reference/returns" />
<!-- members -->
<xsl:choose>
- <xsl:when test="$tgroup='list' and $tsubgroup='namespaces'">
+ <xsl:when test="$tgroup='root'">
<xsl:apply-templates select="/document/reference/elements" mode="root" />
</xsl:when>
<xsl:when test="$group='namespace'">
@@ -124,7 +124,7 @@
<xsl:template name="getParameterDescription">
<xsl:param name="name" />
- <span data="authoredParameterSummary">
+ <span sdata="authoredParameterSummary">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:parameters/ddue:parameter[string(ddue:parameterReference)=$name]/ddue:content" />
</span>
</xsl:template>
@@ -150,13 +150,13 @@
</xsl:template>
<xsl:template name="getReturnsDescription">
- <span data="authoredValueSummary">
+ <span sdata="authoredValueSummary">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:returnValue" />
</span>
</xsl:template>
<xsl:template name="getElementDescription">
- <span data="memberAuthoredSummary">
+ <span sdata="memberAuthoredSummary">
<xsl:apply-templates select="ddue:summary/ddue:para/node()" />
</span>
</xsl:template>
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/main_sandcastle.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/main_sandcastle.xsl
index fe9a864..944e949 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/main_sandcastle.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/main_sandcastle.xsl
@@ -26,7 +26,7 @@
<xsl:apply-templates select="/document/comments/returns" />
<!-- members -->
<xsl:choose>
- <xsl:when test="$tgroup='list' and $tsubgroup='namespaces'">
+ <xsl:when test="$tgroup='root'">
<xsl:apply-templates select="/document/reference/elements" mode="root" />
</xsl:when>
<xsl:when test="$group='namespace'">
@@ -55,7 +55,7 @@
<!-- inheritance -->
<xsl:apply-templates select="/document/reference/family" />
<!--versions-->
- <xsl:if test="not($group='member' or $group='namespace' or $group='root' )">
+ <xsl:if test="not($group='member' or $group='namespace' or $tgroup='root' )">
<xsl:apply-templates select="/document/reference/versions" />
</xsl:if>
<!-- see also -->
@@ -152,22 +152,17 @@
<xsl:choose>
<xsl:when test="code/@language">
<xsl:variable name="codeId" select="generate-id()" />
+ <div name="snippetGroup">
<table class="filter"><tr class="tabs" id="ct_{$codeId}">
<xsl:for-each select="code">
- <td class="tab" x-lang="{@language}" onclick="ct{$codeId}.toggleClass('x-lang','{@language}','activeTab','tab'); cb{$codeId}.toggleStyle('x-lang','{@language}','display','block','none');"><include item="{@language}Label" /></td>
+ <td class="tab" x-lang="{@language}" onclick="toggleClass('ct_{$codeId}','x-lang','{@language}','activeTab','tab'); toggleStyle('cb_{$codeId}','x-lang','{@language}','display','block','none');"><include item="{@language}Label" /></td>
</xsl:for-each></tr></table>
<div id="cb_{$codeId}">
<xsl:for-each select="code">
<div class="code" x-lang="{@language}"><pre><xsl:copy-of select="node()" /></pre></div>
</xsl:for-each>
</div>
- <script type="text/javascript"><xsl:text>
- var ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text> = new ElementCollection('ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>');
- var cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text> = new ElementCollection('cb_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>');
- lfc.registerTabbedArea(ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text>, cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text>);
- ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text>.toggleClass('x-lang','CSharp','activeTab','tab');
- cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text>.toggleStyle('x-lang','CSharp','display','block','none');</xsl:text>
- </script>
+ </div>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates />
@@ -230,12 +225,14 @@
</xsl:template>
<xsl:template name="seealso">
- <xsl:if test="count(/document/comments/seealso | /document/comments/summary/seealso) &gt; 0">
+ <xsl:if test="count(/document/comments//seealso | /document/reference/elements/element/overloads//seealso) &gt; 0">
<xsl:call-template name="section">
<xsl:with-param name="title"><include item="relatedTitle" /></xsl:with-param>
<xsl:with-param name="content">
- <xsl:for-each select="/document/comments/seealso | /document/comments/summary/seealso">
- <xsl:apply-templates select="." />
+ <xsl:for-each select="/document/comments//seealso | /document/reference/elements/element/overloads//seealso">
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="displaySeeAlso" select="true()" />
+ </xsl:apply-templates>
<br />
</xsl:for-each>
</xsl:with-param>
@@ -293,7 +290,26 @@
</xsl:choose>
</xsl:template>
+ <xsl:template match="see[@href]">
+ <xsl:choose>
+ <xsl:when test="normalize-space(.)">
+ <a>
+ <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
+ <xsl:value-of select="." />
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <a>
+ <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
+ <xsl:value-of select="@href" />
+ </a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
<xsl:template match="seealso[@href]">
+ <xsl:param name="displaySeeAlso" select="false()" />
+ <xsl:if test="$displaySeeAlso">
<xsl:choose>
<xsl:when test="normalize-space(.)">
<a>
@@ -308,6 +324,7 @@
</a>
</xsl:otherwise>
</xsl:choose>
+ </xsl:if>
</xsl:template>
<xsl:template match="see[@langword]">
@@ -352,6 +369,8 @@
<xsl:template match="seealso">
+ <xsl:param name="displaySeeAlso" select="false()" />
+ <xsl:if test="$displaySeeAlso">
<xsl:choose>
<xsl:when test="normalize-space(.)">
<referenceLink target="{@cref}">
@@ -362,10 +381,11 @@
<referenceLink target="{@cref}" />
</xsl:otherwise>
</xsl:choose>
+ </xsl:if>
</xsl:template>
<xsl:template match="c">
- <span class="code"><xsl:value-of select="." /></span>
+ <span class="code"><xsl:apply-templates /></span>
</xsl:template>
<xsl:template match="paramref">
@@ -378,7 +398,7 @@
<!-- pass through html tags -->
- <xsl:template match="p|ol|ul|li|dl|dt|dd|table|tr|th|td|h1|h2|h3|h4|h5|h6|hr|br|pre|blockquote|div|span|a|img|b|i|strong|em|del|sub|sup|abbr|acronym|u|font">
+ <xsl:template match="p|ol|ul|li|dl|dt|dd|table|tr|th|td|h1|h2|h3|h4|h5|h6|hr|br|pre|blockquote|div|span|a|img|b|i|strong|em|del|sub|sup|abbr|acronym|u|font|map|area">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_dduexml.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_dduexml.xsl
index 69a050e..dfa8a20 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_dduexml.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_dduexml.xsl
@@ -335,7 +335,7 @@
<xsl:template match="ddue:languageKeyword">
<xsl:variable name="word" select="." />
- <span class="keyword" data="langKeyword" value="{$word}">
+ <span class="keyword" sdata="langKeyword" value="{$word}">
<xsl:choose>
<xsl:when test="$word='null' or $word='Nothing' or $word='nullptr'">
<span class="cs">null</span>
@@ -575,9 +575,10 @@
<!-- this is temporary -->
<xsl:template match="ddue:snippets">
<xsl:variable name="codeId" select="generate-id()" />
+ <div name="snippetGroup">
<table class="filter"><tr class="tabs" id="ct_{$codeId}">
<xsl:for-each select="ddue:snippet">
- <td class="tab" x-lang="{@language}" onclick="ct{$codeId}.toggleClass('x-lang','{@language}','activeTab','tab'); cb{$codeId}.toggleStyle('x-lang','{@language}','display','block','none');"><include item="{@language}Label" /></td>
+ <td class="tab" x-lang="{@language}" onclick="toggleClass('ct_{$codeId}','x-lang','{@language}','activeTab','tab'); toggleStyle('cb_{$codeId}','x-lang','{@language}','display','block','none');"><include item="{@language}Label" /></td>
</xsl:for-each>
</tr></table>
<div id="cb_{$codeId}">
@@ -585,13 +586,7 @@
<div class="code" x-lang="{@language}"><pre><xsl:copy-of select="node()" /></pre></div>
</xsl:for-each>
</div>
- <script type="text/javascript"><xsl:text>
- var ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text> = new ElementCollection('ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>');
- var cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text> = new ElementCollection('cb_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>');
- lfc.registerTabbedArea(ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text>, cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text>);
- ct</xsl:text><xsl:value-of select="$codeId" /><xsl:text>.toggleClass('x-lang','CSharp','activeTab','tab');
- cb</xsl:text><xsl:value-of select="$codeId" /><xsl:text>.toggleStyle('x-lang','CSharp','display','block','none');
- </xsl:text></script>
+ </div>
</xsl:template>
<xsl:template name="section">
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_metadata.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_metadata.xsl
index 0bbce6b..d9db2d7 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_metadata.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_metadata.xsl
@@ -35,7 +35,7 @@
<xsl:choose>
<xsl:when test="$group='type'">
<xsl:variable name="apiTypeName">
- <xsl:value-of select="concat(/document/reference/containers/container[@namespace]/apidata/@name,'.',/document/reference/apidata/@name)" />
+ <xsl:value-of select="concat(/document/reference/containers/namespace/apidata/@name,'.',/document/reference/apidata/@name)" />
<xsl:if test="count(/document/reference/templates/template) > 0">
<xsl:value-of select="concat('`',count(/document/reference/templates/template))" />
</xsl:if>
@@ -59,7 +59,7 @@
</xsl:when>
<xsl:when test="$group='member'">
<xsl:variable name="apiTypeName">
- <xsl:value-of select="concat(/document/reference/containers/container[@namespace]/apidata/@name,'.',/document/reference/containers/container[@type]/apidata/@name)" />
+ <xsl:value-of select="concat(/document/reference/containers/namespace/apidata/@name,'.',/document/reference/containers/container[@type]/apidata/@name)" />
<xsl:if test="count(/document/reference/templates/template) > 0">
<xsl:value-of select="concat('`',count(/document/reference/templates/template))" />
</xsl:if>
diff --git a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_reference.xsl b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_reference.xsl
index 82e67dd..a6d7019 100644
--- a/tools/Sandcastle/Presentation/Prototype/transforms/utilities_reference.xsl
+++ b/tools/Sandcastle/Presentation/Prototype/transforms/utilities_reference.xsl
@@ -9,7 +9,7 @@
<!-- key parameter is the api identifier string -->
<xsl:param name="key" />
<xsl:param name="metadata" value="false" />
- <xsl:param name="languages" />
+ <xsl:param name="languages">false</xsl:param>
<xsl:include href="utilities_metadata.xsl" />
@@ -23,15 +23,6 @@
<xsl:call-template name="insertMetadata" />
</head>
<body>
- <script type="text/javascript">
- <xsl:text>var store = new CookieDataStore('docs');</xsl:text>
-
- <xsl:text>registerEventHandler(window, 'load', function() { var ss = new SplitScreen('control', 'main'); selectLanguage(store.get('lang')); });</xsl:text>
-
- <!--
- <xsl:text>registerEventHandler(window, 'load', function() { selectLanguage(store.get('lang')); });</xsl:text>
- -->
- </script>
<xsl:call-template name="control"/>
<xsl:call-template name="main"/>
</body>
@@ -56,6 +47,10 @@
</xsl:template>
<xsl:template name="insertScripts">
+ <script type="text/javascript">
+ <includeAttribute name="src" item="scriptPath"><parameter>script_prototype.js</parameter></includeAttribute>
+ <xsl:text> </xsl:text>
+ </script>
<script type="text/javascript">
<includeAttribute name="src" item="scriptPath"><parameter>EventUtilities.js</parameter></includeAttribute>
<xsl:text> </xsl:text>
@@ -329,7 +324,7 @@
<span class="topicTitle"><xsl:call-template name="topicTitleDecorated" /></span><br/>
<div id="toolbar">
<span id="chickenFeet"><xsl:call-template name="chickenFeet" /></span>
- <xsl:if test="count($languages/language) &gt; 0">
+ <xsl:if test="boolean(($languages != 'false') and (count($languages/language) &gt; 0))">
<span id="languageFilter">
<select id="languageSelector" onchange="var names = this.value.split(' '); toggleVisibleLanguage(names[1]); lfc.switchLanguage(names[0]); store.set('lang',this.value); store.save();">
<xsl:for-each select="$languages/language">
@@ -337,7 +332,6 @@
</xsl:for-each>
</select>
</span>
- <script>var sd = getStyleDictionary(); var lfc = new LanguageFilterController();</script>
</xsl:if>
</div>
</div>
@@ -361,6 +355,9 @@
<xsl:when test="boolean($tsubgroup)">
<xsl:value-of select="$tsubgroup" />
</xsl:when>
+ <xsl:when test="$tgroup='root'">
+ <xsl:value-of select="$tgroup" />
+ </xsl:when>
</xsl:choose>
<xsl:text>TopicTitle</xsl:text>
</xsl:attribute>
@@ -404,6 +401,9 @@
<xsl:when test="boolean($tsubgroup)">
<xsl:value-of select="$tsubgroup" />
</xsl:when>
+ <xsl:when test="$tgroup='root'">
+ <xsl:value-of select="$tgroup" />
+ </xsl:when>
</xsl:choose>
<xsl:text>TopicTitle</xsl:text>
</xsl:attribute>
@@ -481,10 +481,11 @@
</xsl:template>
<xsl:template name="syntaxContent">
+ <div id="syntaxSection">
<table class="filter">
<tr class="tabs" id="syntaxTabs">
<xsl:for-each select="div[@codeLanguage]">
- <td class="tab" x-lang="{@codeLanguage}" onclick="st.toggleClass('x-lang','{@codeLanguage}','activeTab','tab'); sb.toggleStyle('x-lang','{@codeLanguage}','display','block','none');" ><include item="{@codeLanguage}Label" /></td>
+ <td class="tab" x-lang="{@codeLanguage}" onclick="toggleClass('syntaxTabs','x-lang','{@codeLanguage}','activeTab','tab'); toggleStyle('syntaxBlocks','x-lang','{@codeLanguage}','display','block','none');" ><include item="{@codeLanguage}Label" /></td>
</xsl:for-each>
</tr>
</table>
@@ -493,22 +494,15 @@
<div class="code" x-lang="{@codeLanguage}"><pre><xsl:copy-of select="./node()" /></pre></div>
</xsl:for-each>
</div>
- <script type="text/javascript"><xsl:text>
- var st = new ElementCollection('syntaxTabs');
- var sb = new ElementCollection('syntaxBlocks');
- lfc.registerTabbedArea(st, sb);
- st.toggleClass('x-lang','</xsl:text><xsl:value-of select="div[1]/@codeLanguage" /><xsl:text>','activeTab','tab');
- sb.toggleStyle('x-lang','</xsl:text><xsl:value-of select="div[1]/@codeLanguage" /><xsl:text>','display','block','none');
- </xsl:text></script>
+ </div>
</xsl:template>
<xsl:template name="usyntaxContent">
+ <div id="usyntaxSection">
<table class="filter">
<tr class="tabs" id="usyntaxTabs">
<xsl:for-each select="div[@codeLanguage]">
- <td class="tab" x-lang="{@codeLanguage}" onclick="ust.toggleClass('x-lang','{@codeLanguage}','activeTab','tab'); usb.toggleStyle('x-lang','{@codeLanguage}','display','block','none');" >
- <include item="{@codeLanguage}Label" />
- </td>
+ <td class="tab" x-lang="{@codeLanguage}" onclick="toggleClass('usyntaxTabs','x-lang','{@codeLanguage}','activeTab','tab'); toggleStyle('usyntaxBlocks','x-lang','{@codeLanguage}','display','block','none');" ><include item="{@codeLanguage}Label" /></td>
</xsl:for-each>
</tr>
</table>
@@ -521,15 +515,7 @@
</div>
</xsl:for-each>
</div>
- <script type="text/javascript">
- <xsl:text>
- var ust = new ElementCollection('usyntaxTabs');
- var usb = new ElementCollection('usyntaxBlocks');
- lfc.registerTabbedArea(ust, usb);
- ust.toggleClass('x-lang','</xsl:text><xsl:value-of select="div[1]/@codeLanguage" /><xsl:text>','activeTab','tab');
- usb.toggleStyle('x-lang','</xsl:text><xsl:value-of select="div[1]/@codeLanguage" /><xsl:text>','display','block','none');
- </xsl:text>
- </script>
+ </div>
</xsl:template>
<xsl:template match="elements" mode="root">
@@ -555,23 +541,24 @@
<xsl:call-template name="section">
<xsl:with-param name="title"><include item="typesTitle" /></xsl:with-param>
<xsl:with-param name="content">
+ <div id="typeSection">
<table class="filter">
<tr class="tabs" id="typeFilter">
- <td class="tab" value="all" onclick="tt.toggleClass('value','all','activeTab','tab'); tf.subgroup='all'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="allTypesFilterLabel" /></td>
+ <td class="tab" value="all" onclick="toggleClass('typeFilter','value','all','activeTab','tab'); processSubgroup('all', 'type'); processList('typeList','filterElement', 'type');"><include item="allTypesFilterLabel" /></td>
<xsl:if test="element/apidata[@subgroup='class']">
- <td class="tab" value="class" onclick="tt.toggleClass('value','class','activeTab','tab'); tf.subgroup='class'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="classTypesFilterLabel" /></td>
+ <td class="tab" value="class" onclick="toggleClass('typeFilter','value','class','activeTab','tab'); processSubgroup('class', 'type'); processList('typeList','filterElement','type');"><include item="classTypesFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='structure']">
- <td class="tab" value="structure" onclick="tt.toggleClass('value','structure','activeTab','tab'); tf.subgroup='structure'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="structureTypesFilterLabel" /></td>
+ <td class="tab" value="structure" onclick="toggleClass('typeFilter','value','structure','activeTab','tab'); processSubgroup('structure', 'type'); processList('typeList','filterElement','type');"><include item="structureTypesFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='interface']">
- <td class="tab" value="interface" onclick="tt.toggleClass('value','interface','activeTab','tab'); tf.subgroup='interface'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="interfaceTypesFilterLabel" /></td>
+ <td class="tab" value="interface" onclick="toggleClass('typeFilter','value','interface','activeTab','tab'); processSubgroup('interface', 'type'); processList('typeList','filterElement','type');"><include item="interfaceTypesFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='enumeration']">
- <td class="tab" value="enumeration" onclick="tt.toggleClass('value','enumeration','activeTab','tab'); tf.subgroup='enumeration'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="enumerationTypesFilterLabel" /></td>
+ <td class="tab" value="enumeration" onclick="toggleClass('typeFilter','value','enumeration','activeTab','tab'); processSubgroup('enumeration', 'type'); processList('typeList','filterElement','type');"><include item="enumerationTypesFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='delegate']">
- <td class="tab" value="delegate" onclick="tt.toggleClass('value','delegate','activeTab','tab'); tf.subgroup='delegate'; ts.process(getInstanceDelegate(tf,'filterElement'));"><include item="delegateTypesFilterLabel" /></td>
+ <td class="tab" value="delegate" onclick="toggleClass('typeFilter','value','delegate','activeTab','tab'); processSubgroup('delegate', 'type'); processList('typeList','filterElement','type');"><include item="delegateTypesFilterLabel" /></td>
</xsl:if>
</tr>
</table>
@@ -585,12 +572,7 @@
<xsl:sort select="apidata/@name" />
</xsl:apply-templates>
</table>
- <script type="text/javascript"><xsl:text>
- var tt = new ElementCollection('typeFilter');
- var ts = new ElementCollection('typeList');
- var tf = new TypeFilter();
- tt.toggleClass('value','all','activeTab','tab');
- </xsl:text></script>
+ </div>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
@@ -620,37 +602,38 @@
<xsl:call-template name="section">
<xsl:with-param name="title"><include item="membersTitle" /></xsl:with-param>
<xsl:with-param name="content">
+ <div id="allMembersSection">
<table class="filter">
<tr class="tabs" id="memberTabs">
- <td class="tab" value="all" onclick="mt.toggleClass('value','all','activeTab','tab'); mf.subgroup='all'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="allMembersFilterLabel" /></td>
+ <td class="tab" value="all" onclick="toggleClass('memberTabs','value','all','activeTab','tab'); processSubgroup('all', 'member'); processList('memberList','filterElement','member');"><include item="allMembersFilterLabel" /></td>
<xsl:if test="element/apidata[@subgroup='constructor']">
- <td class="tab" value="constructor" onclick="mt.toggleClass('value','constructor','activeTab','tab'); mf.subgroup='constructor'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="constructorMembersFilterLabel" /></td>
+ <td class="tab" value="constructor" onclick="toggleClass('memberTabs','value','constructor','activeTab','tab'); processSubgroup('constructor','member');processList('memberList','filterElement','member');"><include item="constructorMembersFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='method']">
- <td class="tab" value="method" onclick="mt.toggleClass('value','method','activeTab','tab'); mf.subgroup='method'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="methodMembersFilterLabel" /></td>
+ <td class="tab" value="method" onclick="toggleClass('memberTabs','value','method','activeTab','tab'); processSubgroup('method','member'); processList('memberList','filterElement','member');"><include item="methodMembersFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='property']">
- <td class="tab" value="property" onclick="mt.toggleClass('value','property','activeTab','tab'); mf.subgroup='property'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="propertyMembersFilterLabel" /></td>
+ <td class="tab" value="property" onclick="toggleClass('memberTabs','value','property','activeTab','tab'); processSubgroup('property','member'); processList('memberList','filterElement','member');"><include item="propertyMembersFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='field']">
- <td class="tab" value="field" onclick="mt.toggleClass('value','field','activeTab','tab'); mf.subgroup='field'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="fieldMembersFilterLabel" /></td>
+ <td class="tab" value="field" onclick="toggleClass('memberTabs','value','field','activeTab','tab'); processSubgroup('field','member'); processList('memberList','filterElement','member');"><include item="fieldMembersFilterLabel" /></td>
</xsl:if>
<xsl:if test="element/apidata[@subgroup='event']">
- <td class="tab" value="event" onclick="mt.toggleClass('value','event','activeTab','tab'); mf.subgroup='event'; ms.process(getInstanceDelegate(mf,'filterElement'));"><include item="eventMembersFilterLabel" /></td>
+ <td class="tab" value="event" onclick="toggleClass('memberTabs','value','event','activeTab','tab'); processSubgroup('event','member'); processList('memberList','filterElement','member');"><include item="eventMembersFilterLabel" /></td>
</xsl:if>
</tr>
<tr>
<td class="line" colspan="2">
- <label for="public"><input id="public" type="checkbox" checked="true" onclick="mf['public'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="publicMembersFilterLabel" /></label><br/>
- <label for="protected"><input id="protected" type="checkbox" checked="true" onclick="mf['protected'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="protectedMembersFilterLabel" /></label>
+ <label for="public"><input id="public" type="checkbox" checked="true" onclick="toggleCheckState('public',this.checked); processList('memberList','filterElement','member');" /><include item="publicMembersFilterLabel" /></label><br/>
+ <label for="protected"><input id="protected" type="checkbox" checked="true" onclick="toggleCheckState('protected',this.checked); processList('memberList','filterElement','member');" /><include item="protectedMembersFilterLabel" /></label>
</td>
<td class="line" colspan="2">
- <label for="instance"><input id="instance" type="checkbox" checked="true" onclick="mf['instance'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="instanceMembersFilterLabel" /></label><br/>
- <label for="static"><input id="static" type="checkbox" checked="true" onclick="mf['static'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="staticMembersFilterLabel" /></label>
+ <label for="instance"><input id="instance" type="checkbox" checked="true" onclick="toggleCheckState('instance',this.checked); processList('memberList','filterElement','member');" /><include item="instanceMembersFilterLabel" /></label><br/>
+ <label for="static"><input id="static" type="checkbox" checked="true" onclick="toggleCheckState('static',this.checked); processList('memberList','filterElement','member');" /><include item="staticMembersFilterLabel" /></label>
</td>
<td class="line" colspan="2">
- <label for="declared"><input id="declared" type="checkbox" checked="true" onclick="mf['declared'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="declaredMembersFilterLabel" /></label><br/>
- <label for="inherited"><input id="inherited" type="checkbox" checked="true" onclick="mf['inherited'] = this.checked; ms.process(getInstanceDelegate(mf,'filterElement'));" /> <include item="inheritedMembersFilterLabel" /></label>
+ <label for="declared"><input id="declared" type="checkbox" checked="true" onclick="toggleCheckState('declared',this.checked); processList('memberList','filterElement','member');" /><include item="declaredMembersFilterLabel" /></label><br/>
+ <label for="inherited"><input id="inherited" type="checkbox" checked="true" onclick="toggleCheckState('inherited',this.checked); processList('memberList','filterElement','member');" /><include item="inheritedMembersFilterLabel" /></label>
</td>
</tr>
</table>
@@ -664,12 +647,7 @@
<xsl:sort select="apidata/@name" />
</xsl:apply-templates>
</table>
- <script type="text/javascript"><xsl:text>
- var mt = new ElementCollection('memberTabs');
- var ms = new ElementCollection('memberList');
- var mf = new MemberFilter();
- mt.toggleClass('value','all','activeTab','tab');
- </xsl:text></script>
+ </div>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
@@ -895,7 +873,7 @@
<xsl:template match="library">
<p><include item="locationInformation">
- <parameter><span data="assembly"><xsl:value-of select="@assembly"/></span></parameter>
+ <parameter><span sdata="assembly"><xsl:value-of select="@assembly"/></span></parameter>
<parameter><xsl:value-of select="@module" /></parameter>
</include></p>
</xsl:template>
@@ -978,6 +956,7 @@
<table cellspacing="0" cellpadding="0">
<xsl:for-each select="ancestors/type">
<xsl:sort select="position()" data-type="number" order="descending" />
+ <!-- <xsl:sort select="@api"/> -->
<tr>
<xsl:call-template name="createTableEntries">
<xsl:with-param name="count" select="position() - 2" />
@@ -1023,7 +1002,7 @@
</tr>
<xsl:for-each select="descendents/type">
-
+ <xsl:sort select="@api"/>
<tr>
<xsl:call-template name="createTableEntries">
diff --git a/tools/Sandcastle/Presentation/Shared/configuration/xamlSyntax.config b/tools/Sandcastle/Presentation/Shared/configuration/xamlSyntax.config
index 60f3830..b107cf1 100644
--- a/tools/Sandcastle/Presentation/Shared/configuration/xamlSyntax.config
+++ b/tools/Sandcastle/Presentation/Shared/configuration/xamlSyntax.config
@@ -10,48 +10,83 @@
The XAML syntax blocks for members of all other assemblies get a generic boilerplate, e.g. "Not applicable." -->
<xamlAssemblies>
<assembly name="PresentationFramework">
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml/presentation">
- <clrNamespace name="System.Windows.Input"/>
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <clrNamespace name="System.Windows.Navigation"/>
+ <clrNamespace name="System.Windows.Controls"/>
+ <clrNamespace name="System.Windows.Documents"/>
+ <clrNamespace name="System.Windows.Shapes"/>
+ <clrNamespace name="System.Windows.Data"/>
<clrNamespace name="System.Windows"/>
+ <clrNamespace name="System.Windows.Controls.Primitives"/>
<clrNamespace name="System.Windows.Media.Animation"/>
+ <clrNamespace name="System.Windows.Input"/>
+ </xmlns>
+ <xmlns uri="http://schemas.microsoft.com/netfx/2007/xaml/presentation">
<clrNamespace name="System.Windows.Controls.Primitives"/>
- <clrNamespace name="System.Windows.Data"/>
- <clrNamespace name="System.Windows.Navigation"/>
- <clrNamespace name="System.Windows.Shapes"/>
- <clrNamespace name="System.Windows.Documents"/>
<clrNamespace name="System.Windows.Controls"/>
+ <clrNamespace name="System.Windows.Documents"/>
+ <clrNamespace name="System.Windows.Shapes"/>
+ <clrNamespace name="System.Windows.Navigation"/>
+ <clrNamespace name="System.Windows.Data"/>
+ <clrNamespace name="System.Windows"/>
+ <clrNamespace name="System.Windows.Input"/>
+ <clrNamespace name="System.Windows.Media.Animation"/>
</xmlns>
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml">
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml">
<clrNamespace name="System.Windows.Markup"/>
</xmlns>
</assembly>
<assembly name="PresentationCore">
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml/presentation">
- <clrNamespace name="System.Windows.Input"/>
- <clrNamespace name="System.Windows"/>
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<clrNamespace name="System.Windows.Media.Imaging"/>
- <clrNamespace name="System.Windows.Media.TextFormatting"/>
- <clrNamespace name="System.Windows.Media.Effects"/>
-
+ <clrNamespace name="System.Windows.Input"/>
<clrNamespace name="System.Windows.Media"/>
- <clrNamespace name="System.Windows.Media.Animation"/>
+ <clrNamespace name="System.Windows.Media.Effects"/>
+ <clrNamespace name="System.Windows.Automation"/>
<clrNamespace name="System.Windows.Media.Media3D"/>
+ <clrNamespace name="System.Windows.Media.Animation"/>
+ <clrNamespace name="System.Windows"/>
+ <clrNamespace name="System.Windows.Media.TextFormatting"/>
<clrNamespace name="System.Windows.Ink"/>
+ </xmlns>
+ <xmlns uri="http://schemas.microsoft.com/netfx/2007/xaml/presentation">
+ <clrNamespace name="System.Windows.Media.Imaging"/>
+ <clrNamespace name="System.Windows.Media.Media3D"/>
+ <clrNamespace name="System.Windows.Ink"/>
+ <clrNamespace name="System.Windows.Input"/>
<clrNamespace name="System.Windows.Automation"/>
+ <clrNamespace name="System.Windows.Media.TextFormatting"/>
+ <clrNamespace name="System.Windows.Media.Animation"/>
+ <clrNamespace name="System.Windows.Media"/>
+ <clrNamespace name="System.Windows"/>
+ <clrNamespace name="System.Windows.Media.Effects"/>
</xmlns>
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml">
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml">
<clrNamespace name="System.Windows.Markup"/>
</xmlns>
</assembly>
<assembly name="WindowsBase">
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml/presentation">
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <clrNamespace name="System.Diagnostics"/>
+ <clrNamespace name="System.Windows.Media"/>
<clrNamespace name="System.Windows.Input"/>
<clrNamespace name="System.Windows"/>
+ </xmlns>
+ <xmlns uri="http://schemas.microsoft.com/netfx/2007/xaml/presentation">
+ <clrNamespace name="System.Windows.Input"/>
<clrNamespace name="System.Windows.Media"/>
+ <clrNamespace name="System.Diagnostics"/>
+ <clrNamespace name="System.Windows"/>
+ </xmlns>
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml">
+ <clrNamespace name="System.Windows.Markup"/>
</xmlns>
</assembly>
<assembly name="WindowsFormsIntegration">
- <xmlns uri="http://schemas.microsoft.com/winfx/xaml/presentation">
+ <xmlns uri="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <clrNamespace name="System.Windows.Forms.Integration"/>
+ </xmlns>
+ <xmlns uri="http://schemas.microsoft.com/netfx/2007/xaml/presentation">
<clrNamespace name="System.Windows.Forms.Integration"/>
</xmlns>
</assembly>
diff --git a/tools/Sandcastle/Presentation/Shared/content/syntax_content.xml b/tools/Sandcastle/Presentation/Shared/content/syntax_content.xml
index cf4e580..8f92668 100644
--- a/tools/Sandcastle/Presentation/Shared/content/syntax_content.xml
+++ b/tools/Sandcastle/Presentation/Shared/content/syntax_content.xml
@@ -6,6 +6,10 @@
<!-- C++ messages -->
<item id="UnsupportedOperator_ManagedCPlusPlus">Visual C++ does not support this operator.</item>
+ <!-- F# messages -->
+ <item id="UnsupportedOperator_FSharp">F# does not support this operator.</item>
+ <item id="UnsupportedCast_FSharp">F# does not support the declaration of new casting operators.</item>"
+
<!-- VB messages -->
<item id="UnsupportedUnsafe_VisualBasic">Visual Basic does not support APIs that consume or return unsafe types.</item>
<item id="UnsupportedOperator_VisualBasic">Visual Basic does not support this operator.</item>
@@ -32,6 +36,13 @@
<!-- JavaScript(Script#) messages-->
<item id="UnsupportedType_ScriptSharp">This type supports the Script# infrastructure and cannot be used directly from JavaScript.</item>
+ <item id="UnsupportedUnsafe_JavaScript">JavaScript does not support APIs that consume or return unsafe types.</item>
+ <item id="UnsupportedGeneric_JavaScript">JavaScript does not support generic types or methods.</item>
+ <item id="UnsupportedExplicit_JavaScript">JavaScript does not support explicit interface implementations.</item>
+ <item id="UnsupportedOperator_JavaScript">JavaScript does not support overloaded operators.</item>
+ <item id="UnsupportedStructure_JavaScript">JavaScript supports the use of structures, but not the declaration of new ones.</item>
+ <item id="UnsupportedIndex_JavaScript">JavaScript does not support indexed properties.</item>
+ <item id="UnsupportedCast_JavaScript">JavaScript does not support the declaration of new casting operators.</item>
<!-- VB usages message -->
<item id="UnsupportedUnsafe_VisualBasicUsage">Visual basic does not support APIs that consume or return unsafe types.</item>
<item id="UnsupportedOperator_VisualBasicUsage">Visual basic does not support this operator.</item>
@@ -63,7 +74,7 @@
<item id="propertyXamlSyntax_nonXaml">You cannot set this property in XAML.</item>
<!-- syntax used with all enums in xaml assemblies -->
- <item id="enumerationOverviewXamlSyntax"><span>&lt;<i>object property</i>="<i>enumerationValue</i>" .../&gt;</span></item>
+ <item id="enumerationOverviewXamlSyntax"><span>&lt;<i>object property</i>="<i>enumerationMemberName</i>" .../&gt;</span></item>
<!-- boilerplate used with all method, field, etc. in xaml assemblies -->
<item id="constructorOverviewXamlSyntax">You cannot use constructors in XAML.</item>
diff --git a/tools/Sandcastle/Presentation/Shared/transforms/utilities_dduexml.xsl b/tools/Sandcastle/Presentation/Shared/transforms/utilities_dduexml.xsl
index 633a2da..3825a63 100644
--- a/tools/Sandcastle/Presentation/Shared/transforms/utilities_dduexml.xsl
+++ b/tools/Sandcastle/Presentation/Shared/transforms/utilities_dduexml.xsl
@@ -50,7 +50,7 @@
<xsl:template match="ddue:parameterReference">
<xsl:if test="normalize-space(.)">
- <span class="parameter" data="paramReference">
+ <span class="parameter" sdata="paramReference">
<xsl:value-of select="." />
</span>
</xsl:if> </xsl:template>
@@ -197,7 +197,7 @@
</xsl:template>
<xsl:template match="ddue:link">
- <span data="link">
+ <span sdata="link">
<xsl:choose>
<xsl:when test="starts-with(@xlink:href,'#')">
<!-- in-page link -->
@@ -233,7 +233,7 @@
</xsl:template>
<xsl:template match="ddue:codeEntityReference">
- <span data="cer" target="{string(.)}">
+ <span sdata="cer" target="{string(.)}">
<referenceLink target="{string(.)}">
<xsl:if test="@qualifyHint">
<xsl:attribute name="show-container">
@@ -255,7 +255,7 @@
<!-- LEAVE THIS TEMPORARILY to support oldstyle GTMT link tagging -->
<xsl:template match="ddue:link[starts-with(.,'GTMT#')]">
<!-- not supporting popup definitions; just show the display text -->
- <span data="link">
+ <span sdata="link">
<xsl:value-of select="substring-after(.,'GTMT#')"/>
</span>
</xsl:template>
diff --git a/tools/Sandcastle/Presentation/Shared/transforms/utilities_metadata.xsl b/tools/Sandcastle/Presentation/Shared/transforms/utilities_metadata.xsl
index 6d92746..30fa695 100644
--- a/tools/Sandcastle/Presentation/Shared/transforms/utilities_metadata.xsl
+++ b/tools/Sandcastle/Presentation/Shared/transforms/utilities_metadata.xsl
@@ -71,6 +71,8 @@
<xsl:template name="combineTextNames">
<xsl:param name="left" />
<xsl:param name="right" />
+ <xsl:param name="concatenateOperator" select="'.'" />
+
<xsl:choose>
<xsl:when test="count($left/name) &gt; 1">
<xsl:choose>
@@ -80,7 +82,7 @@
<xsl:variable name="language" select="@language" />
<name language="{$language}">
<xsl:apply-templates select="." />
- <xsl:value-of select="'.'"/>
+ <xsl:copy-of select="$concatenateOperator" />
<xsl:apply-templates select="$right/name[@language=$language]" />
</name>
</xsl:for-each>
@@ -90,8 +92,11 @@
<xsl:for-each select="$left/name">
<xsl:variable name="language" select="@language" />
<name language="{$language}">
- <xsl:apply-templates select="." />
- <xsl:value-of select="concat('.', $right/name)"/>
+ <xsl:apply-templates select="." />
+ <xsl:if test="$right/name">
+ <xsl:copy-of select="$concatenateOperator"/>
+ </xsl:if>
+ <xsl:value-of select="$right/name"/>
</name>
</xsl:for-each>
</xsl:otherwise>
@@ -104,7 +109,10 @@
<xsl:for-each select="$right/name">
<xsl:variable name="language" select="@language" />
<name language="{.}">
- <xsl:value-of select="concat($left/name, '.')"/>
+ <xsl:value-of select="$left/name"/>
+ <xsl:if test="$left/name">
+ <xsl:copy-of select="$concatenateOperator"/>
+ </xsl:if>
<xsl:apply-templates select="." />
</name>
</xsl:for-each>
@@ -112,7 +120,11 @@
<xsl:otherwise>
<!-- neiter is multi-language -->
<name>
- <xsl:value-of select="concat($left/name,'.',$right/name)" />
+ <xsl:value-of select="$left/name"/>
+ <xsl:if test="$left/name and $right/name">
+ <xsl:copy-of select="$concatenateOperator"/>
+ </xsl:if>
+ <xsl:value-of select="$right/name"/>
</name>
</xsl:otherwise>
</xsl:choose>
@@ -125,8 +137,13 @@
<!-- if there are templates: <name langauge="c">Blah<T></name><name language="v">Blah(Of T)</name> -->
<xsl:template name="simpleTextNames">
<xsl:choose>
- <xsl:when test="specialization | templates">
- <xsl:apply-templates select="specialization | templates" mode="index">
+ <xsl:when test="specialization">
+ <xsl:apply-templates select="specialization" mode="index">
+ <xsl:with-param name="name" select="apidata/@name" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="templates">
+ <xsl:apply-templates select="templates" mode="index">
<xsl:with-param name="name" select="apidata/@name" />
</xsl:apply-templates>
</xsl:when>
@@ -219,6 +236,30 @@
<xsl:value-of select="@name" />
</xsl:template>
+ <xsl:template match="arrayOf" mode="index">
+ <name language="c">
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="index"/>
+ <xsl:text>[</xsl:text>
+ <xsl:if test="number(@rank) &gt; 1">,</xsl:if>
+ <xsl:text>]</xsl:text>
+ </name>
+ <name language="v">
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="index"/>
+ <xsl:text>(</xsl:text>
+ <xsl:if test="number(@rank) &gt; 1">,</xsl:if>
+ <xsl:text>)</xsl:text>
+ </name>
+ </xsl:template>
+
+ <xsl:template match="pointerTo" mode="index">
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="index"/>
+ <xsl:text>*</xsl:text>
+ </xsl:template>
+
+ <xsl:template match="referenceTo" mode="index">
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="index"/>
+ </xsl:template>
+
<xsl:template match="type" mode="index">
<xsl:call-template name="textNames" />
</xsl:template>
@@ -226,7 +267,7 @@
<xsl:template match="name/name">
<xsl:variable name="lang" select="ancestor::*/@language"/>
- <xsl:if test="@language = $lang">
+ <xsl:if test="not(@language) or @language = $lang">
<xsl:value-of select="."/>
</xsl:if>
</xsl:template>
@@ -234,5 +275,45 @@
<xsl:template match="name/text()">
<xsl:value-of select="."/>
</xsl:template>
-
+
+ <xsl:template name="operatorTextNames">
+ <xsl:variable name="left">
+ <xsl:if test="parameters/parameter[1]">
+ <xsl:choose>
+ <xsl:when test="parameters/parameter[1]//specialization | parameters/parameter[1]//templates | parameters/parameter[1]//arrayOf">
+ <xsl:apply-templates select="parameters/parameter[1]" mode="index" />
+ </xsl:when>
+ <xsl:otherwise>
+ <name>
+ <xsl:apply-templates select="parameters/parameter[1]" mode="index" />
+ </name>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:variable name="right">
+ <xsl:if test="returns[1]">
+ <xsl:choose>
+ <xsl:when test="returns[1]//specialization | returns[1]//templates | returns[1]//arrayOf">
+ <xsl:apply-templates select="returns[1]" mode="index" />
+ </xsl:when>
+ <xsl:otherwise>
+ <name>
+ <xsl:apply-templates select="returns[1]" mode="index" />
+ </name>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:call-template name="combineTextNames">
+ <xsl:with-param name="left" select="msxsl:node-set($left)" />
+ <xsl:with-param name="right" select="msxsl:node-set($right)" />
+ <xsl:with-param name="concatenateOperator">
+ <xsl:text> to </xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+
</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/Shared/transforms/utilities_reference.xsl b/tools/Sandcastle/Presentation/Shared/transforms/utilities_reference.xsl
index bfe8fcc..1ef5792 100644
--- a/tools/Sandcastle/Presentation/Shared/transforms/utilities_reference.xsl
+++ b/tools/Sandcastle/Presentation/Shared/transforms/utilities_reference.xsl
@@ -42,6 +42,7 @@
</span>
<span class="cpp">&lt;</span>
<span class="nu">(</span>
+ <span class="fs">&lt;'</span>
</span>
<xsl:for-each select="*">
<xsl:apply-templates select="." mode="link" />
@@ -54,6 +55,7 @@
<span class="vb">)</span>
<span class="cpp">&gt;</span>
<span class="nu">)</span>
+ <span class="fs">&gt;</span>
</span>
</xsl:template>
@@ -88,6 +90,11 @@
<xsl:if test="number(@rank) &gt; 1">,</xsl:if>
<xsl:text>]</xsl:text>
</span>
+ <span class="fs">
+ <xsl:text>[</xsl:text>
+ <xsl:if test="number(@rank) &gt; 1">,</xsl:if>
+ <xsl:text>]</xsl:text>
+ </span>
</span>
</xsl:template>
@@ -122,21 +129,20 @@
<xsl:template match="member" mode="link">
<xsl:param name="qualified" select="true()" />
- <xsl:if test="$qualified">
- <xsl:apply-templates select="type" mode="link" />
- <span class="languageSpecificText">
- <span class="cs">.</span>
- <span class="vb">.</span>
- <span class="cpp">::</span>
- <span class="nu">.</span>
- </span>
- </xsl:if>
<xsl:choose>
<xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
+ <referenceLink target="{@api}" display-target="{@display-api}">
+ <xsl:if test="$qualified">
+ <xsl:attribute name="show-container">true</xsl:attribute>
+ </xsl:if>
+ </referenceLink>
</xsl:when>
<xsl:otherwise>
- <referenceLink target="{@api}" />
+ <referenceLink target="{@api}">
+ <xsl:if test="$qualified">
+ <xsl:attribute name="show-container">true</xsl:attribute>
+ </xsl:if>
+ </referenceLink>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -157,6 +163,27 @@
</xsl:if>
</xsl:template>
+ <!-- Produces parameter and return types in (plain) format:(Int32 to Decimal) for operator members -->
+ <xsl:template name="operatorTypesPlain">
+ <xsl:if test="count(parameters/parameter/*) = 1 or count(returns/*) = 1">
+ <xsl:text>(</xsl:text>
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1">
+ <xsl:apply-templates select="parameters/parameter[1]/type|parameters/parameter[1]/arrayOf|parameters/parameter[1]/pointerTo|
+ parameters/parameter[1]/referenceTo|parameters/parameter[1]/template" mode="plain" />
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1 and count(returns/*) = 1">
+ <xsl:text> to </xsl:text>
+ </xsl:if>
+ <xsl:if test="count(returns/*) = 1">
+ <xsl:apply-templates select="returns[1]/type|returns[1]/arrayOf|returns[1]/pointerTo|returns[1]/referenceTo|
+ returns[1]/template" mode="plain" />
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1 or count(returns/*) = 1">
+ <xsl:text>)</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
<!-- when position on a type api, produces a (plain) name; outer types are indicated by dot-seperators; -->
<!-- generic types are indicated by a keyword, because we can't show templates in a language-independent way -->
<xsl:template name="typeNamePlain">
@@ -198,12 +225,12 @@
</xsl:template>
<xsl:template match="pointerTo" mode="plain">
- <xsl:apply-templates mode="plain"/>
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="plain"/>
<xsl:text>*</xsl:text>
</xsl:template>
<xsl:template match="referenceTo" mode="plain">
- <xsl:apply-templates mode="plain"/>
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="plain"/>
</xsl:template>
<xsl:template match="template" mode="plain">
@@ -224,6 +251,27 @@
</xsl:if>
</xsl:template>
+ <!-- Produces parameter and return types in (decorated) format:(Int32 to Decimal) for operator members -->
+ <xsl:template name="operatorTypesDecorated">
+ <xsl:if test="count(parameters/parameter/*) = 1 or count(returns/*) = 1">
+ <xsl:text>(</xsl:text>
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1">
+ <xsl:apply-templates select="parameters/parameter[1]/type|parameters/parameter[1]/arrayOf|parameters/parameter[1]/pointerTo|
+ parameters/parameter[1]/referenceTo|parameters/parameter[1]/template" mode="decorated" />
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1 and count(returns/*) = 1">
+ <xsl:text> to </xsl:text>
+ </xsl:if>
+ <xsl:if test="count(returns/*) = 1">
+ <xsl:apply-templates select="returns[1]/type|returns[1]/arrayOf|returns[1]/pointerTo|returns[1]/referenceTo|
+ returns[1]/template" mode="decorated" />
+ </xsl:if>
+ <xsl:if test="count(parameters/parameter/*) = 1 or count(returns/*) = 1">
+ <xsl:text>)</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
<!-- when position on a type api, produces a (decorated) name, including outer types and templates -->
<xsl:template name="typeNameDecorated">
<xsl:if test="type|(containers/type)">
@@ -233,6 +281,7 @@
<span class="vb">.</span>
<span class="cpp">::</span>
<span class="nu">.</span>
+ <span class="fs">.</span>
</span>
</xsl:if>
<xsl:value-of select="apidata/@name" />
@@ -258,6 +307,7 @@
</span>
<span class="cpp">&lt;</span>
<span class="nu">(</span>
+ <span class="fs">&lt;'</span>
</span>
<xsl:for-each select="*">
<xsl:apply-templates select="." mode="decorated" />
@@ -270,6 +320,7 @@
<span class="vb">)</span>
<span class="cpp">&gt;</span>
<span class="nu">)</span>
+ <span class="fs">&gt;</span>
</span>
</xsl:template>
@@ -301,16 +352,21 @@
<xsl:if test="number(@rank) &gt; 1">,</xsl:if>
<xsl:text>]</xsl:text>
</span>
+ <span class="fs">
+ <xsl:text>[</xsl:text>
+ <xsl:if test="number(@rank) &gt; 1">,</xsl:if>
+ <xsl:text>]</xsl:text>
+ </span>
</span>
</xsl:template>
<xsl:template match="pointerTo" mode="decorated">
- <xsl:apply-templates mode="decorated"/>
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="decorated"/>
<xsl:text>*</xsl:text>
</xsl:template>
<xsl:template match="referenceTo" mode="decorated">
- <xsl:apply-templates mode="decorated"/>
+ <xsl:apply-templates select="type|arrayOf|pointerTo|referenceTo|template|specialization|templates" mode="decorated"/>
<span class="cpp">%</span>
</xsl:template>
diff --git a/tools/Sandcastle/Presentation/hana/Content/conceptual_content.xml b/tools/Sandcastle/Presentation/hana/Content/conceptual_content.xml
deleted file mode 100644
index 3869c90..0000000
--- a/tools/Sandcastle/Presentation/hana/Content/conceptual_content.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<content xml:space="preserve">
-
- <!-- control window stuff -->
- <item id="productTitle">.NET Framework Developer's Guide</item>
-
- <!-- main window stuff -->
-
- <!-- body -->
-
- <!-- section titles -->
- <item id="inThisSectionTitle">In This Section</item>
- <item id="buildInstructionsTitle">Compiling the Code</item>
- <item id="nextStepsTitle">Next Steps</item>
- <item id="requirementsTitle">Requirements</item>
- <item id="relatedSectionsTitle">Related Sections</item>
- <item id="relatedTopicsTitle">See Also</item>
- <item id="syntaxTitle">Syntax</item>
- <item id="parametersTitle">Parameters</item>
- <item id="returnValueTitle">Return Value</item>
- <item id="attributesAndElements">Attributes and Elements</item>
- <item id="attributes">Attributes</item>
- <item id="childElement">Child Elements</item>
- <item id="parentElement">Parent Elements</item>
- <item id="elementInformation">Element Information</item>
- <item id="textValue">Text Value</item>
- <item id="dotNetFrameworkEquivalent">.NET Framework Equivalent</item>
- <item id="prerequisites">Prerequisites</item>
- <item id="robustProgramming">Robust Programming</item>
- <item id="securitySection">Security</item>
- <item id="externalResources">External Resources</item>
- <item id="demonstrates">Demonstrates</item>
- <item id="appliesTo">Applies To</item>
- <item id="conclusion">Conclusion</item>
- <item id="background">Background</item>
- <item id="whatsNew">What's New</item>
- <item id="reference">Reference</item>
- <item id="errorMessage">Error Message</item>
-
- <!-- language filter -->
- <item id="languageFilter">Language Filter: {0}</item>
- <item id="all">All</item>
- <item id="multiple">Multiple</item>
- <item id="VisualBasic">Visual Basic</item>
- <item id="VBScript">Visual Basic Script</item>
- <item id="CSharp">C#</item>
- <item id="ManagedCPlusPlus">Visual C++</item>
- <item id="JSharp">J#</item>
- <item id="JScript">JScript</item>
- <item id="xmlLang">Xml</item>
- <item id="html">Html</item>
- <item id="visualbasicANDcsharp"><include item="VisualBasic"/> and <include item="CSharp"/></item>
- <item id="other"></item>
- <item id="XAML">XAML</item>
- <item id="usage">Usage</item>
-
- <item id="VisualBasicDeclaration"><include item="VisualBasic"/> (Declaration)</item>
- <item id="VisualBasicUsage"><include item="VisualBasic"/> (<include item="usage"/>)</item>
-
- <item id="collapseAll">Collapse All</item>
- <item id="expandAll">Expand All</item>
- <item id="Example">Example</item>
-
- <!-- Sample Topics -->
- <item id="downloadSample">Download</item>
- <item id="sampleFiles">Sample Files:</item>
- <item id="viewSampleSource">View Source</item>
-
-</content>
diff --git a/tools/Sandcastle/Presentation/hana/Content/reference_content.xml b/tools/Sandcastle/Presentation/hana/Content/reference_content.xml
deleted file mode 100644
index 2cfee10..0000000
--- a/tools/Sandcastle/Presentation/hana/Content/reference_content.xml
+++ /dev/null
@@ -1,482 +0,0 @@
-<content xml:space="preserve">
-
- <!-- note text -->
- <item id="notDocumentedText">This API is not documented.</item>
- <item id="preliminaryText">This API is preliminary and subject to change.</item>
- <!-- topic titles -->
- <item id="tocTitle">{0}</item>
- <item id="rlTitle">{0} ({1})</item>
- <item id="rootTopicTitle">Namespaces</item>
- <item id="namespaceTopicTitle">{0} Namespace</item>
- <item id="classTopicTitle">{0} Class</item>
- <item id="structureTopicTitle">{0} Structure</item>
- <item id="interfaceTopicTitle">{0} Interface</item>
- <item id="DerivedTypeListTopicTitle">{0} Derived Classes</item>
-
- <item id="delegateTopicTitle">{0} Delegate</item>
- <item id="enumerationTopicTitle">{0} Enumeration</item>
- <item id="fieldTopicTitle">{0} Field</item>
- <item id="methodTopicTitle">{0} Method {1}</item>
- <item id="constructorTopicTitle">{0} Constructor {1}</item>
- <item id="propertyTopicTitle">{0} Property {1}</item>
- <item id="eventTopicTitle">{0} Event</item>
- <item id="operatorTopicTitle">{0} Operator</item>
-
- <item id="attachedPropertyTopicTitle">{0} Attached Property</item>
- <item id="attachedEventTopicTitle">{0} Attached Event</item>
-
- <item id="generic_classTopicTitle">{0} Generic Class</item>
- <item id="generic_structureTopicTitle">{0} Generic Structure</item>
- <item id="generic_interfaceTopicTitle">{0} Generic Interface</item>
- <item id="generic_delegateTopicTitle">{0} Generic Delegate</item>
- <item id="generic_methodTopicTitle">{0} Generic Method</item>
-
- <!-- list topic titles -->
- <item id="FieldsTopicTitle">{0} Fields</item>
- <item id="MethodsTopicTitle">{0} Methods {1}</item>
- <item id="ConstructorsTopicTitle">{0} Constructors {1}</item>
- <item id="PropertiesTopicTitle">{0} Properties {1}</item>
- <item id="EventsTopicTitle">{0} Events</item>
- <item id="AttachedPropertiesTopicTitle">{0} Attached Properties</item>
- <item id="AttachedEventsTopicTitle">{0} Attached Events</item>
- <item id="membersTopicTitle">{0} Members</item>
-
- <!-- member titles -->
- <item id="enumMembersTitle">Members</item>
-
- <!-- index entries -->
- <item id="rootIndexEntry">namespaces</item>
- <item id="namespaceIndexEntry">{0} namespace</item>
- <item id="classIndexEntry">{0} class</item>
- <item id="structureIndexEntry">{0} structure</item>
- <item id="interfaceIndexEntry">{0} interface</item>
- <item id="delegateIndexEntry">{0} delegate</item>
- <item id="enumerationIndexEntry">{0} enumeration</item>
- <item id="enumerationMemberIndexEntry">{0} enumeration member</item>
- <item id="aboutTypeIndexEntry">{0}, about {0}</item>
- <item id="derivedTypesIndexEntry">{0}, derived types</item>
- <item id="membersIndexEntry">{0}, all members</item>
- <item id="methodsIndexEntry">{0}, methods</item>
- <item id="propertiesIndexEntry">{0}, properties</item>
- <item id="fieldsIndexEntry">{0}, fields</item>
- <item id="eventsIndexEntry">{0}, events</item>
- <item id="constructorsIndexEntry">{0}, constructors</item>
- <item id="constructorIndexEntry">{0}, constructor</item>
- <item id="constructorTypeIndexEntry">{0} constructor</item>
- <item id="methodIndexEntry">{0} method</item>
- <item id="propertyIndexEntry">{0} property</item>
- <item id="eventIndexEntry">{0} event</item>
- <item id="fieldIndexEntry">{0} field</item>
- <item id="operatorIndexEntry">{0} operator</item>
- <item id="attachedPropertyIndexEntry">{0} attached property</item>
- <item id="attachedEventIndexEntry">{0} attached event</item>
-
- <!-- index entries like: "FileClassifier class" or "Execute method" or "Microsoft.Build.Tasks.Windows.FileClassifier class"
- {0} is API's name, which is shortname in some cases, or FQName in others
- {1} is API's subgroup, e.g. 'class', 'method', etc.
- <item id="nameSubgroupIndexEntry">{0} <include item="{1}IndexEntry"/></item>
--->
- <!-- index entries like: "FileClassifier class, about FileClassifier class"
- {0} is API's name, which is shortname in some cases, or FQName in others
- {1} is API's subgroup, e.g. 'class', 'method', etc.
- <item id="aboutTypeIndexEntry">{0} <include item="{1}IndexEntry"/>, about {0} <include item="{1}IndexEntry"/></item>
- -->
- <!-- index entries like: "FileClassifier class, methods"
- {0} is type's name;
- {1} is type's subgroup, e.g. 'class';
- {2} is the kind of list, e.g. 'AllMembers', 'Methods', etc.
- <item id="listTopicIndexEntry">{0} <include item="{1}IndexEntry"/>, <include item="{2}IndexEntry"/></item>
- -->
- <!-- main window stuff -->
-
- <!-- body -->
-
- <!-- section titles -->
- <item id="syntaxTitle">Syntax</item>
- <item id="templatesTitle">Type Parameters</item>
- <item id="parametersTitle">Parameters</item>
- <item id="valueTitle">Value</item>
- <item id="delegateValueTitle">Return Value</item>
- <item id="methodValueTitle">Return Value</item>
- <item id="propertyValueTitle">Property Value</item>
- <item id="fieldValueTitle">Field Value</item>
- <item id="implementsTitle">Implements</item>
- <item id="examplesTitle">Examples</item>
- <item id="threadSafetyTitle">Thread Safety</item>
- <item id="exceptionsTitle">Exceptions</item>
- <item id="permissionsTitle">Permissions</item>
- <item id="namespacesTitle">Namespaces</item>
- <item id="typesTitle">Types</item>
- <item id="allMembersTitle">Members</item>
- <item id="membersTitle">Overload List</item>
- <item id="familyTitle">Inheritance Hierarchy</item>
- <item id="versionsTitle">Version Information</item>
- <item id="platformsTitle">Platforms</item>
- <item id="relatedTitle">See Also</item>
-
- <!-- table headers -->
- <item id="namespaceNameHeader">Namespace</item>
- <item id="namespaceDescriptionHeader">Description</item>
- <item id="typeIconHeader">Icon</item>
- <item id="classNameHeader">Class</item>
- <item id="structureNameHeader">Structure</item>
- <item id="interfaceNameHeader">Interface</item>
- <item id="delegateNameHeader">Delegate</item>
- <item id="enumerationNameHeader">Enumeration</item>
- <item id="typeNameHeader">Name</item>
- <item id="typeDescriptionHeader">Description</item>
- <item id="memberIconHeader">Icon</item>
- <item id="memberNameHeader">Member</item>
- <item id="memberDescriptionHeader">Description</item>
- <item id="exceptionNameHeader">Exception</item>
- <item id="exceptionConditionHeader">Condition</item>
- <item id="permissionNameHeader">Permission</item>
- <item id="permissionDescriptionHeader">Description</item>
-
- <!-- filter control text -->
- <item id="allTypesFilterLabel">All Types</item>
- <item id="classTypesFilterLabel">Classes</item>
- <item id="structureTypesFilterLabel">Structures</item>
- <item id="interfaceTypesFilterLabel">Interfaces</item>
- <item id="delegateTypesFilterLabel">Delegates</item>
- <item id="enumerationTypesFilterLabel">Enumerations</item>
- <item id="allMembersFilterLabel">All Members</item>
- <item id="constructorMembersFilterLabel">Constructors</item>
- <item id="methodMembersFilterLabel">Methods</item>
- <item id="propertyMembersFilterLabel">Properties</item>
- <item id="attachedPropertyMembersFilterLabel">Attached Properties</item>
- <item id="fieldMembersFilterLabel">Fields</item>
- <item id="eventMembersFilterLabel">Events</item>
- <item id="operatorMembersFilterLabel">Operators</item>
- <item id="attachedEventMembersFilterLabel">Attached Events</item>
- <item id="explicitInterfaceMembersFilterLabel">Explicit Interface Implementations</item>
- <item id="publicMembersFilterLabel">Public</item>
- <item id="protectedMembersFilterLabel">Protected</item>
- <item id="instanceMembersFilterLabel">Instance</item>
- <item id="staticMembersFilterLabel">Static</item>
- <item id="declaredMembersFilterLabel">Declared</item>
- <item id="inheritedMembersFilterLabel">Inherited</item>
- <item id=".NETCompactFilterLabel">.NET Compact Framework Only</item>
- <item id="XNAFilterLabel">XNA Framework Only</item>
- <!-- member list stuff -->
- <item id="Publicconstructor">Public Constructors</item>
- <item id="Protectedconstructor">Protected Constructors</item>
- <item id="constructorsTable">Constructors</item>
- <item id="Privateconstructor">Private Constructors</item>
- <item id="Publicmethod">Public Methods</item>
- <item id="Protectedmethod">Protected Methods</item>
- <item id="Privatemethod">Private Methods</item>
- <item id="Publicfield">Public Fields</item>
- <item id="Protectedfield">Protected Fields</item>
- <item id="Privatefield">Private Fields</item>
- <item id="Publicproperty">Public Properties</item>
- <item id="Protectedproperty">Protected Properties</item>
- <item id="Privateproperty">Private Properties</item>
- <item id="Publicevent">Public Events</item>
- <item id="Protectedevent">Protected Events</item>
- <item id="Privateevent">Private Events</item>
- <item id="PublicattachedProperty">Public Attached Properties</item>
- <item id="ProtectedattachedProperty">Protected Attached Properties</item>
- <item id="PrivateattachedProperty">Private Attached Properties</item>
- <item id="PublicattachedEvent">Public Attached Events</item>
- <item id="ProtectedattachedEvent">Protected Attached Events</item>
- <item id="PrivateattachedEvent">Private Attached Events</item>
- <item id="seeMemberGroup"> (see also {0})</item>
-
- <!-- Thread Safety -->
- <item id="ThreadSafety">Thread Safety</item>
- <item id="ThreadSafetyBP">Any public static (<b>Shared</b> in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.</item>
-
- <item id="NotesForImplementers">Notes to Implementers: </item>
- <item id="NotesForCallers">Notes to Callers: </item>
- <item id="NotesForInheritors">Notes to Inheritors: </item>
-
- <!-- Used for Platform Notes -->
- <item id="PlatformNote">
- <b>{0} Platform Note:</b> {1}
- </item>
- <item id="Win95">Windows 95</item>
- <item id="Win98Se">Windows 98 Second Edition</item>
-
- <item id="WinNT4">Windows NT 4.0</item>
- <item id="WinNT4Svr">Windows NT Server 4.0</item>
- <item id="WinNT4Wks">Windows NT Workstation 4.0</item>
-
- <item id="Win2kFamily">Windows 2000</item>
- <item id="Win2kProfessional">Windows 2000 Professional</item>
- <item id="Win2kServer">Windows 2000 Server</item>
- <item id="Win2kDatacenter">Windows 2000 Advanced Server</item>
-
- <item id="WinXPPersonal">Windows XP Home Edition</item>
- <item id="WinXPPro">Windows XP Professional x64 Edition</item>
- <item id="WinXPSvr"><include item="WinSvr2003"/></item>
- <item id="WinXpTablet">Windows XP Tablet PC Edition</item>
- <item id="WinXpEmbedded">Windows XP Embedded</item>
-
- <item id="ECMACLI">Common Language Infrastructure (CLI) Standard</item>
-
- <item id="MSTV">Microsoft TV</item>
-
- <item id="Win9xFamily"><include item="Win95"/>, <include item="Win98"/>, <include item="Win98Se"/>, <include item="WinME"/></item>
- <item id="WinNt4Family"><include item="WinNT4"/></item>
- <item id="WinXpFamily"><include item="WinXPPersonal"/>, <include item="WinXPPro"/>, <include item="WinXPSvr"/></item>
- <item id="WinCE"><include item="WindowsCE"/></item>
- <item id="Win2K"><include item="WinSvr2000"/></item>
- <item id="Win2KSvr"><include item="Win2kServer"/></item>
- <item id="Win2KADC"><include item="Win2kDatacenter"/></item>
-
- <item id="WinNt4Server"><include item="WinNT4Svr"/></item>
- <item id="WinNt4Workstation"><include item="WinNT4Wks"/></item>
- <item id="Win2kAdvanced"><include item="Win2kDatacenter"/></item>
- <item id="Win2kServerApplianceKit"></item>
- <item id="WinXpHome"><include item="WinXPPersonal"/></item>
- <item id="WinXpProfessional"><include item="WinXPPro"/></item>
- <item id="Win2003Server"><include item="WinXPSvr"/></item>
- <item id="NETCF"><include item="PocketPC"/>, <include item="SmartPhone"/>, <include item="WindowsCE"/></item>
- <!-- Platform Notes -->
-
- <item id="Platforms">Platforms</item>
- <!-- Platforms Information -->
- <item id="developmentPlatformsLayout">
- <p/>
- <span>
- The .NET Framework 3.0 is supported on Windows Vista, Microsoft Windows XP SP2, and Windows Server 2003 SP1.
- </span>
- </item>
-
- <!-- inserted boilerplate -->
- <item id="runningHeaderText">.NET Framework Class Library</item>
- <item id="rootLink"><referenceLink target="R:Project">Namespaces</referenceLink></item>
- <item id="obsoleteShort"><span class="obsolete">Obsolete.</span></item>
- <item id="obsoleteLong"><span class="obsolete">This API is obsolete.</span></item>
- <item id="nonobsoleteAlternative">The non-obsolete alternative is {0}.</item>
- <item id="obsoleteRed"><font color="red"><b>Obsolete. </b></font></item>
- <item id="ObsoleteBoilerPlate">
- <font color="red"><b>NOTE: This API is now obsolete.</b></font>
- </item>
- <item id="inheritedFrom">(Inherited from {0}.)</item>
- <item id="overridesMember">(Overrides {0}.)</item>
- <item id="locationInformation">Assembly: {0} (Module: {1})</item>
- <item id="hostProtectionAttributeShort">HostProtectionAttribute.</item>
- <item id="hostProtectionAttributeLong">The <referenceLink target="T:System.Security.Permissions.HostProtectionAttribute" prefer-overload="true" /> attribute applied to this <include item="{0}"/> has the following <referenceLink target="P:System.Security.Permissions.HostProtectionAttribute.Resources" prefer-overload="true" /> property value: {1}. The <referenceLink target="T:System.Security.Permissions.HostProtectionAttribute" prefer-overload="true" /> does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the <referenceLink target="T:System.Security.Permissions.HostProtectionAttribute" prefer-overload="true" /> class or <conceptualLink target="7dfa36b4-e773-4c75-a3ff-ff1af3ce4c4f" />.</item>
- <item id="classLower">class</item>
- <item id="delegateLower">delegate</item>
- <item id="structureLower">structure</item>
- <item id="interfaceLower">interface</item>
- <item id="enumerationLower">enumeration</item>
- <!-- thread safety boilerplate -->
- <item id="staticThreadSafe">Static members of this type are safe for multi-threaded operations. </item>
- <item id="staticNotThreadSafe">Static members of this type are not safe for multi-threaded operations. </item>
- <item id="instanceThreadSafe">Instance members of this type are safe for multi-threaded operations. </item>
- <item id="instanceNotThreadSafe">Instance members of this type are not safe for multi-threaded operations. </item>
-
- <!-- alt text for images -->
- <item id="pubClassAltText">Public class</item>
- <item id="pubStructureAltText">Public structure</item>
- <item id="pubInterfaceAltText">Public interface</item>
- <item id="pubDelegateAltText">Public delegate</item>
- <item id="pubEnumerationAltText">Public enumeration</item>
- <item id="protClassAltText">Protected class</item>
- <item id="protStructureAltText">Protected structure</item>
- <item id="protInterfaceAltText">Protected interface</item>
- <item id="protDelegateAltText">Protected delegate</item>
- <item id="protEnumerationAltText">Protected enumeration</item>
- <item id="privClassAltText">Private class</item>
- <item id="privStructureAltText">Private structure</item>
- <item id="privInterfaceAltText">Private interface</item>
- <item id="privDelegateAltText">Private delegate</item>
- <item id="privEnumerationAltText">Private enumeration</item>
-
- <item id="pubConstructorAltText">Public constructor</item>
- <item id="pubMethodAltText">Public method</item>
- <item id="pubFieldAltText">Public field</item>
- <item id="pubPropertyAltText">Public property</item>
- <item id="pubEventAltText">Public event</item>
- <item id="pubOperatorAltText">Public operator</item>
- <item id="pubAttachedPropertyAltText">Public attached property</item>
- <item id="pubAttachedEventAltText">Public attached event</item>
- <item id="protConstructorAltText">Protected constructor</item>
- <item id="protMethodAltText">Protected method</item>
- <item id="protFieldAltText">Protected field</item>
- <item id="protPropertyAltText">Protected property</item>
- <item id="protEventAltText">Protected event</item>
- <item id="protOperatorAltText">Protected operator</item>
- <item id="protAttachedPropertyAltText">Protected attached property</item>
- <item id="protAttachedEventAltText">Protected attached event</item>
- <item id="privConstructorAltText">Private constructor</item>
- <item id="privMethodAltText">Private method</item>
- <item id="privFieldAltText">Private field</item>
- <item id="privPropertyAltText">Private property</item>
- <item id="privEventAltText">Private event</item>
- <item id="privOperatorAltText">Private operator</item>
- <item id="privtAttachedPropertyAltText">Private attached property</item>
- <item id="privAttachedEventAltText">Private attached event</item>
- <item id="staticAltText">Static member</item>
-
- <!-- language filter -->
- <item id="languageFilter">Language Filter: {0}</item>
- <item id="all">All</item>
- <item id="multiple">Multiple</item>
- <item id="VisualBasic">Visual Basic</item>
- <item id="VBScript">Visual Basic Script</item>
- <item id="CSharp">C#</item>
- <item id="ManagedCPlusPlus">Visual C++</item>
- <item id="JSharp">J#</item>
- <item id="JScript">JScript</item>
- <item id="xmlLang">Xml</item>
- <item id="html">Html</item>
- <item id="visualbasicANDcsharp"><include item="VisualBasic"/> and <include item="CSharp"/></item>
- <item id="other"></item>
- <item id="XAML">XAML</item>
- <item id="usage">Usage</item>
-
- <item id="VisualBasicDeclaration"><include item="VisualBasic"/> (Declaration)</item>
- <item id="VisualBasicUsage"><include item="VisualBasic"/> (<include item="usage"/>)</item>
- <!-- labels for links at the top of the All Members topic -->
- <item id="constructorGroup">Constructors</item>
- <item id="methodGroup">Methods</item>
- <item id="propertyGroup">Properties</item>
- <item id="eventGroup">Events</item>
- <item id="fieldGroup">Fields</item>
- <item id="operatorGroup">Operators</item>
- <item id="attachedPropertyGroup">Attached Properties</item>
- <item id="attachedEventGroup">Attached Events</item>
- <item id="Group"></item>
- <item id="collapseAll">Collapse All</item>
- <item id="expandAll">Expand All</item>
-
- <item id="Example">Example</item>
- <item id="SeeAlsoNamespaceLinkText">{0} Namespace</item>
- <item id="SeeAlsoTypeLinkText">{0} <include item="{1}SubGroup"/></item>
- <item id="SeeAlsoMembersLinkText">{0} Members</item>
-
- <item id="SubGroup"></item>
- <item id="classSubGroup">Class</item>
- <item id="structureSubGroup">Structure</item>
- <item id="interfaceSubGroup">Interface</item>
- <item id="delegateSubGroup">Delegate</item>
- <item id="enumerationSubGroup">Enumeration</item>
-
- <item id="membersOptionsShowAll">Members Options: Show All</item>
- <item id="membersOptionsFiltered">Members Options: Filtered</item>
- <item id="includeInheritedMembers">Include Inherited Members</item>
- <item id="includeProtectedMembers">Include Protected Members</item>
- <item id="netcfMembersOnly">.NET Compact Framework Members Only</item>
- <item id="netXnaMembersOnly">XNA Framework Members Only</item>
-
- <item id="requirementsNamespaceLayout">
- <b>Namespace:</b>
- </item>
-
- <item id="requirementsPlatformsLayout">
- <b>Platforms:</b> {0}
- </item>
-
- <item id="requirementsAssembliesLabel">
- <b>Assemblies:</b>
- </item>
-
- <item id="requirementsAssemblyLabel">
- <b>Assembly:</b>
- </item>
-
- <item id="assemblyNameAndModule">{0} (in {1}.{2})</item>
-
- <item id="requirementsAssemblyLayout">
- <b>Assembly:</b> {0} (in {1}.dll)
- </item>
-
- <!-- Used for Version Information Section -->
- <item id="supportedIn_1">Supported in: {0}</item>
- <item id="supportedIn_2">Supported in: {0}, {1}</item>
- <item id="supportedIn_3">Supported in: {0}, {1}, {2}</item>
- <item id="supportedIn_4">Supported in: {0}, {1}, {2}, {3}</item>
- <item id="supportedIn_5">Supported in: {0}, {1}, {2}, {3}, {4}</item>
- <item id="obsoleteWarning">Obsolete (compiler warning) in {0}</item>
- <item id="obsoleteError">Obsolete (does not compile) in {0} and later</item>
-
-
- <item id="ReturnValue">Return Value</item>
- <item id="PropertyValue">Property Value</item>
- <item id="FieldValue">Field Value</item>
-
- <item id="derivedClasses">Derived Classes</item>
- <item id="CompactFrameworkAltText">Supported by the .NET Compact Framework</item>
- <item id="XNAFrameworkAltText">Supported by the XNA Framework</item>
- <item id="ExplicitInterfaceImplementation">Explicit Interface Implementations</item>
- <item id="ExplicitInterfaceAltText">Explicit interface implemetation</item>
-
- <!-- boilerplate intro to member list tables -->
- <item id="genericExposedMembersTableText">The {0} generic type exposes the following <include item="{1}"/>.</item>
- <item id="exposedMembersTableText">The {0} type exposes the following <include item="{1}"/>.</item>
- <item id="membersSubgroup">members</item>
- <item id="MethodsSubgroup">methods</item>
- <item id="PropertiesSubgroup">properties</item>
- <item id="EventsSubgroup">events</item>
- <item id="FieldsSubgroup">fields</item>
- <item id="OperatorsSubgroup">operators</item>
- <item id="AttachedPropertiesSubgroup">attached properties</item>
- <item id="AttachedEventsSubgroup">attached events</item>
-
- <item id="dependencyPropertyInfoHeading">Dependency Property Information</item>
- <item id="routedEventInfoHeading">Routed Event Information</item>
- <item id="mrefTaskMoreCodeHeading">More Code</item>
-
- <item id="Overloaded">Overloaded. </item>
- <item id="defaultNamespace">( Default Namespace )</item>
-
- <!-- First line of a param or retval description is a link to the type of the param or retval.
- This boilerplate is used if the type is a type parameter of the member's type. -->
- <item id="typeLinkToTypeParameter"><b>{0}</b> type parameter of {1}.</item>
-
- <!-- Internal only Boilerplate text -->
- <item id="internalOnly">This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.</item>
- <item id="infraStructure">Infrastructure. </item>
-
- <!-- platform names that appear in the Platforms section on mref type and member pages
- The id values must be in sync with the platform/@name values used in the manifold platformFilters.xml filter files.
- These values are also used in <platformNotes>
- -->
- <item id="Win98">Windows 98</item>
- <item id="WinME">Windows Millennium Edition</item>
- <item id="WinSvr2000">Windows Server 2000 SP4</item>
- <item id="WinXPPro64">Windows XP Professional x64 Edition</item>
- <item id="WinXP">Windows XP SP2</item>
- <item id="WindowsCE">Windows CE</item>
- <item id="PocketPC">Windows Mobile for Pocket PC</item>
- <item id="SmartPhone">Windows Mobile for Smartphone</item>
- <item id="WinSvr2003">Windows Server 2003</item>
- <item id="WinXpMediaCenter">Windows XP Media Center Edition</item>
- <item id="WinXPSE">Windows XP Starter Edition</item>
- <item id="WinVista">Windows Vista</item>
-
- <!-- framework ids:
- These shared content item strings are used for the headings in the Version Information section
- These ids must be in sync with the ids used in the config file for VersionBuilder.
- -->
- <item id="netfw">.NET Framework</item>
- <item id="netcfw">.NET Compact Framework</item>
- <item id="xnafw">XNA Framework</item>
-
- <!-- framework version ids
- These shared content item strings are used in the Version Information section.
- These ids must be in sync with the ids used in the config file for VersionBuilder.
- The ids are also used in the platformFilters.xml filter files to indicate the framework version supported by each platform
- -->
- <item id="netfw35">3.5</item>
- <item id="netfw30">3.0</item>
- <item id="netfw20">2.0</item>
- <item id="netfw11">1.1</item>
- <item id="netfw10">1.0</item>
-
- <item id="netcfw35">3.5</item>
- <item id="netcfw20">2.0</item>
- <item id="netcfw10">1.0</item>
-
- <item id="xnafw10">1.0</item>
-
- <!-- Used in the Requirements section to display an xmlns URI for apis that can be used in XAML -->
- <item id="xamlXmlnsRequirementsLayout"><b>XMLNS for XAML:</b> {0}</item>
- <item id="unmappedXamlXmlns">Not mapped to an xmlns.</item>
-
-</content>
diff --git a/tools/Sandcastle/Presentation/hana/Content/shared_content.xml b/tools/Sandcastle/Presentation/hana/Content/shared_content.xml
deleted file mode 100644
index 57ed291..0000000
--- a/tools/Sandcastle/Presentation/hana/Content/shared_content.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<content xml:space="preserve"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp">
-
- <!-- paths -->
- <item id="iconPath">../icons/{0}</item>
- <item id="scriptPath">../scripts/{0}</item>
- <item id="artPath">../art/{0}</item>
- <item id="stylePath">../styles/{0}</item>
-
- <!-- locale -->
- <item id="locale">en-us</item>
-
- <item id="desktopTechnologyAttribute">kbNetFramewk</item>
- <item id="netcfTechnologyAttribute">kbNetCompactFramewk</item>
- <item id="netcfDocSetAttribute">NetCompactFramework</item>
-
- <!-- header -->
- <item id="header"><font color="DarkGray">[This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.]</font>
- <p/> </item>
-
- <!-- alert titles -->
- <item id="tipTitle"><b>Tip:</b></item>
- <item id="cautionTitle"><b>Caution:</b></item>
- <item id="securityTitle"><b>Security Note:</b></item>
- <item id="noteTitle"><b>Note:</b></item>
- <item id="importantTitle"><b>Important Note:</b></item>
- <item id="visualBasicTitle"><b>Visual Basic Note:</b></item>
- <item id="visualC#Title"><b>C# Note:</b></item>
- <item id="visualC++Title"><b>C++ Note:</b></item>
- <item id="visualJ#Title"><b>J# Note:</b></item>
-
- <!-- alert alt text -->
- <item id="tipAltText">Tip</item>
- <item id="cautionAltText">Caution note</item>
- <item id="securityAltText">Security note</item>
- <item id="noteAltText">Note</item>
- <item id="importantAltText">Important note</item>
- <item id="visualBasicAltText">Visual Basic note</item>
- <item id="visualC#AltText">C# note</item>
- <item id="visualC++AltText">C++ note</item>
- <item id="visualJ#AltText">J# note</item>
-
- <!-- code labels -->
- <item id="CSharpLabel">C#</item>
- <item id="VisualBasicLabel">Visual Basic</item>
- <item id="VisualBasicUsageLabel">Visual Basic Usage</item>
- <item id="ManagedCPlusPlusLabel">Visual C++</item>
- <item id="JSharpLabel">J#</item>
- <item id="JScriptLabel">JScript</item>
- <item id="XAMLLabel">XAML</item>
- <item id="declarationLabel">Declaration</item>
- <item id="usageLabel">Usage</item>
-
- <item id="SeeAlso">See Also</item>
- <item id="SeeAlsoTasks">Tasks</item>
- <item id="SeeAlsoReference">Reference</item>
- <item id="SeeAlsoConcepts">Concepts</item>
- <item id="SeeAlsoOtherResources">Other Resources</item>
-
- <!-- tool tips -->
- <item id="collapseAllImage">CollapseAll image</item>
- <item id="expandAllImage">ExpandAll image</item>
- <item id="dropDownImage">DropDown image</item>
- <item id="dropDownHoverImage">DropDownHover image</item>
- <item id="collapseImage">Collapse image</item>
- <item id="expandImage">Expand Image</item>
- <item id="copyHoverImage">CopyHover image</item>
- <item id="copyImage">Copy image</item>
- <item id="footerImage">Footer image</item>
-
- <!-- product labels -->
- <item id="framework">.NET Framework</item>
- <item id="compact">.NET Compact Framework</item>
- <item id="everett">1.1</item>
- <item id="whidbey">2.0</item>
-
- <item id="copyCode">Copy Code</item>
-
-
- <!-- dynamic Link Information -->
- <item id="mshelpKTable"><MSHelp:ktable keywords='{0}' locHeader='Location' topicHeader = 'Topic' disambiguator='table' indexMoniker='!DefaultDynamicLinkIndex' /></item>
-
- <item id="dynamicLinkInlinePreFixText">For more information, see </item>
- <item id="dynamicLinkInlinePostFixText">.</item>
- <item id="dynamicLinkInlineSeperatorText"> and </item>
-
- <item id="remarksTitle">Remarks</item>
-
- <!-- transforms insert K Index Technology qualifiers based on a conceptual topic's //metadata/attribute[@name='DocSet'] value />-->
- <!-- If you add new docset values, the item/@id must = "kIndexTechTag_" + the lower-case DocSet name. -->
- <item id="kIndexTermWithTechQualifier">{0}<include item="kIndexTechTag_{1}" />{2}</item>
- <item id="kIndexTechTag_avalon"> [Windows Presentation Foundation]</item>
- <item id="kIndexTechTag_wpf"> [Windows Presentation Foundation]</item>
- <item id="kIndexTechTag_wcf"> [Windows Communication Foundation]</item>
- <item id="kindextechtag_windowsforms"> [Windows Forms]</item>
-
- <!-- values for MSHelp:Attr Name="TopicType" -->
- <item id="TT_developerConceptualDocument">kbArticle</item>
- <item id="TT_developerErrorMessageDocument">kbRef</item>
- <item id="TT_developerGlossaryDocument">kbRef</item>
- <item id="TT_developerHowToDocument">kbHowTo</item>
- <item id="TT_developerOrientationDocument">kbOrient</item>
- <item id="TT_developerReferenceWithSyntaxDocument">kbSyntax</item>
- <item id="TT_developerReferenceWithoutSyntaxDocument">kbRef</item>
- <item id="TT_developerSampleDocument">kbSampleProd</item>
- <item id="TT_developerSDKTechnologyOverviewArchitectureDocument">kbArticle</item>
- <item id="TT_developerSDKTechnologyOverviewCodeDirectoryDocument">kbOrient</item>
- <item id="TT_developerSDKTechnologyOverviewOrientationDocument">kbOrient</item>
- <item id="TT_developerSDKTechnologyOverviewScenariosDocument">kbHowTo</item>
- <item id="TT_developerSDKTechnologyOverviewTechnologySummaryDocument">kbRef</item>
- <item id="TT_developerTroubleshootingDocument">kbHowTo</item>
- <item id="TT_developerUIReferenceDocument">kbRef</item>
- <item id="TT_developerWalkthroughDocument">kbHowTo</item>
- <item id="TT_developerWhitePaperDocument">kbArticle</item>
- <item id="TT_developerXmlReference">kbSyntax</item>
- <item id="TT_ManagedReference">apiref</item>
-
- <item id="top">Top</item>
-
- <!-- footer -->
-
- <item id="footer">
- <p/>
- <span>
- Send
- <a>
- <includeAttribute name="href" item="MailToLink">
- <parameter>{0}</parameter>
- <parameter>{1}</parameter>
- </includeAttribute>
- comments
- </a>
- about this topic to Microsoft.
- </span>
- </item>
-
- <item id="MailToLink">javascript:sendfeedback('Documentation Feedback (Sandcastle CTP): ', '{1}', '');</item>
-
-</content>
diff --git a/tools/Sandcastle/Presentation/hana/Content/token_content.xml b/tools/Sandcastle/Presentation/hana/Content/token_content.xml
deleted file mode 100644
index 1ccae34..0000000
--- a/tools/Sandcastle/Presentation/hana/Content/token_content.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<items xml:space="preserve" xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
- <item id="vbprvblong"><ddue:legacyItalic>Visual Basic 2005</ddue:legacyItalic></item>
- <item id="aspnet_see_dataaccess_overview">See <ddue:link xlink:href="1ff79676-9b84-4939-91b7-885a5ce4fdf8" /> for more information.</item>
-</items>
diff --git a/tools/Sandcastle/Presentation/hana/DocModel.ps1 b/tools/Sandcastle/Presentation/hana/DocModel.ps1
deleted file mode 100644
index dade8e2..0000000
--- a/tools/Sandcastle/Presentation/hana/DocModel.ps1
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Sandcastle build script overrides for vsorcas doc model.
-
-. $DxRoot\Presentation\Shared\SharedDocModel.ps1
-
-function PostProcessReflectionData($sourceFile, $targetFile) {
- WriteInfo "Post processing reflection data."
- &$XslTransform $sourceFile `
- /xsl:$DxRoot\ProductionTransforms\ApplyVSDocModel.xsl `
- /xsl:$DxRoot\ProductionTransforms\AddFriendlyFilenames.xsl `
- /arg:IncludeAllMembersTopic=false `
- /arg:IncludeInheritedOverloadTopics=true `
- /out:$targetFile
-}
-
-function CreateToc {
- WriteInfo "Creating TOC."
- &$XslTransform $TempDir\ReflectionData\targets.xml `
- /xsl:$DxRoot\ProductionTransforms\createvstoc.xsl `
- /out:$TempDir\toc.xml
-}
-
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/CommonUtilities.js b/tools/Sandcastle/Presentation/hana/Scripts/CommonUtilities.js
deleted file mode 100644
index 431eb96..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/CommonUtilities.js
+++ /dev/null
@@ -1,314 +0,0 @@
-function codeBlockHandler(id, data, value, curvedTabCollections, tabCollections, blockCollections)
-{
- var names = value.split(' ');
-
- //Blocks
- for(var blockCount = 0; blockCount < blockCollections.length; blockCount++)
- {
- toggleStyle(blockCollections[blockCount], 'x-lang', names[0], 'display', 'block', 'none');
- }
-
- //curvedTabs
- for(var curvedTabCount = 0; curvedTabCount < curvedTabCollections.length; curvedTabCount++)
- {
- curvedToggleClass(curvedTabCollections[curvedTabCount], 'x-lang',names[0]);
- }
-
- //Tabs
- for(var tabCount = 0; tabCount < tabCollections.length; tabCount++)
- {
- toggleClass(tabCollections[tabCount], 'x-lang', names[0], 'activeTab', 'tab');
- }
-}
-
-function styleSheetHandler(id, data, value, curvedTabCollections, tabCollections, blockCollections)
-{
- var names = value.split(' ');
- var name = names[1];
- toggleInlineStyle(name);
-}
-
-function persistenceHandler(id, data, value, curvedTabCollections, tabCollections, blockCollections)
-{
- data.set('lang', value);
- data.save();
-}
-
-function languageHandler(id, data, value, curvedTabCollections, tabCollections, blockCollections)
-{
- var names = value.split(' ');
- toggleLanguage(id, 'x-lang', names[0]);
-}
-
-toggleInlineStyle = function(name)
-{
- var sd = getStyleDictionary();
- if (name == 'cs') {
- sd['span.cs'].display = 'inline';
- sd['span.vb'].display = 'none';
- sd['span.cpp'].display = 'none';
- } else if (name == 'vb') {
- sd['span.cs'].display = 'none';
- sd['span.vb'].display = 'inline';
- sd['span.cpp'].display = 'none';
- } else if (name == 'cpp') {
- sd['span.cs'].display = 'none';
- sd['span.vb'].display = 'none';
- sd['span.cpp'].display = 'inline';
- } else {
- }
-}
-
-toggleLanguage = function(id, data, value)
-{
- var tNodes = getChildNodes('languageFilterToolTip');
-
- for(var labelCount=0; labelCount < tNodes.length; labelCount++)
- {
- if(tNodes[labelCount].tagName != 'IMG' && tNodes[labelCount].tagName != '/IMG')
- {
- if(tNodes[labelCount].getAttribute('id').indexOf(value) >= 0)
- {
- tNodes[labelCount].style['display'] = 'inline';
- }
- else
- {
- tNodes[labelCount].style['display'] = 'none';
- }
- }
- }
-
- var languageNodes = getChildNodes(id);
-
- for(var languageCount=0; languageCount < languageNodes.length; languageCount++)
- {
- if(languageNodes[languageCount].tagName == 'DIV');
- {
- if(languageNodes[languageCount].getAttribute('id'))
- {
- var imageNodes = getChildNodes(languageNodes[languageCount].getAttribute('id'))[0];
- if (languageNodes[languageCount].getAttribute('id') == value)
- {
- imageNodes.src = radioSelectImage.src;
- }
- else
- {
- imageNodes.src = radioUnSelectImage.src;
- }
- }
- }
- }
-}
-
-toggleStyle = function(blocks, attributeName, attributeValue, styleName, trueStyleValue, falseStyleValue)
-{
- var blockNodes = getChildNodes(blocks);
-
- for(var blockCount=0; blockCount < blockNodes.length; blockCount++)
- {
- var blockElement = blockNodes[blockCount].getAttribute(attributeName);
- if (blockElement == attributeValue) blockNodes[blockCount].style[styleName] = trueStyleValue;
- else blockNodes[blockCount].style[styleName] = falseStyleValue;
- }
-}
-
-curvedToggleClass = function(curvedTabs, attributeName, attributeValue)
-{
- var curvedTabNodes = getChildNodes(curvedTabs);
-
- for(var curvedTabCount=0; curvedTabCount < curvedTabNodes.length; curvedTabCount++)
- {
- var curvedTabElement = curvedTabNodes[curvedTabCount].getAttribute(attributeName);
- if (curvedTabElement == attributeValue)
- {
- if (curvedTabNodes[curvedTabCount].className == 'leftTab' || curvedTabNodes[curvedTabCount].className == 'activeLeftTab')
- {
- curvedTabNodes[curvedTabCount].className = 'activeLeftTab';
- }
- else if(curvedTabNodes[curvedTabCount].className == 'rightTab' || curvedTabNodes[curvedTabCount].className == 'activeRightTab')
- {
- curvedTabNodes[curvedTabCount].className = 'activeRightTab';
- }
- else if(curvedTabNodes[curvedTabCount].className == 'middleTab' || curvedTabNodes[curvedTabCount].className == 'activeMiddleTab')
- {
- curvedTabNodes[curvedTabCount].className = 'activeMiddleTab';
- }
- }
- else
- {
- if (curvedTabNodes[curvedTabCount].className == 'leftTab' || curvedTabNodes[curvedTabCount].className == 'activeLeftTab')
- {
- curvedTabNodes[curvedTabCount].className = 'leftTab';
- }
- else if(curvedTabNodes[curvedTabCount].className == 'rightTab' || curvedTabNodes[curvedTabCount].className == 'activeRightTab')
- {
- curvedTabNodes[curvedTabCount].className = 'rightTab';
- }
- else if(curvedTabNodes[curvedTabCount].className == 'middleTab' || curvedTabNodes[curvedTabCount].className == 'activeMiddleTab')
- {
- curvedTabNodes[curvedTabCount].className = 'middleTab';
- }
- }
- }
-}
-
-toggleClass = function(tabs, attributeName, attributeValue, trueClass, falseClass)
-{
- var tabNodes = getChildNodes(tabs);
-
- for(var tabCount=0; tabCount < tabNodes.length; tabCount++)
- {
- var tabElement = tabNodes[tabCount].getAttribute(attributeName);
-
- if (tabElement == attributeValue)
- {
- if(tabNodes[tabCount].className == 'leftGrad' || tabNodes[tabCount].className == 'activeLeftGrad')
- {
- tabNodes[tabCount].className = 'activeLeftGrad';
- }
- else if (tabNodes[tabCount].className == 'rightGrad' || tabNodes[tabCount].className == 'activeRightGrad')
- {
- tabNodes[tabCount].className = 'activeRightGrad';
- }
- else tabNodes[tabCount].className = trueClass;
- }
- else
- {
- if(tabNodes[tabCount].className == 'leftGrad' || tabNodes[tabCount].className == 'activeLeftGrad')
- {
- tabNodes[tabCount].className = 'leftGrad';
- }
- else if (tabNodes[tabCount].className == 'rightGrad' || tabNodes[tabCount].className == 'activeRightGrad')
- {
- tabNodes[tabCount].className = 'rightGrad';
- }
- else tabNodes[tabCount].className = falseClass;
- }
- }
-}
-
-getChildNodes = function(node)
-{
- var element = document.getElementById(node);
-
- // get the children
- if (element.tagName == 'TABLE')
- {
- // special handling for tables
- var bodies = element.tBodies;
- for(i = 0; i < bodies.length; i++)
- {
- var nodes = bodies[i].rows;
- return nodes;
- }
- }
- else
- {
- // all other cases
- var nodes = element.childNodes;
- return nodes;
- }
-}
-
-process = function(list, processFunction)
-{
- var listNodes = getChildNodes(list);
-
- for(var i=0; i < listNodes.length; i++)
- {
- var listElement = listNodes[i];
- processFunction(listElement);
- }
-}
-
-function getStyleDictionary() {
- var styleDictionary = new Array();
-
- // iterate through stylesheets
- var sheets = document.styleSheets;
-
- for(var i=0; i<sheets.length;i++) {
- var sheet = sheets[i];
-
- // Ignore sheets at ms-help Urls
- if (sheet.href.substr(0,8) == 'ms-help:') continue;
-
- // get sheet rules
- var rules = sheet.cssRules;
-
- if (rules == null) rules = sheet.rules;
-
- // iterate through rules
- for(j=0; j<rules.length; j++) {
- var rule = rules[j];
-
- // Ignore ones that aren't defined
- if(rule.selectorText == null)
- continue;
-
- // add rule to dictionary
- styleDictionary[rule.selectorText.toLowerCase()] = rule.style;
- }
- }
-
- return(styleDictionary);
-}
-
-function toggleCheck(imageElement)
-{
- if(imageElement.src == checkBoxSelectImage.src)
- {
- imageElement.src = checkBoxUnSelectImage.src;
- return false;
- }
- else
- {
- imageElement.src = checkBoxSelectImage.src;
- return true;
- }
-}
-
-function mouseOverCheck(imageElement, selected, unselected, selected_hover, unselected_hover)
-{
- if(imageElement.src == selected.src)
- {
- imageElement.src = selected_hover.src;
- }
- else if(imageElement.src == unselected.src)
- {
- imageElement.src = unselected_hover.src;
- }
-}
-
-
-function mouseOutCheck(imageElement, selected, unselected, selected_hover, unselected_hover)
-{
- if(imageElement.src == selected_hover.src)
- {
- imageElement.src = selected.src;
- }
- else if(imageElement.src == unselected_hover.src)
- {
- imageElement.src = unselected.src;
- }
-}
-
-function toggleSelect(imageElement, section)
-{
- if(imageElement.src == twirlSelectImage.src)
- {
- imageElement.src = twirlUnSelectImage.src;
- section.style['display'] = 'none';
- }
- else
- {
- imageElement.src = twirlSelectImage.src;
- section.style['display'] = 'block';
- }
-}
-
-
-
-
-
-
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/DataStore.js b/tools/Sandcastle/Presentation/hana/Scripts/DataStore.js
deleted file mode 100644
index 12e072c..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/DataStore.js
+++ /dev/null
@@ -1,116 +0,0 @@
-// cookie data store
-function DataStore(name)
-{
- this.name = name;
- this.load();
-}
-
-DataStore.prototype.load = function ()
-{
- // create a key/value store
- this.language = new Object();
-
- // get cookie text
- var text = getCookie(this.name);
-
- if (text == null) return;
-
- // populate the store using the cookie text
- var data = text.split(';');
-
- for (var i=0; i<data.length; i++)
- {
- var datum = data[i];
- var index = datum.indexOf('=');
-
- if (index > 0)
- {
- var key = datum.substring(0,index);
- var value = datum.substring(index+1);
- this.language[key] = value;
- }
- }
-
-}
-
-function setCookie(name, value, expires, path, domain, secure)
-{
- var text = name + "=" + escape(value);
-
- if (expires)
- {
-
- var currentDate = new Date();
- var expireDate = new Date( currentDate.getTime() + expires*24*60*60*1000 );
- text = text + ";expires=" + expireDate.toGMTString();
- }
- if (path) text = text + ";path=" + path;
- if (domain) text = text + ";domain=" + domain;
- if (secure) text = text + ";secure";
-
- document.cookie = text;
-}
-
-function removeCookie(name)
-{
- setCookie(name, "", -1);
-}
-
-function getCookie(name)
-{
- var text = document.cookie;
-
- var index = text.indexOf(name + "=");
-
- if (index < 0) return(null);
-
- var start = index + name.length + 1;
- var end = text.indexOf(";", start);
-
- if (end < 0) end = text.length;
-
- var value = unescape( text.substring(start, end) );
- return(value);
-}
-
-DataStore.prototype.set = function(key, value)
-{
- this.language[key] = value;
-}
-
-DataStore.prototype.get = function(key)
-{
- return(this.language[key]);
-}
-
-DataStore.prototype.clear = function ()
-{
- this.language = new Object();
-}
-
-DataStore.prototype.save = function ()
-{
- // prepare a cookie string
- var text = "";
-
- // construct the string
- for (var key in this.language)
- {
- var datum = key + "=" + this.language[key];
- text = text + datum + ";";
- }
-
- // set it
- setCookie(this.name, text);
-}
-
-DataStore.prototype.count = function()
-{
- var i = 0;
- for (var key in this.data)
- {
- i++;
- }
- return(i);
-}
- \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/Dropdown.js b/tools/Sandcastle/Presentation/hana/Scripts/Dropdown.js
deleted file mode 100644
index d4f1fe0..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/Dropdown.js
+++ /dev/null
@@ -1,56 +0,0 @@
-
- // Dropdown menu control
-
- function Dropdown(activatorId, dropdownId) {
-
- // store activator and dropdown elements
- this.activator = document.getElementById(activatorId);
- this.dropdown = document.getElementById(dropdownId);
-
- // wire up show/hide events
- registerEventHandler(this.activator,'mouseover', getInstanceDelegate(this, "show"));
- registerEventHandler(this.activator,'mouseout', getInstanceDelegate(this, "requestHide"));
- registerEventHandler(this.dropdown,'mouseover', getInstanceDelegate(this, "show"));
- registerEventHandler(this.dropdown,'mouseout', getInstanceDelegate(this, "requestHide"));
-
- // fix visibility and position
- this.dropdown.style.visibility = 'hidden';
- this.dropdown.style.position = 'absolute';
- this.reposition(null);
-
- // wire up repositioning event
- registerEventHandler(window, 'resize', getInstanceDelegate(this, "reposition"));
-
-
- }
-
- Dropdown.prototype.show = function(e) {
- clearTimeout(this.timer);
- this.dropdown.style.visibility = 'visible';
- }
-
- Dropdown.prototype.hide = function(e) {
- this.dropdown.style.visibility = 'hidden';
- }
-
- Dropdown.prototype.requestHide = function(e) {
- this.timer = setTimeout( getInstanceDelegate(this, "hide"), 250);
- }
-
- Dropdown.prototype.reposition = function(e) {
-
- // get position of activator
- var offsetLeft = 0;
- var offsetTop = 0;
- var offsetElement = this.activator;
- while (offsetElement) {
- offsetLeft += offsetElement.offsetLeft;
- offsetTop += offsetElement.offsetTop;
- offsetElement = offsetElement.offsetParent;
- }
-
- // set position of dropdown relative to it
- this.dropdown.style.left = offsetLeft;
- this.dropdown.style.top = offsetTop + this.activator.offsetHeight;
-
- }
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/EventUtilities.js b/tools/Sandcastle/Presentation/hana/Scripts/EventUtilities.js
deleted file mode 100644
index 1828a11..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/EventUtilities.js
+++ /dev/null
@@ -1,23 +0,0 @@
-
- // attach a handler to a particular event on an element
- // in a browser-independent way
- function registerEventHandler (element, event, handler) {
- if (element.attachEvent) {
- // MS registration model
- element.attachEvent('on' + event, handler);
- } else if (element.addEventListener) {
- // NN (W4C) regisration model
- element.addEventListener(event, handler, false);
- } else {
- // old regisration model as fall-back
- element[event] = handler;
- }
- }
-
- // get a delegate that refers to an instance method
- function getInstanceDelegate (obj, methodName) {
- return( function(e) {
- e = e || window.event;
- return obj[methodName](e);
- } );
- }
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/LanguageFilter.js b/tools/Sandcastle/Presentation/hana/Scripts/LanguageFilter.js
deleted file mode 100644
index c5b75f9..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/LanguageFilter.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-
-function Selector2 (id, tag, attribute) {
- this.root = document.getElementById(id);
- this.elements = new Array();
- this.values = new Array();
- this.registerChildren(root, attribute);
-
- this.handlers = new Array();
-}
-
-Selector2.prototype.registerChildren(parent, tag, attribute) {
- var children = parent.childNodes;
- for (var i = 0; i<children.length; i++) {
- var child = children[i];
- if (child.nodeType == 1) {
- var value = child.getAttribute(attribute);
- if (value) {
- this.elements.add(child);
- this.values.add(value);
- }
- this.registerChildren(child, tag, attribute);
- }
- }
-}
-
-Selector2.prototype.registerHandler(handler) {
- this.handlers.add(handler);
-}
-
-Selector2.prototype.select(value) {
- for (var i=0; i<handlers.length; i++) {
- this.handlers[i](this, value);
- }
-}
-*/
-
-function Selector(id)
-{
- this.selectorHandlers = new Array();
- this.curvedTabCollections = new Array();
- this.tabCollections = new Array();
- this.blockCollections = new Array();
- this.id = id;
-}
-
-Selector.prototype.register=function(handler)
-{
- this.selectorHandlers.push(handler);
-}
-
-Selector.prototype.registerTabbedArea = function(curvedTabCollection, tabCollection, blockCollection)
-{
- this.curvedTabCollections.push(curvedTabCollection);
- this.tabCollections.push(tabCollection);
- this.blockCollections.push(blockCollection);
-}
-
-Selector.prototype.changeLanguage = function(data, name, style)
-{
-
- var value= name + ' ' + style;
-
- for(var handler in this.selectorHandlers)
- {
- this.selectorHandlers[handler](this.id, data, value, this.curvedTabCollections, this.tabCollections, this.blockCollections);
- }
-}
-
-Selector.prototype.select = function(data)
-{
- var value = data.get('lang');
-
- if (value == null) return;
- var names = value.split(' ');
-
- var nodes = getChildNodes(this.id);
-
- for( var i=0; i<nodes.length; i++)
- {
- if(nodes[i].getAttribute('id') == names[0])
- {
- styleSheetHandler(this.id, data, value, this.curvedTabCollections, this.tabCollections, this.blockCollections);
- codeBlockHandler(this.id, data, value, this.curvedTabCollections, this.tabCollections, this.blockCollections);
- languageHandler(this.id, data, value, this.curvedTabCollections, this.tabCollections, this.blockCollections);
- }
- }
-}
-
-
-
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/MemberFilter.js b/tools/Sandcastle/Presentation/hana/Scripts/MemberFilter.js
deleted file mode 100644
index b6cd3ec..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/MemberFilter.js
+++ /dev/null
@@ -1,110 +0,0 @@
-
- // a member filter
-
- function MemberFilter () {
-
- // set up defaults
-
- this.subgroup = "all";
-
- this.public = true;
- this.protected = true;
- this.private = true;
-
- this.instance = true;
- this.static = true;
-
- this.declared = true;
- this.inherited = true;
-
- this.compact = true;
-
- this.xna = true;
- }
-
- MemberFilter.prototype.filterElement = function(element) {
-
- // get the data for the element
- if (element == null) return;
- var data = element.getAttribute("data");
- if (data == null) return;
- var datum = data.split("; ");
- if (datum.length != 6) return;
-
- // extract the relevent member attributes
- var subgroup = datum[0];
- var visibility = datum[1];
- var binding = datum[2];
- var origin = datum[3];
- var compactFramework = datum[4];
- var xnaFramework = datum[5];
-
-
- // determine whether to show the member
- var show = true;
- if (this[visibility] == false) show = false;
- if (this[binding] == false) show = false;
- if (this[origin] == false) show = false;
- if (this[compactFramework] == false) show = false;
- if(this[xnaFramework] == false) show = false;
-
- if ((this.subgroup != null) && (this.subgroup != 'all')) {
- if (subgroup != this.subgroup) show = false;
- }
-
-
- // show or hide the element
- if (show) {
- // either block or table-row, depending on browswer, so use default
- element.style["display"] = "";
- } else {
- element.style["display"] = "none";
- }
-
- }
-
- // a type filter
-
- function TypeFilter () {
-
- // set up defaults
-
-
- this.subgroup = "all";
-
- this.public = true;
- this.internal = true;
-
- }
-
- TypeFilter.prototype.filterElement = function(element) {
-
- // get the data for the element
- if (element == null) return;
- var data = element.getAttribute("data");
- if (data == null) return;
- var datum = data.split("; ");
- if (datum.length != 2) return;
-
- // extract the relevent member attributes
- var subgroup = datum[0];
- var visibility = datum[1];
-
- // determine whether to show the member
- var show = true;
- if (this[visibility] == false) show = false;
- if ((this.subgroup != null) && (this.subgroup != 'all')) {
- if (subgroup != this.subgroup) show = false;
- }
-
- // show or hide the element
- if (show) {
- // either block or table-row, depending on browser, so use default
- element.style["display"] = "";
- } else {
- element.style["display"] = "none";
- }
-
- }
-
- \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/SplitScreen.js b/tools/Sandcastle/Presentation/hana/Scripts/SplitScreen.js
deleted file mode 100644
index 3b04f0a..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/SplitScreen.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
- function SplitScreen (nonScrollingRegionId, scrollingRegionId) {
-
- // store references to the two regions
- this.nonScrollingRegion = document.getElementById(nonScrollingRegionId);
- this.scrollingRegion = document.getElementById(scrollingRegionId);
-
- // set the scrolling settings
- document.body.style.margin = "0px";
- document.body.style.overflow = "hidden";
- this.scrollingRegion.style.overflow = "auto";
-
- // fix the size of the scrolling region
- this.resize(null);
-
- // add an event handler to resize the scrolling region when the window is resized
- registerEventHandler(window, 'resize', getInstanceDelegate(this, "resize"));
-
- }
-
- SplitScreen.prototype.resize = function(e) {
- var height = document.body.clientHeight - this.nonScrollingRegion.offsetHeight;
- if (height > 0) {
- this.scrollingRegion.style.height = height;
- } else {
- this.scrollingRegion.style.height = 0;
- }
- this.scrollingRegion.style.width = document.body.clientWidth;
- }
diff --git a/tools/Sandcastle/Presentation/hana/Scripts/script_manifold.js b/tools/Sandcastle/Presentation/hana/Scripts/script_manifold.js
deleted file mode 100644
index e64a126..0000000
--- a/tools/Sandcastle/Presentation/hana/Scripts/script_manifold.js
+++ /dev/null
@@ -1,1594 +0,0 @@
-window.onload=LoadPage;
-window.onunload=Window_Unload;
-//window.onresize=ResizeWindow;
-window.onbeforeprint = set_to_print;
-window.onafterprint = reset_form;
-
-var vbDeclaration;
-var vbUsage;
-var csLang;
-var cLang;
-var jsharpLang;
-var jsLang;
-var xamlLang;
-
-var scrollPos = 0;
-
-var inheritedMembers;
-var protectedMembers;
-var netcfMembersOnly;
-var netXnaMembersOnly;
-
-// Initialize array of section states
-
-var sectionStates = new Array();
-var sectionStatesInitialized = false;
-
-//Hide sample source in select element
-function HideSelect()
-{
- var selectTags = document.getElementsByTagName("SELECT");
- var spanEles = document.getElementsByTagName("span");
- var i = 10;
- var m;
-
- if (selectTags.length != null || selectTags.length >0)
- {
- for (n=0; n<selectTags.length; n++)
- {
- var lan = selectTags(n).getAttribute("id").substr("10");
- //hide the first select that is on
- switch (lan.toLowerCase())
- {
- case "visualbasic":
- //alert(lan);
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "VisualBasic" && spanEles[m].style.display != "none" && n <i)
- i = n;
- }
- break;
- case "visualbasicdeclaration":
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "VisualBasicDeclaration" && spanEles[m].style.display != "none" && n < i)
- i = n;
- }
- break;
- case "visualbasicusage":
- //alert(lan);
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "VisualBasicUsage" && spanEles[m].style.display != "none" && n <i)
- i = n;
- }
- break;
- case "csharp":
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "CSharp" && spanEles[m].style.display != "none" && n < i)
- i = n;
- }
- break;
- case "managedcplusplus":
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "ManagedCPlusPlus" && spanEles[m].style.display != "none" && n < i)
- i = n;
- }
- break;
- case "jsharp":
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "JSharp" && spanEles[m].style.display != "none" && n < i)
- i = n;
- }
- break;
- case "jscript":
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "JScript" && spanEles[m].style.display != "none" && n < i)
- i = n;
- }
- break;
- case "xaml":
- //alert(lan);
- for (m=0; m<spanEles.length; m++)
- {
- if (spanEles[m].getAttribute("codeLanguage") == "XAML" && spanEles[m].style.display != "none" && n <i)
- i = n;
- }
- break;
- }
- }
- if (i != 10)
- selectTags(i).style.visibility = "hidden";
- }
- else{ alert("Not found!");}
-}
-
-function UnHideSelect()
-{
- var selectTags = document.getElementsByTagName("SELECT");
- var n;
-
- //un-hide all the select sections
- if (selectTags.length != null || selectTags.length >0)
- {
- for (n=0; n<selectTags.length; n++)
- selectTags(n).style.visibility = "visible";
- }
-}
-
-function InitSectionStates()
-{
- sectionStatesInitialized = true;
-
- if (globals == null) globals = GetGlobals();
-
- // SectionStates has the format:
- //
- // firstSectionId:state;secondSectionId:state;thirdSectionId:state; ... ;lastSectionId:state
- //
- // where state is either "e" (expanded) or "c" (collapsed)
-
- // get the SectionStates from the previous topics
- var states = Load("SectionStates");
-
- var start = 0;
- var end;
- var section;
- var state;
- var allCollapsed = false;
- // copy the previous section states to the sectionStates array for the current page
- if (states != null && states != "")
- {
- allCollapsed = true;
- while (start < states.length)
- {
- end = states.indexOf(":", start);
-
- section = states.substring(start, end);
-
- start = end + 1;
- end = states.indexOf(";", start);
- if (end == -1) end = states.length;
- state = states.substring(start, end);
- sectionStates[section] = state;
- allCollapsed = allCollapsed && (state == "c");
- start = end + 1;
- }
- }
-
- // now set the state for any section ids in the current document that weren't in previous
- var imgElements = document.getElementsByName("toggleSwitch");
- var i;
- for (i = 0; i < imgElements.length; ++i)
- sectionStates[imgElements[i].id] = GetInitialSectionState(imgElements[i].id, allCollapsed);
-}
-
-function GetInitialSectionState(itemId, allCollapsed)
-{
- // if the global state is "allCollapsed", set all section states to collapsed
- if (allCollapsed) return "c";
-
- // generic <section> node ids begin with "sectionToggle", so the same id can refer to different sections in different topics
- // we don't want to persist their state; set it to expanded
- if (itemId.indexOf("sectionToggle", 0) == 0) return "e";
-
- // the default state for new section ids is expanded
- if (sectionStates[itemId] == null) return "e";
-
- // otherwise, persist the passed in state
- return sectionStates[itemId];
-}
-
-var noReentry = false;
-
-function OnLoadImage(eventObj)
-{
- if (noReentry) return;
-
- if (!sectionStatesInitialized)
- InitSectionStates();
-
- var elem;
- if(document.all) elem = eventObj.srcElement;
- else elem = eventObj.target;
-
-
- if ((sectionStates[elem.id] == "e"))
- ExpandSection(elem);
- else if((sectionStates[elem.id] == "c"))
- CollapseSection(elem);
-}
-
-/*
-**********
-********** Begin
-**********
-*/
-
-function LoadPage()
-{
- // If not initialized, grab the DTE.Globals object
- if (globals == null) globals = GetGlobals();
-
- // show correct language
- LoadLanguages();
- LoadMembersOptions();
-
- Set_up_checkboxes();
-
- DisplayLanguages();
-
- DisplayFilteredMembers();
-
- ChangeMembersOptionsFilterLabel();
-
- if (!sectionStatesInitialized)
- InitSectionStates();
-
- SetCollapseAll();
-
-// ResizeWindow();
- // split screen
- var screen = new SplitScreen('header', 'mainSection');
-
- // filtering dropdowns
- if (document.getElementById('languageSpan') != null) {
- var languageMenu = new Dropdown('languageFilterToolTip', 'languageSpan');
- }
- if (document.getElementById('membersOptionsFilterToolTip') != null) {
- var languageMenu = new Dropdown('membersOptionsFilterToolTip', 'membersOptionsSpan');
- }
-
- var mainSection = document.getElementById("mainSection");
-
- // vs70.js did this to allow up/down arrow scrolling, I think
- try { mainSection.setActive(); } catch(e) { }
-
- //set the scroll position
- try{mainSection.scrollTop = scrollPos;}
- catch(e){}
-}
-
-function Window_Unload()
-{
- SaveLanguages();
- SaveMembersOptions();
- SaveSections();
-}
-
-/*
-function ResizeWindow()
-{
- if (document.body.clientWidth==0) return;
- var header = document.all.item("header");
- var mainSection = document.all.item("mainSection");
- if (mainSection == null) return;
-
-
- document.body.scroll = "no"
- mainSection.style.overflow= "auto";
- header.style.width= document.body.offsetWidth - 2;
- //mainSection.style.paddingRight = "20px"; // Width issue code
- mainSection.style.width= document.body.offsetWidth - 2;
- mainSection.style.top=0;
- if (document.body.offsetHeight > header.offsetHeight + 10)
- mainSection.style.height= document.body.offsetHeight - (header.offsetHeight + 2);
- else
- mainSection.style.height=0;
-
- try
- {
- mainSection.setActive();
- }
- catch(e)
- {
- }
-}
-*/
-
-function set_to_print()
-{
- //breaks out of divs to print
- var i;
-
- if (window.text)document.all.text.style.height = "auto";
-
- for (i=0; i < document.all.length; i++)
- {
- if (document.all[i].tagName == "body")
- {
- document.all[i].scroll = "yes";
- }
- if (document.all[i].id == "header")
- {
- document.all[i].style.margin = "0px 0px 0px 0px";
- document.all[i].style.width = "100%";
- }
- if (document.all[i].id == "mainSection")
- {
- document.all[i].style.overflow = "visible";
- document.all[i].style.top = "5px";
- document.all[i].style.width = "100%";
- document.all[i].style.padding = "0px 10px 0px 30px";
- }
- }
-}
-
-function reset_form()
-{
- //returns to the div nonscrolling region after print
- document.location.reload();
-}
-
-function Set_up_checkboxes()
-{
- var checkbox;
-
- checkbox = document.getElementById("vbDeclarationCheckbox");
- if(checkbox != null)
- {
- if(vbDeclaration == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("vbUsageCheckbox");
- if(checkbox != null)
- {
- if(vbUsage == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("csCheckbox");
- if(checkbox != null)
- {
- if(csLang == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("cCheckbox");
- if(checkbox != null)
- {
- if(cLang == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("jsharpCheckbox");
- if(checkbox != null)
- {
- if(jsharpLang == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("jsCheckbox");
- if(checkbox != null)
- {
- if(jsLang == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("xamlCheckbox");
- if(checkbox != null)
- {
- if(xamlLang == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("inheritedCheckbox");
- if(checkbox != null)
- {
- if(inheritedMembers == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("protectedCheckbox");
- if(checkbox != null)
- {
- if(protectedMembers == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("netcfCheckbox");
- if(checkbox != null)
- {
- if(netcfMembersOnly == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-
- checkbox = document.getElementById("netXnaCheckbox");
- if(checkbox != null)
- {
- if(netXnaMembersOnly == "on")
- checkbox.checked = true;
- else
- checkbox.checked = false;
- }
-}
-
-/*
-**********
-********** End
-**********
-*/
-
-
-/*
-**********
-********** Begin Language Filtering
-**********
-*/
-
-function SetLanguage(key)
-{
- var i = 0;
- if(vbDeclaration == "on")
- i++;
- if(vbUsage == "on")
- i++;
- if(csLang == "on")
- i++;
- if(cLang == "on")
- i++;
- if(jsharpLang == "on")
- i++;
- if(jsLang == "on")
- i++;
- if(xamlLang == "on")
- i++;
-
- if(key.id == "vbDeclarationCheckbox")
- {
- if(vbDeclaration == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
- vbDeclaration = "off";
- }
- else
- vbDeclaration = "on";
- }
- if(key.id == "vbUsageCheckbox")
- {
- if(vbUsage == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- vbUsage = "off";
- }
- else
- vbUsage = "on";
- }
- if(key.id == "csCheckbox")
- {
- if(csLang == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- csLang = "off";
- }
- else
- csLang = "on";
- }
- if(key.id == "cCheckbox")
- {
- if(cLang == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- cLang = "off";
- }
- else
- cLang = "on";
- }
- if(key.id == "jsharpCheckbox")
- {
- if(jsharpLang == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- jsharpLang = "off";
- }
- else
- jsharpLang = "on";
- }
- if(key.id == "jsCheckbox")
- {
- if(jsLang == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- jsLang = "off";
- }
- else
- jsLang = "on";
- }
- if(key.id == "xamlCheckbox")
- {
- if(xamlLang == "on")
- {
- if(i == 1)
- {
- key.checked = true;
- return;
- }
-
- xamlLang = "off";
- }
- else
- xamlLang = "on";
- }
-
- DisplayLanguages();
-}
-
-function DisplayLanguages()
-{
- var spanElements = document.getElementsByTagName("span");
- var x = 0;
- if(vbDeclaration == "on")
- x++;
- if(vbUsage == "on")
- x++;
- if(csLang == "on")
- x++;
- if(cLang == "on")
- x++;
- if(jsharpLang == "on")
- x++;
- if(jsLang == "on")
- x++;
- if(xamlLang == "on")
- x++;
-
- var i;
- for(i = 0; i < spanElements.length; ++i)
- {
- if(spanElements[i].getAttribute("codeLanguage") != null)
- {
- if(spanElements[i].getAttribute("codeLanguage") == "VisualBasic")
- {
- if(vbDeclaration == "on" || vbUsage == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "VisualBasicDeclaration")
- {
-
- if(vbDeclaration == "on")
- spanElements[i].style.display = "";
- else{
-
- spanElements[i].style.display = "none";
- }
- }
- if(spanElements[i].getAttribute("codeLanguage") == "VisualBasicUsage")
- {
- if(vbUsage == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "CSharp")
- {
- if(csLang == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "ManagedCPlusPlus")
- {
- if(cLang == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "JSharp")
- {
- if(jsharpLang == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "JScript")
- {
- if(jsLang == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
- if(spanElements[i].getAttribute("codeLanguage") == "XAML")
- {
- if(xamlLang == "on")
- spanElements[i].style.display = "";
- else
- spanElements[i].style.display = "none";
- }
-
- if(spanElements[i].getAttribute("codeLanguage") == "NotVisualBasicUsage")
- {
- if((x == 1) && (vbUsage == "on"))
- {
- spanElements[i].style.display = "none";
- }
- else
- {
- spanElements[i].style.display = "";
- }
- }
- }
- }
- ChangeLanguageFilterLabel();
-}
-
-function ChangeLanguageFilterLabel()
-{
- var i = 0;
- if(vbDeclaration == "on")
- i++;
- if(vbUsage == "on")
- i++;
- if(csLang == "on")
- i++;
- if(cLang == "on")
- i++;
- if(jsharpLang == "on")
- i++;
- if(jsLang == "on")
- i++;
- if(xamlLang == "on")
- i++;
-
- var labelElement;
-
- labelElement = document.getElementById("showAllLabel");
-
- if(labelElement == null)
- return;
-
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("multipleLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("vbLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("csLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("cLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("jsharpLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("jsLabel");
- labelElement.style.display = "none";
-
- labelElement = document.getElementById("xamlLabel");
- labelElement.style.display = "none";
-
- if(i == 7)
- {
- labelElement = document.getElementById("showAllLabel");
- labelElement.style.display = "inline";
- }
- else if ((i > 1) && (i < 7))
- {
- if((i == 2) && ((vbDeclaration == "on") && (vbUsage == "on")))
- {
- labelElement = document.getElementById("vbLabel");
- labelElement.style.display = "inline";
- }
- else
- {
- labelElement = document.getElementById("multipleLabel");
- labelElement.style.display = "inline";
- }
- }
- else if (i == 1)
- {
- if(vbDeclaration == "on" || vbUsage == "on")
- {
- labelElement = document.getElementById("vbLabel");
- labelElement.style.display = "inline";
- }
- if(csLang == "on")
- {
- labelElement = document.getElementById("csLabel");
- labelElement.style.display = "inline";
- }
- if(cLang == "on")
- {
- labelElement = document.getElementById("cLabel");
- labelElement.style.display = "inline";
- }
- if(jsharpLang == "on")
- {
- labelElement = document.getElementById("jsharpLabel");
- labelElement.style.display = "inline";
- }
- if(jsLang == "on")
- {
- labelElement = document.getElementById("jsLabel");
- labelElement.style.display = "inline";
- }
- if(xamlLang == "on")
- {
- labelElement = document.getElementById("xamlLabel");
- labelElement.style.display = "inline";
- }
- }
-}
-
-function LoadLanguages()
-{
- var value;
- value = Load("vbDeclaration");
- if(value == null)
- vbDeclaration = "on";
- else
- vbDeclaration = value;
-
- value = Load("vbUsage");
- if(value == null)
- vbUsage = "on";
- else
- vbUsage = value;
-
- value = Load("csLang");
- if(value == null)
- csLang = "on";
- else
- csLang = value;
-
- value = Load("cLang");
- if(value == null)
- cLang = "on";
- else
- cLang = value;
-
- value = Load("jsharpLang");
- if(value == null)
- jsharpLang = "on";
- else
- jsharpLang = value;
-
- value = Load("jsLang");
- if(value == null)
- jsLang = "on";
- else
- jsLang = value;
-
- value = Load("xamlLang");
- if(value == null)
- xamlLang = "on";
- else
- xamlLang = value;
-}
-
-function SaveLanguages()
-{
- Save("vbDeclaration", vbDeclaration);
- Save("vbUsage", vbUsage);
- Save("csLang", csLang);
- Save("cLang", cLang);
- Save("jsharpLang", jsharpLang);
- Save("jsLang", jsLang);
- Save("xamlLang", xamlLang);
-}
-
-/*
-**********
-********** End Language Filtering
-**********
-*/
-
-
-/*
-**********
-********** Begin Members Options Filtering
-**********
-*/
-
-function SetMembersOptions(key)
-{
- if(key.id == "inheritedCheckbox")
- {
- if(key.checked == true)
- inheritedMembers = "on";
- else
- inheritedMembers = "off";
- }
- if(key.id == "protectedCheckbox")
- {
- if(key.checked == true)
- protectedMembers = "on";
- else
- protectedMembers = "off";
- }
- if(key.id == "netcfCheckbox")
- {
- if(key.checked == true)
- netcfMembersOnly = "on";
- else
- netcfMembersOnly = "off";
- }
- if(key.id == "netXnaCheckbox")
- {
- if(key.checked == true)
- netXnaMembersOnly = "on";
- else
- netXnaMembersOnly = "off";
- }
- DisplayFilteredMembers();
-
- ChangeMembersOptionsFilterLabel();
-}
-
-function DisplayFilteredMembers()
-{
- var iAllMembers = document.getElementsByTagName("tr");
- var i;
-
- for(i = 0; i < iAllMembers.length; ++i)
- {
- if (((iAllMembers[i].getAttribute("protected") == "true") && (protectedMembers == "off")) ||
- ((iAllMembers[i].notSupportedOnXna == "true") && (netXnaMembersOnly == "on")) ||
- ((iAllMembers[i].getAttribute("name") == "inheritedMember") && (inheritedMembers == "off")) ||
- ((iAllMembers[i].getAttribute("notSupportedOn") == "netcf") && (netcfMembersOnly == "on")))
- iAllMembers[i].style.display = "none";
- else
- iAllMembers[i].style.display = "";
- }
-}
-
-function ChangeMembersOptionsFilterLabel()
-{
-
- var showAllMembersLabelElement = document.getElementById("showAllMembersLabel");
- var filteredMembersLabelElement = document.getElementById("filteredMembersLabel");
-
- if(showAllMembersLabelElement == null || filteredMembersLabelElement == null)
- return;
-
- if ((inheritedMembers=="off") || (protectedMembers=="off") || (netXnaMembersOnly == "on") || (netcfMembersOnly=="on"))
- {
- filteredMembersLabelElement.style.display = "inline";
- showAllMembersLabelElement.style.display = "none";
- }
- else
- {
- filteredMembersLabelElement.style.display = "none";
- showAllMembersLabelElement.style.display = "inline";
- }
-}
-
-function LoadMembersOptions()
-{
- var value;
- value = Load("inheritedMembers");
- if(value == null)
- inheritedMembers = "on";
- else
- inheritedMembers = value;
-
- value = Load("protectedMembers");
- if(value == null)
- protectedMembers = "on";
- else
- protectedMembers = value;
-
- value = Load("netcfMembersOnly");
- if(value == null)
- netcfMembersOnly = "off";
- else
- netcfMembersOnly = value;
-
- value = Load("netXnaMembersOnly");
- if(value == null)
- netXnaMembersOnly = "off";
- else
- netXnaMembersOnly = value;
-}
-
-function SaveMembersOptions()
-{
- Save("inheritedMembers", inheritedMembers);
- Save("protectedMembers", protectedMembers);
- Save("netcfMembersOnly", netcfMembersOnly);
- Save("netXnaMembersOnly", netXnaMembersOnly);
-}
-
-/*
-**********
-********** End Members Options Filtering
-**********
-*/
-
-
-/*
-**********
-********** Begin Expand/Collapse
-**********
-*/
-
-// expand or collapse a section
-function ExpandCollapse(imageItem)
-{
- if (sectionStates[imageItem.id] == "e")
- CollapseSection(imageItem);
- else
- ExpandSection(imageItem);
-
- SetCollapseAll();
-}
-
-// expand or collapse all sections
-function ExpandCollapseAll(imageItem)
-{
- var collapseAllImage = document.getElementById("collapseAllImage");
- var expandAllImage = document.getElementById("expandAllImage");
- if (imageItem == null || collapseAllImage == null || expandAllImage == null) return;
- noReentry = true; // Prevent entry to OnLoadImage
-
- var imgElements = document.getElementsByName("toggleSwitch");
- var i;
- var collapseAll = (imageItem.src == collapseAllImage.src);
- if (collapseAll)
- {
- imageItem.src = expandAllImage.src;
- imageItem.alt = expandAllImage.alt;
-
- for (i = 0; i < imgElements.length; ++i)
- {
- CollapseSection(imgElements[i]);
- }
- }
- else
- {
- imageItem.src = collapseAllImage.src;
- imageItem.alt = collapseAllImage.alt;
-
- for (i = 0; i < imgElements.length; ++i)
- {
- ExpandSection(imgElements[i]);
- }
- }
- SetAllSectionStates(collapseAll);
- SetToggleAllLabel(collapseAll);
-
- noReentry = false;
-}
-
-function ExpandCollapse_CheckKey(imageItem, eventObj)
-{
- if(eventObj.keyCode == 13)
- ExpandCollapse(imageItem);
-}
-
-function ExpandCollapseAll_CheckKey(imageItem, eventObj)
-{
- if(eventObj.keyCode == 13)
- ExpandCollapseAll(imageItem);
-}
-
-function SetAllSectionStates(collapsed)
-{
- for (var sectionId in sectionStates)
- sectionStates[sectionId] = (collapsed) ? "c" : "e";
-}
-
-function ExpandSection(imageItem)
-{
- noReentry = true; // Prevent re-entry to OnLoadImage
- try
- {
- var collapseImage = document.getElementById("collapseImage");
- imageItem.src = collapseImage.src;
- imageItem.alt = collapseImage.alt;
-
- imageItem.parentNode.parentNode.nextSibling.style.display = "";
- sectionStates[imageItem.id] = "e";
- }
- catch (e)
- {
- }
- noReentry = false;
-}
-
-function CollapseSection(imageItem)
-{
- noReentry = true; // Prevent re-entry to OnLoadImage
- var expandImage = document.getElementById("expandImage");
- imageItem.src = expandImage.src;
- imageItem.alt = expandImage.alt;
- imageItem.parentNode.parentNode.nextSibling.style.display = "none";
- sectionStates[imageItem.id] = "c";
- noReentry = false;
-}
-
-function AllCollapsed()
-{
- var imgElements = document.getElementsByName("toggleSwitch");
- var allCollapsed = true;
- var i;
-
- for (i = 0; i < imgElements.length; i++) allCollapsed = allCollapsed && (sectionStates[imgElements[i].id] == "c");
-
- return allCollapsed;
-}
-
-function SetCollapseAll()
-{
- var imageElement = document.getElementById("toggleAllImage");
- if (imageElement == null) return;
-
- var allCollapsed = AllCollapsed();
- if (allCollapsed)
- {
- var expandAllImage = document.getElementById("expandAllImage");
- if (expandAllImage == null) return;
- imageElement.src = expandAllImage.src;
- imageElement.alt = expandAllImage.alt;
- }
- else
- {
- var collapseAllImage = document.getElementById("collapseAllImage");
- if (collapseAllImage == null) return;
- imageElement.src = collapseAllImage.src;
- imageElement.alt = collapseAllImage.alt;
- }
-
- SetToggleAllLabel(allCollapsed);
-}
-
-function SetToggleAllLabel(allCollapsed)
-{
- var collapseLabelElement = document.getElementById("collapseAllLabel");
- var expandLabelElement = document.getElementById("expandAllLabel");
-
- if (collapseLabelElement == null || expandLabelElement == null) return;
-
- if (allCollapsed)
- {
- collapseLabelElement.style.display = "none";
- expandLabelElement.style.display = "inline";
- }
- else
- {
- collapseLabelElement.style.display = "inline";
- expandLabelElement.style.display = "none";
- }
-}
-
-function SaveSections()
-{
- try
- {
- var states = "";
-
- for (var sectionId in sectionStates) states += sectionId + ":" + sectionStates[sectionId] + ";";
-
- Save("SectionStates", states.substring(0, states.length - 1));
- }
- catch (e)
- {
- }
-
-}
-
-function OpenSection(imageItem)
-{
- if (sectionStates[imageItem.id] == "c") ExpandCollapse(imageItem);
-}
-
-/*
-**********
-********** End Expand/Collapse
-**********
-*/
-
-
-
-/*
-**********
-********** Begin Copy Code
-**********
-*/
-
-function CopyCode(key)
-{
- var trElements = document.getElementsByTagName("tr");
- var i;
- for(i = 0; i < trElements.length; ++i)
- {
- if(key.parentNode.parentNode.parentNode == trElements[i].parentNode)
- {
- if (window.clipboardData)
- {
- // the IE-manner
- window.clipboardData.setData("Text", trElements[i].innerText);
- }
- else if (window.netscape)
- {
- // Gives unrestricted access to browser APIs using XPConnect
- try
- {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- }
- catch(e)
- {
- alert("Universal Connect was refused, cannot copy to " +
- "clipboard. Go to about:config and set " +
- "signed.applets.codebase_principal_support to true to " +
- "enable clipboard support.");
- return;
- }
-
- // Creates an instance of nsIClipboard
- var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
- if (!clip) return;
-
- // Creates an instance of nsITransferable
- var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
- if (!trans) return;
-
- // register the data flavor
- trans.addDataFlavor('text/unicode');
-
- // Create object to hold the data
- var str = new Object();
-
- // Creates an instance of nsISupportsString
- var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
-
- //Assigns the data to be copied
- var copytext = trElements[i].textContent;
- str.data = copytext;
-
- // Add data objects to transferable
- trans.setTransferData("text/unicode",str,copytext.length*2);
- var clipid = Components.interfaces.nsIClipboard;
- if (!clip) return false;
-
- // Transfer the data to clipboard
- clip.setData(trans,null,clipid.kGlobalClipboard);
- }
- }
- }
-}
-
-function ChangeCopyCodeIcon(key)
-{
- var i;
- var imageElements = document.getElementsByName("ccImage")
- for(i=0; i<imageElements.length; ++i)
- {
- if(imageElements[i].parentNode == key)
- {
- if(imageElements[i].src == copyImage.src)
- {
- imageElements[i].src = copyHoverImage.src;
- imageElements[i].alt = copyHoverImage.alt;
- key.className = 'copyCodeOnHover';
- }
- else
- {
- imageElements[i].src = copyImage.src;
- imageElements[i].alt = copyImage.alt;
- key.className = 'copyCode';
- }
- }
- }
-}
-
-function CopyCode_CheckKey(key, eventObj)
-{
- if(eventObj.keyCode == 13)
- CopyCode(key);
-}
-
-/*
-**********
-********** End Copy Code
-**********
-*/
-
-
-/*
-**********
-********** Begin Maintain Scroll Position
-**********
-*/
-
-function loadAll(){
- try
- {
- scrollPos = allHistory.getAttribute("Scroll");
- }
- catch(e){}
-}
-
-function saveAll(){
- try
- {
- allHistory.setAttribute("Scroll", mainSection.scrollTop);
- }
- catch(e){}
-}
-
-/*
-**********
-********** End Maintain Scroll Position
-**********
-*/
-
-
-/*
-**********
-********** Begin Send Mail
-**********
-*/
-
-function formatMailToLink(anchor)
-{
- var release = "Release: " + anchor.doc_Release;
- var topicId = "Topic ID: " + anchor.doc_TopicID;
- var topicTitle = "Topic Title: " + anchor.doc_TopicTitle;
- var url = "URL: " + document.URL;
- var browser = "Browser: " + window.navigator.userAgent;
-
- var crlf = "%0d%0a";
- var body = release + crlf + topicId + crlf + topicTitle + crlf + url + crlf + browser + crlf + crlf + "Comments:" + crlf + crlf;
-
- anchor.href = anchor.href + "&body=" + body;
-}
-
-/*
-**********
-********** End Send Mail
-**********
-*/
-
-
-/*
-**********
-********** Begin Persistence
-**********
-*/
-
-var globals;
-
-function GetGlobals()
-{
- var tmp;
-
- // Try to get VS implementation
- try { tmp = window.external.Globals; }
- catch (e) { tmp = null; }
-
- // Try to get DExplore implementation
- try { if (tmp == null) tmp = window.external.GetObject("DTE", "").Globals; }
- catch (e) { tmp = null; }
-
- return tmp;
-}
-
-function Load(key)
-{
- try
- {
- return globals.VariableExists(key) ? globals.VariableValue(key) : null;
- }
- catch (e)
- {
- return null;
- }
-}
-
-function Save(key, value)
-{
- try
- {
- globals.VariableValue(key) = value;
- globals.VariablePersists(key) = true;
- }
- catch (e)
- {
- }
-}
-
-/*
-**********
-********** End Persistence
-**********
-*/
-
-/* This is the part for Glossary popups */
-// The method is called when the user positions the mouse cursor over a glossary term in a document.
-// Current implementation assumes the existence of an associative array (g_glossary).
-// The keys of the array correspond to the argument passed to this function.
-
-var bGlossary=true;
-var oDialog;
-var oTimeout="";
-var oTimein="";
-var iTimein=.5;
-var iTimeout=30;
-var oLastNode;
-var oNode;
-var bInit=false;
-var aTerms=new Array();
-
-// Called from mouseover and when the contextmenu behavior fires oncontextopen.
-function clearDef(eventObj){
- if(eventObj){
- var elem;
- if(document.all) elem = eventObj.toElement;
- else elem = eventObj.relatedTarget;
- if(elem!=null || elem!="undefined"){
- if(typeof(oTimein)=="number"){
- window.clearTimeout(oTimein);
- }
- if(oDialog.dlg_status==true){
- hideDef();
- }
- }
- }
-}
-function hideDef(eventObj){
- window.clearTimeout(oTimeout);
- oTimeout="";
- oDialog.style.display="none";
- oDialog.dlg_status=false;
-}
-function showDef(oSource){
- if(bInit==false){
- glossaryInit();
- bInit=true;
- }
- if(bGlossary==true){
- if(typeof(arguments[0])=="object"){
- oNode=oSource;
- }
- else{
- if(document.all) oNode = eventObj.srcElement;
- else oNode = eventObj.target;
- }
- var bStatus=oDialog.dlg_status; // BUGBUG: oDialog is null.
- if((oLastNode!=oNode)||(bStatus==false)){
- if((typeof(oTimein)=="number")&& eventObj){
-
- var elem;
- if(document.all) elem = eventObj.fromElement;
- else elem = eventObj.relatedTarget;
-
- if( elem != null || elem != "undefined")
- window.clearTimeout(oTimein);
- }
- oTimein=window.setTimeout("openDialog(oNode)",iTimein*1000);
- }
- }
-}
-
-
-
-function glossaryInit(){
- oDialog=fnCreateDialog(150,50);
-}
-
-function navigateTerm(eventObj){
- var oNode;
- if(document.all) oNode = eventObj.srcElement;
- else oNode = eventObj.target;
-
- var iTermID=oNode.termID;
- if(oNode!=aTerms[iTermID]){
- var iAbsTop=getAbsoluteTop(aTerms[iTermID]);
- if(iAbsTop<document.body.scrollTop){
- window.scrollTo(document.body.scrollLeft,getAbsoluteTop(aTerms[iTermID]));
- }
- openDialog(aTerms[iTermID]);
- }
-}
-function disableGlossary(eventObj){
- if(bGlossary==true){
- if(document.all) eventObj.srcElement.innerText="Enable Automatic Glossary";
- else eventObj.target.innerText="Enable Automatic Glossary";
- bGlossary=false;
- hideDef();
- }
- else{
- if(document.all) eventObj.srcElement.innerText="Disable Automatic Glossary";
- else eventObj.target.innerText="Disable Automatic Glossary";
- bGlossary=true;
- }
-}
-function openGlossary(){
-
-}
-function fnSetMenus(eventObj){
- var oNode;
- if(document.all) oNode = eventObj.srcElement;
- else oNode = eventObj.target;
-
- var oMenu=oNode.createMenu("SPAN","G_RID");
- var oSubItem1=oNode.createMenuItem("Glossary",fnStub,oMenu,true);
- document.body.createMenuItem("Open External Glossary",openGlossary,oSubItem1.subMenu);
- document.body.createMenuItem("Disable Automatic Glossary",disableGlossary,oSubItem1.subMenu);
- for(var i=0;i<aTerms.length;i++){
- var oItem=document.body.createMenuItem(aTerms[i].innerText,navigateTerm,oMenu);
- oItem.termID=i;
- }
-}
-// This is a bogus stub. It should be sniffed out rather than added in.
-function fnStub(){
-
-}
-function fnAttachMenus(aTips){
- // This walk is only necessary for the context menu.
- var aTips=document.getElementsByTagName("SPAN");
- for(var i=0;i<aTips.length;i++){
- var oNode=aTips[i];
- if(oNode.getAttribute("G_RID")){
- var sTerm=oNode.getAttribute("G_RID");
- if(typeof(g_glossary[sTerm])=="string"){
- // Removed client-side scripting to add events. This entire process should be singled out for IE 5 and later .. and, its only for the context menu.
- aTerms[aTerms.length]=oNode;
- }
- }
- }
- if(oBD.majorVer>=5){
- document.body.addBehavior(gsContextMenuPath);
- document.body.onbehaviorready="fnSetMenus()";
- document.body.oncontextopen="clearDef()";
- }
-
-}
-// Called by showDef. The showDef function sniffs for initialization.
-function openDialog(oNode,x,y){
- var bStatus=oDialog.dlg_status; // BUGBUG: This code assumes that oDialog has been initialized
- if(bStatus==false){
- oDialog.dlg_status=true;
- oDialog.style.display="block";
- }
- else{
- if(typeof(oTimeout)=="number"){
- window.clearTimeout(oTimeout);
- }
- }
-
- var sTerm=oNode.getAttribute("G_RID");
- var oDef=oNode.children(0);
- var sDef=oDef.text;
- sDef=sDef.substr(4,sDef.length-7); //Strips the html comment markers from the definition.
- oDialog.innerHTML=sDef
-
-
- //oDialog.innerHTML=g_glossary[sTerm];
-
- var iScrollLeft=document.body.scrollLeft;
- var iScrollTop=document.body.scrollTop;
- var iOffsetLeft=getAbsoluteLeft(oNode)// - iScrollLeft;
- var iOffsetWidth=oNode.offsetWidth;
- var oParent=oNode.parentNode;
- var iOffsetParentLeft=getAbsoluteLeft(oParent);
- var iOffsetTop=getAbsoluteTop(oNode); //- iScrollTop;
- var iOffsetDialogWidth=oDialog.offsetWidth;
-
-
- if((iOffsetLeft + iOffsetWidth) > (iOffsetParentLeft + oParent.offsetWidth)){
- iOffsetLeft=iOffsetParentLeft;
- if(iOffsetLeft - iOffsetDialogWidth>0){
- iOffsetTop+=oNode.offsetHeight;
- }
- }
- var iLeft=0;
- var iTop=0;
- if((iOffsetLeft + iOffsetWidth - iScrollLeft + iOffsetDialogWidth) < document.body.offsetWidth ){
- iLeft=iOffsetLeft + iOffsetWidth;
- }
- else{
- if(iOffsetLeft - iOffsetDialogWidth>0){
- iLeft=iOffsetLeft - iOffsetDialogWidth;
- }
- else{
- iLeft=iOffsetParentLeft;
- }
- }
- if(iOffsetTop - iScrollTop<oDialog.offsetHeight){
- iTop=iOffsetTop + oNode.offsetHeight;
- }
- else{
- iTop=iOffsetTop - oDialog.offsetHeight;
- }
- oDialog.style.top=iTop;
- oDialog.style.left=iLeft;
- oTimeout=window.setTimeout("hideDef()",iTimeout*1000);
-}
-function getAbsoluteTop(oNode){
- var oCurrentNode=oNode;
- var iTop=0;
- while(oCurrentNode.tagName!="BODY"){
- iTop+=oCurrentNode.offsetTop;
- oCurrentNode=oCurrentNode.offsetParent;
- }
- return iTop;
-}
-function getAbsoluteLeft(oNode){
- var oCurrentNode=oNode;
- var iLeft=0;
- while(oCurrentNode.tagName!="BODY"){
- iLeft+=oCurrentNode.offsetLeft;
- oCurrentNode=oCurrentNode.offsetParent;
- }
- return iLeft;
-}
-function fnCreateDialog(iWidth,iHeight){
- document.body.insertAdjacentHTML("BeforeEnd","<DIV></DIV>");
- oNewDialog=document.body.children(document.body.children.length-1);
- oNewDialog.className="clsTooltip";
- oNewDialog.style.width=iWidth;
- oNewDialog.dlg_status=false;
- return oNewDialog;
-}
-
-function sendfeedback(subject, id,alias){
- var rExp = /\"/gi;
- var url = location.href;
- // Need to replace the double quotes with single quotes for the mailto to work.
- var rExpSingleQuotes = /\'\'"/gi;
-
- var title;
- if(document.getElementsByTagName("TITLE")[0].innerText) title = document.getElementsByTagName("TITLE")[0].innerText.replace(rExp, "''")
- else title = document.getElementsByTagName("TITLE")[0].textContent.replace(rExp, "''");
- location.href = "mailto:" + alias + "?subject=" + subject + title + "&body=Topic%20ID:%20" + id + "%0d%0aURL:%20" + url + "%0d%0a%0d%0aComments:%20";
-}
diff --git a/tools/Sandcastle/Presentation/hana/Styles/Presentation.css b/tools/Sandcastle/Presentation/hana/Styles/Presentation.css
deleted file mode 100644
index 0a01db1..0000000
--- a/tools/Sandcastle/Presentation/hana/Styles/Presentation.css
+++ /dev/null
@@ -1,934 +0,0 @@
-/* * * This file was autogenerated by Styler at 02:02 on 02/15/2003 * * */
-
-@import url("tabs.css");
-@import url("syntax.css");
-
-/***********************************************************
- * SCRIPT-SUPPORTING STYLES
- ***********************************************************/
-
-/* Defines the userData cache persistence mechanism. */
-.userDataStyle
-{
- behavior: url(#default#userData);
-}
-
-/* Used to save the scroll bar position when navigating away from a page. */
-div.saveHistory
-{
- behavior: url(#default#saveHistory);
-}
-
-/* Formats the expand/collapse images for all collapsible regions. */
-img.toggle
-{
- border: 0px;
- margin-right: 5px;
-}
-
-/* Formats the Language filter drop-down image. */
-img#languageFilterImage
-{
- border: 0px;
- margin-left: 0px;
- vertical-align: middle;
-}
-
-/* Formats the Members Options filter drop-down image. */
-img#membersOptionsFilterImage
-{
- border: 0px;
- margin-left: 0px;
- vertical-align: middle;
-}
-
-/* Formats the Collapse All/Expand All images. */
-img#toggleAllImage
-{
- margin-left: 0px;
- vertical-align: middle;
-}
-
-/* Supports XLinks */
-MSHelp\:link
-{
- text-decoration: underline;
- /*color: #0000ff; */
- color: #0481DA;
- hoverColor: #3366ff;
- filterString: ;
-}
-
-
-/***********************************************************
- * CONTENT PRESENTATION STYLES
- ***********************************************************/
-
-body
-{
- background: #FFFFFF;
- color: #000000;
- font-family: Verdana;
- font-size: medium;
- font-style: normal;
- font-weight: normal;
- margin: 0px;
- width: 100%;
-}
-
-dl
-{
- margin-top: 15px;
- margin-bottom:5px;
- padding-left: 1px;
-}
-
-/*dt
-{
- font-style: italic;
-}*/
-
-dd
-{
- margin-left: 0px;
-}
-
-ul
-{
- margin-top:0px;
- margin-bottom:0px;
- margin-left: 17px;
- list-style-type: disc;
-}
-
-ul ul
-{
- margin-bottom: 4px;
- margin-left: 17px;
- margin-top: 3px;
- list-style-type: disc;
-}
-
-ol
-{
- margin-top:0px;
- margin-bottom:0px;
- margin-left: 28px;
- list-style-type: decimal;
-}
-
-ol ol
-{
- margin-bottom: 4px;
- margin-left: 28px;
- margin-top: 3px;
- list-style-type: lower-alpha;
-}
-
-li
-{
- margin-top: 5;
- margin-bottom: 5;
-}
-
-p
-{
- margin-top: 10px;
- margin-bottom: 5px;
-}
-a[href]
-{
- color: #0481DA;
-}
-a
-{
- color:#0481DA;
-}
-
-a:visited
-{
- color: #0481DA;
-}
-
-a:hover
-{
- /*color: #3366FF;*/
- color: #E85F17;
-}
-
-code
-{
- font-family: Monospace, Courier New, Courier;
- font-size: 105%;
- color: #000066;
-}
-
-span.parameter {
- font-style: italic;
- font-weight:bold;
-}
-
-span.italic {
- font-style: italic;
-}
-
-span.referenceNoLink {
- font-weight: bold;
-}
-span.nolink {
- font-weight: bold;
-}
-
-span.selflink {
- font-weight: bold;
-}
-
-span.nonLinkTerm {
- font-weight: bold;
-}
-span.linkTerm {
- font-weight:normal;
-}
-
-/***********************************************************
- * STRUCTURE PRESENTATION STYLES
- ***********************************************************/
-
-/* Applies to everything below the non-scrolling header region. */
-div#mainSection
-{
- font-size: 62.5%;
- width: 100%;
- overflow:hidden;
-}
-html>body #mainSection
-{
- font-size:73%;
- width: 100%;
-}
-
-/* Applies to everything below the non-scrolling header region, minus the footer. */
-div#mainBody
-{
- font-size: 100%;
- margin-left: 15px;
- margin-top: 10px;
- padding-bottom: 20px;
- overflow:hidden;
-}
-
-html>body #mainBody
-{
- font-size: 93%;
- margin-left: 15px;
- margin-top: 10px;
- padding-bottom: 20px;
-}
-
-/* Adds right padding for all blocks in mainBody */
-div#mainBody p, div#mainBody ol, div#mainBody ul, div#mainBody dl
-{
- padding-right: 5px;
-}
-
-/*------------------------------ Begin Non-scrolling Header Region Styles -------------------------------*/
-/* Applies to the entire non-scrolling header region. */
-div#header
-{
- background-color: white;
- padding-top: 0px;
- padding-bottom: 0px;
- padding-left: 0px;
- padding-right: 0px;
- width: 100%;
-}
-
-/* Applies to both tables in the non-scrolling header region. */
-div#header table
-{
- width: 100%;
-}
-
-/* Applies to cells in both tables in the non-scrolling header region. */
-div#header table td
-{
- /*color: #0000FF;*/
- color:#0481DA;
- font-size: 70%;
- margin-top: 0px;
- margin-bottom: 0;
- padding-right: 20;
-}
-
-/* Applies to the last row in the upper table of the non-scrolling header region. Text
- in this row includes See Also, Constructors, Methods, and Properties. */
-div#header table tr#headerTableRow3 td
-{
- padding-bottom: 2px;
- padding-top: 5px;
- padding-left: 15px;
-}
-
-/* Applies to the lower table in the non-scrolling header region. Text in this table
- includes Collapse All/Expand All, Language Filter, and Members Options. */
-div#header table#bottomTable
-{
- border-top-color: #FFFFFF;
- border-top-style: solid;
- border-top-width: 1px;
- text-align: left;
- padding-left: 15px;
-}
-
-/* Formats the first column--the one that displays icons--in mref list tables (such as Public Constructors,
- Protected Constructors, Public Properties, Protected Properties, and so on). */
-div#mainSection table td.imageCell
-{
- white-space: nowrap;
-}
-/*------------------------------ End General Table Styles -------------------------------*/
-
-/*------------------------------ Begin General Table Styles -------------------------------*/
-
-div#mainBody div.alert, div#mainBody div.code, div#mainBody div.tableSection
-{
- width:98.9%;
-}
-
-div#mainBody div.section div.alert, div#mainBody div.section div.code,
-div#mainBody div.section div.tableSection
-{
- width:100%;
-}
-
-div#mainBody div.section ul div.alert, div#mainBody div.section ul div.code,
-div#mainBody div.section ul div.tableSection, div#mainBody div.section ol div.alert,
-div#mainBody div.section ol div.code, div#mainBody div.section ol div.tableSection
-{
- width:100%;
-}
-
-div.alert p, div.code p
-{
- margin-top:5px;
- margin-bottom:8px;
-}
-dd p
-{
- margin-top:2px;
- margin-bottom:8px;
-}
-div.tableSection p
-{
- margin-top:1px;
- margin-bottom:4px;
-}
-li p
-{
- margin-top:2px;
- margin-bottom:2px;
-}
-div.seeAlsoNoToggleSection dl
-{
- margin-top:8px;
- margin-bottom:1px;
- padding-left:1px;
-}
-div.seeAlsoNoToggleSection dd p
-{
- margin-top:2px;
- margin-bottom:8px;
-}
-div.section dl
-{
- margin-top:8px;
- margin-bottom:1px;
- padding-left:1px;
-}
-div.section dd p
-{
- margin-top:2px;
- margin-bottom:8px;
-}
-/*------------------------------ End General Table Styles -------------------------------*/
-
-/* Applies to the running header text in the first row of the upper table in the
- non-scrolling header region. */
-span#runningHeaderText
-{
- color: #495F7F;
- font-size: 90%;
- padding-left: 13px;
-}
-
-/* Applies to the topic title in the second row of the upper table in the
- non-scrolling header region. */
-span#nsrTitle
-{
- color: #495F7F;
- font-size: 120%;
- font-weight: 600;
- padding-left: 13px;
-}
-/*------------------------------ End Non-scrolling Header Region Styles -------------------------------*/
-
-
-/* Formats the footer. Currently, the transforms pass in two parameters to the
- footer SSC, but the default footer SSC doesn't use either parameter.
- TODO: Investigate whether the default footer SSC has any impact on doc spec. */
-div#footer
-{
- font-size: 80%;
- margin: 0px;
- padding-top: 8px;
- padding-bottom: 6px;
- padding-left: 5px;
- padding-right: 2px;
- width: 100%;
-}
-
-html>body div#footer
-{
- font-size: 80%;
- margin: 0px;
- padding-top: 2px;
- padding-bottom: 6px;
- padding-left: 5px;
- padding-right: 2px;
- width: 98%;
-}
-
-/* Unable to find this style in the transforms. The default footer SSC adds a plain horizontal rule.
- TODO: Determine whether this style is required by the doc spec. */
-/*
-hr#footerHR
-{
- border-bottom-color: #EEEEFF;
- border-bottom-style: solid;
- border-bottom-width: 1px;
- border-top-color: C8CDDE;
- border-top-style: solid;
- border-top-width: 1px;
- height: 3px;
- color: #D4DFFF;
-}
-*/
-
-/********************************************************************************************************************
- Collapsible Section Structure
-
- <h1 class="heading"> // Format of the collapsible section text
- <span onclick="ExpandCollapse(xxxToggle)"> // Defines the onclick procedure for the expand/collapse section
- <img id="xxxToggle"> // Expand/collapse image
- </img>
- </span>
- </h1>
-
- <div id="xxxSection" class="section"> // The body of the collapsible section; hidden by default
- </div>
-
-
- The ExpandCollapse() function is responsible for toggling the expand/collapse image, and for
- displaying/hiding the body of the collapsible section.
-********************************************************************************************************************/
-
-/* Applies to the body of a collapsible section */
-div.seeAlsoNoToggleSection
-{
- margin-left:0;
- padding-top: 2px;
- padding-bottom: 2px;
- padding-left: 0px;
- padding-right: 15px;
- width: 100%;
-}
-
-div.section
-{
- margin-left:0px;
- padding-left: 16px;
- padding-right: 15px;
- width: 100%;
-}
-html>body div.section
-{
- margin-left:0px;
- padding-top: 2px;
- padding-bottom: 2px;
- padding-left: 16px;
- padding-right: 15px;
- width: 97%;
-}
-div.seeSection
-{
- margin-left:0px;
- padding-top: 0px;
- padding-bottom: 2px;
- padding-left: 16px;
- padding-right: 15px;
- width: 100%;
-}
-
-/*------------------------------ Begin Heading Styles -------------------------------*/
-/* As far as I can tell, only <h1> tags use this class.
- TODO: Decide whether to roll these attributes into the h1.heading style */
-.heading
-{
- font-weight: bold;
- margin-top: 18px;
- margin-bottom: 8px;
-}
-
-/* All <h1> headings. */
-h1.heading
-{
- color: #0481DA;
- font-size: 130%;
-}
-
-/* Applies to table titles and subsection titles. */
-.subHeading
-{
- font-weight: bold;
- margin-bottom: 4px;
-}
-.procedureSubHeading
-{
- font-weight: bold;
- margin-bottom: 4px;
-}
-
-/* Formats the titles of author-generated tables. */
-h3.subHeading
-{
- color: #000000;
- font-size: 120%;
- font-weight:800;
-}
-
-h3.procedureSubHeading
-{
- color: #0481DA;
- font-size: 120%;
-}
-
-/* Formats the titles of all subsections. */
-h4.subHeading
-{
- color: #000000;
- font-size: 110%;
- font-weight:800;
-}
-span.labelheading, div.labelheading
-{
- font-size:100%;
- color: #0481DA;
-}
-
-/*------------------------------ End Heading Styles -------------------------------*/
-
-
-/*------------------------------ Begin Image Styles -------------------------------*/
-img.copyCodeImage
-{
- border: 0px;
- margin: 1px;
- margin-right: 3px;
-}
-
-img.downloadCodeImage
-{
- border: 0px;
- margin-right: 3px;
-}
-
-img.viewCodeImage
-{
- border: 0px;
- margin-right: 3px;
-}
-
-img.note
-{
- border: 0px;
- margin-right: 3px;
-}
-/*------------------------------ End Image Styles -------------------------------*/
-
-/*------------------------------ Begin Note Styles -------------------------------*/
-div.alert table
-{
- border: 0px;
- font-size: 100%;
- width: 100%;
-}
-
-div.alert table th
-{
- background: #EFEFF7;
- border-bottom-width: 0px;
- color: #000066;
- padding-left: 5px;
- padding-right: 5px;
-}
-
-div.alert table td
-{
- background: #F7F7FF;
- border-top-color: #FFFFFF;
- border-top-style: solid;
- border-top-width: 1px;
- padding-left: 5px;
- padding-right: 5px;
-}
-
-
-/*------------------------------ End Note Styles -------------------------------*/
-
-
-/* Applies to the copy code text and image. */
-span.copyCode
-{
- color: #0481DA;
- font-size:xx-small;
- font-weight: normal;
- cursor: pointer;
- float: left;
- display: inline;
- text-align: left;
- padding-bottom:10px;
-}
-span.copyCodeOnHover
-{
- color: #E85F17;
- font-size:xx-small;
- font-weight: normal;
- cursor: pointer;
- float: left;
- display: inline;
- text-align: left;
- padding-bottom:10px;
- text-decoration: underline;
-}
-
-.downloadCode
-{
- color: #0000ff;
- font-size: 90%;
- font-weight: normal;
- cursor: pointer;
-}
-
-.viewCode
-{
- color: #0000ff;
- font-size: 90%;
- font-weight: normal;
- cursor: pointer;
-}
-
-/* Formats parameter tooltips. */
-.tip
-{
- color: #0000FF;
- font-style: italic;
- cursor: pointer;
- text-decoration:underline;
-}
-
-/* Applies to the language labels in the Language Filter drop-down list. */
-.languageFilter
-{
- color: #0000FF;
- cursor: pointer;
- text-decoration:underline;
- padding-bottom:4px;
-}
-
-/* Applies to text styled as math. This text is passed as a parameter to the italics SSC definition */
-.math
-{
- font-family: Times New Roman;
- font-size: 125%
-}
-
-/* The sourceCodeList class doesn't appear in the transforms.
- TODO: Find out whether this style is needed for the doc spec. */
-/*
-.sourceCodeList
-{
- font-family: Verdana;
- font-size: 90%;
-}
-*/
-
-/* The viewCode class doesn't appear in the transforms.
- TODO: Find out whether this style is needed for the doc spec. */
-/*
-pre.viewCode
-{
- width: 100%;
- overflow: auto;
-}
-*/
-
-/* Dropdown areas */
-
-#languageSpan
-{
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background:white;
- padding: 4px;
- font-size:82.5%;
- }
-
-#membersOptionsSpan {
- position: absolute;
- visibility: hidden;
- border-style: solid;
- border-width: 1px;
- border-color: #C8CDDE;
- background: #d4dfff;
- padding: 4px;
- font-size: 62.5%;
-}
-
-/* Line seperating footer from main body */
-
-div.footerLine {
- margin: 0;
- width: 100%;
- padding-top: 8px;
- padding-bottom: 6px;
- padding-left: 5px;
- padding-right: 2px;
-
-}
-
-div.hr1
-{
- margin: 0px;
- width: 100%;
- height: 1px;
- padding: 0px;
- background: #C8CDDE;
- font-size: 1px;
-}
-
-div.hr2
-{
- margin: 0px;
- width: 100%;
- height: 1px;
- padding: 0px;
- background: #D4DFFF;
- font-size: 1px;
-}
-
-div.hr3
-{
- margin: 0px;
- width: 100%;
- height: 1px;
- padding: 0px;
- background: #EEEEFF;
- font-size: 1px;
-}
-
-span.cs
-{
- display: none;
-}
-
-span.vb
-{
- display: inline;
-}
-
-span.cpp
-{
- display: none;
-}
-
-span.nu
-{
- display: none;
-}
-
-span.code
-{
- font-family: Monospace, Courier New, Courier;
- font-size: 105%;
- color: #000066;
-}
-span.ui
-{
- font-weight: bold;
-}
-span.math
-{
- font-style: italic;
-}
-span.input
-{
- font-weight: bold;
-}
-span.term
-{
- font-style: italic;
-}
-span.label
-{
- font-weight: bold;
-}
-span.foreignPhrase
-{
- font-style: italic;
-}
-span.placeholder
-{
- font-style: italic;
-}
-span.keyword
-{
- font-weight: bold;
-}
-span.typeparameter
-{
- font-style:italic;
-}
-
-div.caption
-{
- font-weight: bold;
- font-size:100%;
- color:#003399;
-}
-
-div.code
-{
- clear: both;
- width: 100%;
- background: #E3E6EB;
- padding: 0.4em;
- font-family: "Andale Mono", "Courier New", Courier, monospace;
- font-size: 9pt;
- margin-bottom: 1em;
- border-bottom:solid 1px #bfc2c7;
- border-right:solid 1px #bfc2c7;
- display:block;
- background-image:url(../icons/tab_sel_lft_grad.gif);
- background-repeat:repeat-y;
-}
-
-div.memberSection
-{
- background: #E3E6EB;
- border-bottom:solid 1px #bfc2c7;
- border-right:solid 1px #bfc2c7;
- padding:8px;
- background-image:url(../icons/tab_sel_lft_grad.gif);
- background-repeat:repeat-y;
- width:100%;
-}
-
-div.listSection
-{
- background: #E3E6EB;
- border-top:solid 1px #bfc2c7;
- border-bottom:solid 1px #bfc2c7;
- border-right:solid 1px #bfc2c7;
- padding:8px;
- background-image:url(../icons/tab_sel_lft_grad.gif);
- background-repeat:repeat-y;
- width:100%;
-}
-
-/* table styles */
-
-table.memberOptions
-{
- font-size:xx-small;
- padding:0px;
-}
-table.members {
- table-layout: fixed;
- background: white;
- padding:0px;
- width:100%;
-}
-
-table.members tr {
- min-height: 20px;
-}
-
-table.members th.iconColumn {
- width: 60px;
-}
-
-table.members th.nameColumn {
- width: 33%;
-}
-
-table.members th.descriptionColumn {
- width: 66%;
-}
-
-table.members th {
- border-color: #c7ced8;
- border-style: solid;
- border-width: 1px;
- background: white;
- text-align: left;
- color: #000066;
- font-weight: bold;
- font-size:xx-small;
-}
-
-table.members td {
- border-style: solid;
- border-color: #c7ced8;
- border-width: 1px;
- background: white;
- vertical-align: top;
- overflow: hidden;
- font-size:xx-small;
-}
-
-div.section table.filter {
- table-layout: fixed;
-}
-
-/* end of table styles */
-
-
-td.line
-{
- width:22em;
-}
-
-td.nsrBottom
-{
- height:0.6em;
-}
-/* end of tab styles */
-
-span.syntaxLabel
-{
- color:#0481DA;
- font-weight:bold;
-}
-
-div.seeAlsoStyle
-{
- padding-top:5px;
-}
-/* end of syntax styles */
-
-/* Glossary */
-SPAN.clsGlossary {cursor: default; color: #509950; font-weight: bold;}
-DIV.clsTooltip {border: 1px solid black; padding: 2px; position: absolute; top: 0; left: 0; display: none; background-color: #FFFFAA; color: black; font-size: 8pt; font-family: Arial;}
diff --git a/tools/Sandcastle/Presentation/hana/Styles/syntax.css b/tools/Sandcastle/Presentation/hana/Styles/syntax.css
deleted file mode 100644
index ec5b4dd..0000000
--- a/tools/Sandcastle/Presentation/hana/Styles/syntax.css
+++ /dev/null
@@ -1,22 +0,0 @@
-
-/* syntax styles */
-
-div.code span.identifier {
- font-weight: bold;
-}
-
-div.code span.keyword {
- color: #0000ff;
-}
-
-div.code span.parameter {
- font-style: italic;
-}
-
-div.code span.literal {
- color: #a31515;
-}
-
-div.code span.comment {
- color: #007f00;
-}
diff --git a/tools/Sandcastle/Presentation/hana/Styles/tabs.css b/tools/Sandcastle/Presentation/hana/Styles/tabs.css
deleted file mode 100644
index af06695..0000000
--- a/tools/Sandcastle/Presentation/hana/Styles/tabs.css
+++ /dev/null
@@ -1,118 +0,0 @@
-/* tab styles */
-
-/* unselected label */
-div.section table.filter tr.tabs td.tab {
- width: 10em;
- background: white;
- text-align: center;
- color: #0481DA;
- font-weight: normal;
- overflow: hidden;
- cursor: pointer;
- border-bottom: solid 1px #cad1da;
- font-size: xx-small;
-}
-
-/* selected label */
-div.section table.filter tr.tabs td.activeTab {
- width: 10em;
- background: #E3E6EB;
- text-align: center;
- color: #000066;
- font-weight: bold;
- overflow: hidden;
- font-size: xx-small;
-}
-
-/* unselected upper left corner */
-td.LeftTab {
- width: 5px;
- height: 5px;
- background-image: url("../icons/tab_unsel_lft_cnr.gif");
- background-repeat: no-repeat;
- font-size:2pt;
-}
-
-/* selected upper left corner */
-td.activeLeftTab {
- width: 5px;
- height: 5px;
- background-image: url("../icons/tab_sel_lft_cnr.gif");
- background-repeat: no-repeat;
- font-size:2pt;
-}
-
-/* unselected upper right corner */
-td.RightTab {
- width: 5px;
- height: 5px;
- background-image: url("../icons/tab_unsel_rt_cnr.gif");
- background-repeat: no-repeat;
- font-size:2pt;
-}
-
-/* selected upper right corner */
-td.activeRightTab {
- width: 5px;
- height: 5px;
- background-image: url("../icons/tab_sel_rt_cnr.gif");
- background-repeat: no-repeat;
- font-size:2pt;
-}
-
-/* unselected left gradient */
-td.leftGrad {
- width: 5px;
- border-bottom: solid 1px #cad1da;
- background-image: url("../icons/tab_unsel_lft_grad.gif");
- background-repeat: repeat-y;
- font-size:2pt;
-}
-
-/* selected left gradient */
-td.activeLeftGrad {
- width: 5px;
- background-image: url("../icons/tab_sel_lft_grad.gif");
- background-repeat: repeat-y;
- font-size:2pt;
-}
-
-/* unselected right gradient */
-td.RightGrad {
- width: 5px;
- border-bottom: solid 1px #cad1da;
- background-image: url("../icons/tab_unsel_rt_grad.gif");
- background-repeat: repeat-y;
- white-space:nowrap;
- font-size:2pt;
-}
-
-/* selected right gradient */
-td.activeRightGrad {
- width: 5px;
- background-image: url("../icons/tab_sel_rt_grad.gif");
- background-repeat: repeat-y;
- white-space:nowrap;
- font-size:2pt;
-}
-
-/* unselected label top */
-td.middleTab {
- width: 10em;
- background: white;
- height: 5px;
- border-top: solid 1px #cad1da;
- font-size:2pt;
-}
-
-/* selected label top */
-td.activeMiddleTab
-{
- width: 10em;
- background: #E3E6EB;
- height: 5px;
- border-top: solid 1px #bdc6d2;
- font-size:2pt;
-}
-
-
diff --git a/tools/Sandcastle/Presentation/hana/configuration/conceptual.config b/tools/Sandcastle/Presentation/hana/configuration/conceptual.config
deleted file mode 100644
index 08b4d3c..0000000
--- a/tools/Sandcastle/Presentation/hana/configuration/conceptual.config
+++ /dev/null
@@ -1,108 +0,0 @@
-<configuration>
- <dduetools>
- <builder>
- <components>
-
- <!-- Create skeleton document -->
- <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <data file="%DXROOT%\Presentation\Vsorcas\transforms\skeleton_conceptual.xml" />
- <copy source="/*" target="/" />
- </component>
-
- <!-- Copy in comments -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="comments" value="/topic" key="@id">
- <data files=".\DdueXml\*.xml" />
- </index>
- <copy name="comments" source="/topic" target="/document" />
- </component>
-
- <!-- resolve tokens -->
- <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
- <content file="%DXROOT%\Data\tokens.xml" />
- <replace elements="/*//ddue:token" item="string(.)" />
- </component>
-
- <!-- copy in metadata keywords -->
- <component type="Microsoft.Ddue.Tools.CopyFromFilesComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy base=".\XmlComp" file="concat($key,'.cmp.xml')" source="/metadata/topic[@id=$key]/*" target="/document/metadata" />
- </component>
-
- <!-- copy in metadata attributes -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="metadata" value="/metadata/topic" key="@id">
- <data files=".\ExtractedFiles\*.ContentMetadata.xml" />
- </index>
- <copy name="metadata" source="*" target="/document/metadata" />
- <copy name="metadata" key="string('*')" source="*" target="/document/metadata" />
- </component>
-
- <!-- Resolve code snippets -->
- <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <examples file="%DXROOT%\Data\CodeSnippet.xml" />
- <colors language="VisualBasic">
- <color pattern="^\s*'[^\r\n]*" class="comment" />
- <color pattern="\&#34;.*\&#34;" class="literal" />
- <color pattern="\b((AddHandler)|(AddressOf)|(As)|(ByRef)|(ByVal)|(Case)|(Catch)|(Class)|(Const)|(Continue)|(Delegate)|(Dim)|(Each)|(Else)|(ElseIf)|(End)|(Enum)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(Function)|(Get)|(Handles)|(Implements)|(Imports)|(In)|(Inherits)|(Interface)|(Is)|(Loop)|(Me)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(Namespace)|(New)|(Next)|(Nothing)|(NotInheritable)|(NotOverrideable)|(Of)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(RemoveHandler)|(Set)|(Shadows)|(Shared)|(Static)|(Step)|(Structure)|(Sub)|(Then)|(Throw)|(To)|(True)|(Try)|(Until)|(Using)|(When)|(While)|(With)|(WriteOnly))\b" class="keyword" />
- </colors>
- <colors language="CSharp">
- <color pattern="/\*(.|\n)+?\*/" class="comment" />
- <color pattern="//[^\r\n]*" class="comment" />
- <color pattern="\&#34;.*\&#34;" class="literal" />
- <color pattern="\b((abstract)|(as)|(base)|(bool)|(break)|(case)|(catch)|(class)|(const)|(continue)|(default)|(delegate)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(foreach)|(get)|(if)|(in)|(interface)|(internal)|(is)|(namespace)|(new)|(null)|(out)|(override)|(params)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sealed)|(set)|(static)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(using)|(virtual)|(volatile)|(void)|(while))\b" class="keyword" />
- </colors>
- <colors language="ManagedCPlusPlus">
- <color pattern="/\*(.|\n)+?\*/" class="comment" />
- <color pattern="//[^\r\n]*" class="comment" />
- <color pattern="\&#34;.*\&#34;" class="literal" />
- <color pattern="\b((abstract)|(array)|(break)|(case)|(catch)|(class)|(const)|(continue)|(delegate)|(delete)|(do)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(interface)|(literal)|(namespace)|(new)|(noinline)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(sealed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(throw)|(true)|(try)|(typedef)|(union)|(using)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
- </colors>
- </component>
-
- <!-- transform -->
- <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <transform file="%DXROOT%\Presentation\vsorcas\transforms\main_conceptual.xsl">
- <argument key="metadata" value="true" />
- <argument key="languages">
- <language label="CSharp" name="CSharp" style="cs" />
- <language label="VisualBasic" name="VisualBasic" style="vb" />
- <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cs" />
- <language label="JSharp" name="JSharp" style="cs" />
- <language label="JScript" name="JScript" style="cs" />
- <language label="XAML" name="XAML" style="cs" />
- </argument>
- </transform>
- </component>
-
- <!-- resolve art links -->
- <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets input="%DXROOT%\Data\ArtStore" output=".\Output\media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
- </component>
-
- <!-- resolve shared content -->
- <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <content file="%DXROOT%\Presentation\vsorcas\content\shared_content.xml" />
- <content file="%DXROOT%\Presentation\vsorcas\content\conceptual_content.xml" />
- </component>
-
- <!-- resolve conceptual links -->
- <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base=".\XmlComp" type="local" />
- <targets base="%DXROOT%\Data\XmlComp" type="index"/>
- </component>
-
- <!-- resolve reference links -->
- <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" type="index" />
- </component>
-
- <!-- save the result -->
- <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <save base=".\Output\html" path="concat($key,'.htm')" indent="true" omit-xml-declaration="true" />
- </component>
-
- </components>
- </builder>
- </dduetools>
-</configuration>
diff --git a/tools/Sandcastle/Presentation/hana/configuration/sandcastle-scbuild.config b/tools/Sandcastle/Presentation/hana/configuration/sandcastle-scbuild.config
deleted file mode 100644
index c2e1097..0000000
--- a/tools/Sandcastle/Presentation/hana/configuration/sandcastle-scbuild.config
+++ /dev/null
@@ -1,126 +0,0 @@
-<configuration>
- <dduetools>
- <builder>
- <components>
-
- <!-- Create skeleton document -->
- <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <data file="%DXROOT%\Presentation\hana\Transforms\skeleton.xml" />
- <copy source="/*" target="/" />
- </component>
-
- <!-- Copy in reflection data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
- <data base="%DxTempDir%\ReflectionData" recurse="true" files="*.xml" />
- </index>
- <copy name="reflection" source="*" target="/document/reference" />
- </component>
-
- <!-- Copy in container data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
- </component>
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/containers//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in parameter data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/parameters/parameter//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
- </component>
- </components>
- </component>
-
- <!-- Generate syntax -->
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(starts-with($key,'Overload:') or starts-with($key,'R:'))" />
- <then>
- <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <syntax input="/document/reference" output="/document/syntax" />
- <generators>
- <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- </generators>
- </component>
- </then>
- </component>
-
- <!-- Copy in comments -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="comments" value="/doc/members/member" key="@name" cache="100">
- <data base="%DxTempDir%\Comments\" recurse="false" files="*.xml" />
- </index>
- <copy name="comments" source="*" target="/document/comments" />
- </component>
-
- <!-- Copy in reflection data and comments for members -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/elements//element/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(/document/reference/elements//element[@api=$key]/apidata)" />
- <then>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </then>
- </component>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" source="summary|overloads" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in comments for the member's declaring type. -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" key="string(/document/reference/containers/type/@api)" source="summary" target="/document/reference/containers" />
- </component>
-
- <!-- transform -->
- <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <transform file="%DXROOT%\Presentation\hana\Transforms\main_sandcastle.xsl">
- <argument key="metadata" value="true" />
- <argument key="languages">
- <language label="VisualBasic" name="VisualBasic" style="vb" />
- <language label="CSharp" name="CSharp" style="cs" />
- <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
- <!--<language label="JSharp" name="JSharp" style="cs" />
- <language label="JScript" name="JScript" style="cs" />
- <language label="XAML" name="XAML" style="cs" /> -->
- </argument>
- </transform>
- </component>
-
- <!-- resolve shared content -->
- <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <content file="%DXROOT%\Presentation\hana\content\shared_content.xml" />
- <content file="%DXROOT%\Presentation\hana\content\reference_content.xml" />
- <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
- </component>
-
- <!-- resolve reference links -->
- <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%DxTempDir%\ReflectionData\Framework" recurse="true" files="*.xml" type="msdn" />
- <targets base="%DxTempDir%\ReflectionData\Dependencies" recurse="true" files="*.xml" type="index" />
- <targets files="%DxTempDir%\ReflectionData\targets.xml" type="local" />
- </component>
-
- <!-- save the result -->
- <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <save base ="%DxTempDir%\Output\html" path="concat(/html/head/meta[@name='guid']/@content,'.htm')" indent="false" omit-xml-declaration="true" />
- </component>
-
- </components>
- </builder>
- </dduetools>
-</configuration>
diff --git a/tools/Sandcastle/Presentation/hana/configuration/sandcastle.config b/tools/Sandcastle/Presentation/hana/configuration/sandcastle.config
deleted file mode 100644
index cfa51df..0000000
--- a/tools/Sandcastle/Presentation/hana/configuration/sandcastle.config
+++ /dev/null
@@ -1,127 +0,0 @@
-<configuration>
- <dduetools>
- <builder>
- <components>
-
- <!-- Create skeleton document -->
- <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <data file="%DXROOT%\Presentation\hana\Transforms\skeleton.xml" />
- <copy source="/*" target="/" />
- </component>
-
- <!-- Copy in reflection data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
- <data base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" />
- <data files=".\reflection.xml" />
- </index>
- <copy name="reflection" source="*" target="/document/reference" />
- </component>
-
- <!-- Copy in container data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
- </component>
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/containers//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in parameter data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/parameters/parameter//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
- </component>
- </components>
- </component>
-
- <!-- Generate syntax -->
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(starts-with($key,'Overload:') or starts-with($key,'R:'))" />
- <then>
- <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <syntax input="/document/reference" output="/document/syntax" />
- <generators>
- <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- </generators>
- </component>
- </then>
- </component>
-
- <!-- Copy in comments -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="comments" value="/doc/members/member" key="@name" cache="100">
- <data files="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\*.xml" />
- <data files=".\comments.xml" />
- </index>
- <copy name="comments" source="*" target="/document/comments" />
- </component>
-
- <!-- Copy in reflection data and comments for members -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/elements//element/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(/document/reference/elements//element[@api=$key]/apidata)" />
- <then>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </then>
- </component>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" source="summary|overloads" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in comments for the member's declaring type. -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" key="string(/document/reference/containers/type/@api)" source="summary" target="/document/reference/containers" />
- </component>
-
- <!-- transform -->
- <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <transform file="%DXROOT%\Presentation\hana\Transforms\main_sandcastle.xsl">
- <argument key="metadata" value="true" />
- <argument key="languages">
- <language label="VisualBasic" name="VisualBasic" style="vb" />
- <language label="CSharp" name="CSharp" style="cs" />
- <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
- <!--<language label="JSharp" name="JSharp" style="cs" />
- <language label="JScript" name="JScript" style="cs" />
- <language label="XAML" name="XAML" style="cs" /> -->
- </argument>
- </transform>
- </component>
-
- <!-- resolve shared content -->
- <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <content file="%DXROOT%\Presentation\hana\content\shared_content.xml" />
- <content file="%DXROOT%\Presentation\hana\content\reference_content.xml" />
- <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
- </component>
-
- <!-- resolve reference links -->
- <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" type="msdn" />
- <targets files=".\reflection.xml" type="local" />
- </component>
-
- <!-- save the result -->
- <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <save base =".\Output\html" path="concat(/html/head/meta[@name='guid']/@content,'.htm')" indent="false" omit-xml-declaration="true" />
- </component>
-
- </components>
- </builder>
- </dduetools>
-</configuration>
diff --git a/tools/Sandcastle/Presentation/hana/copyOutput.bat b/tools/Sandcastle/Presentation/hana/copyOutput.bat
deleted file mode 100644
index 60fc216..0000000
--- a/tools/Sandcastle/Presentation/hana/copyOutput.bat
+++ /dev/null
@@ -1,11 +0,0 @@
-if not exist Output mkdir Output
-if not exist Output\html mkdir Output\html
-if not exist Output\icons mkdir Output\icons
-if not exist Output\scripts mkdir Output\scripts
-if not exist Output\styles mkdir Output\styles
-if not exist Output\media mkdir Output\media
-copy "%DXROOT%\Presentation\hana\icons\*" Output\icons
-copy "%DXROOT%\Presentation\hana\scripts\*" Output\scripts
-copy "%DXROOT%\Presentation\hana\styles\*" Output\styles
-if not exist Intellisense mkdir Intellisense
-
diff --git a/tools/Sandcastle/Presentation/hana/icons/CFW.gif b/tools/Sandcastle/Presentation/hana/icons/CFW.gif
deleted file mode 100644
index cbcabf1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/CFW.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/Caution.gif b/tools/Sandcastle/Presentation/hana/icons/Caution.gif
deleted file mode 100644
index c58e1f9..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/Caution.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/LastChild.gif b/tools/Sandcastle/Presentation/hana/icons/LastChild.gif
deleted file mode 100644
index 0b9af7e..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/LastChild.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/NSRbottomgrad.gif b/tools/Sandcastle/Presentation/hana/icons/NSRbottomgrad.gif
deleted file mode 100644
index a6f9ac6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/NSRbottomgrad.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/adm.gif b/tools/Sandcastle/Presentation/hana/icons/adm.gif
deleted file mode 100644
index 558dbd1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/adm.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/adm_arch.gif b/tools/Sandcastle/Presentation/hana/icons/adm_arch.gif
deleted file mode 100644
index 918f568..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/adm_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/adm_dev.gif b/tools/Sandcastle/Presentation/hana/icons/adm_dev.gif
deleted file mode 100644
index e7398bb..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/adm_dev.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/adm_dev_arch.gif b/tools/Sandcastle/Presentation/hana/icons/adm_dev_arch.gif
deleted file mode 100644
index 9beb941..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/adm_dev_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/alert_caution.gif b/tools/Sandcastle/Presentation/hana/icons/alert_caution.gif
deleted file mode 100644
index c58e1f9..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/alert_caution.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/alert_note.gif b/tools/Sandcastle/Presentation/hana/icons/alert_note.gif
deleted file mode 100644
index 3393af3..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/alert_note.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/alert_security.gif b/tools/Sandcastle/Presentation/hana/icons/alert_security.gif
deleted file mode 100644
index 48661ce..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/alert_security.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/arch.gif b/tools/Sandcastle/Presentation/hana/icons/arch.gif
deleted file mode 100644
index a75cdf8..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/big_adm.gif b/tools/Sandcastle/Presentation/hana/icons/big_adm.gif
deleted file mode 100644
index 9351c4b..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/big_adm.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/big_arch.gif b/tools/Sandcastle/Presentation/hana/icons/big_arch.gif
deleted file mode 100644
index 8ba260d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/big_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/big_dev.gif b/tools/Sandcastle/Presentation/hana/icons/big_dev.gif
deleted file mode 100644
index 221a4dd..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/big_dev.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/big_kw.gif b/tools/Sandcastle/Presentation/hana/icons/big_kw.gif
deleted file mode 100644
index 365cca2..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/big_kw.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/box.gif b/tools/Sandcastle/Presentation/hana/icons/box.gif
deleted file mode 100644
index c022894..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/box.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/ch_selected.gif b/tools/Sandcastle/Presentation/hana/icons/ch_selected.gif
deleted file mode 100644
index 7a81770..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/ch_selected.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/ch_selected_hover.gif b/tools/Sandcastle/Presentation/hana/icons/ch_selected_hover.gif
deleted file mode 100644
index 21edffc..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/ch_selected_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/ch_unselected.gif b/tools/Sandcastle/Presentation/hana/icons/ch_unselected.gif
deleted file mode 100644
index 04c9cfd..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/ch_unselected.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/ch_unselected_hover.gif b/tools/Sandcastle/Presentation/hana/icons/ch_unselected_hover.gif
deleted file mode 100644
index 693ec56..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/ch_unselected_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/collall.gif b/tools/Sandcastle/Presentation/hana/icons/collall.gif
deleted file mode 100644
index 66a6f11..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/collall.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/collapse.gif b/tools/Sandcastle/Presentation/hana/icons/collapse.gif
deleted file mode 100644
index d57c046..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/collapse.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/collapse_all.gif b/tools/Sandcastle/Presentation/hana/icons/collapse_all.gif
deleted file mode 100644
index 45f018a..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/collapse_all.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/copycode.gif b/tools/Sandcastle/Presentation/hana/icons/copycode.gif
deleted file mode 100644
index 1678162..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/copycode.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/copycodeHighlight.gif b/tools/Sandcastle/Presentation/hana/icons/copycodeHighlight.gif
deleted file mode 100644
index be87230..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/copycodeHighlight.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/dev.gif b/tools/Sandcastle/Presentation/hana/icons/dev.gif
deleted file mode 100644
index 376241d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/dev.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/dev_arch.gif b/tools/Sandcastle/Presentation/hana/icons/dev_arch.gif
deleted file mode 100644
index 12b5520..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/dev_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/drpdown.gif b/tools/Sandcastle/Presentation/hana/icons/drpdown.gif
deleted file mode 100644
index 9d3bbb6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/drpdown.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/drpdown_orange.gif b/tools/Sandcastle/Presentation/hana/icons/drpdown_orange.gif
deleted file mode 100644
index cf50c20..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/drpdown_orange.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/drpdown_orange_up.gif b/tools/Sandcastle/Presentation/hana/icons/drpdown_orange_up.gif
deleted file mode 100644
index a173df1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/drpdown_orange_up.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/drpup.gif b/tools/Sandcastle/Presentation/hana/icons/drpup.gif
deleted file mode 100644
index de77198..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/drpup.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/exp.gif b/tools/Sandcastle/Presentation/hana/icons/exp.gif
deleted file mode 100644
index 023b837..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/exp.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/expall.gif b/tools/Sandcastle/Presentation/hana/icons/expall.gif
deleted file mode 100644
index 1a91b12..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/expall.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/expand_all.gif b/tools/Sandcastle/Presentation/hana/icons/expand_all.gif
deleted file mode 100644
index 123fda9..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/expand_all.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/filter1a.gif b/tools/Sandcastle/Presentation/hana/icons/filter1a.gif
deleted file mode 100644
index 8a2f9b5..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/filter1a.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/filter1c.gif b/tools/Sandcastle/Presentation/hana/icons/filter1c.gif
deleted file mode 100644
index 49de223..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/filter1c.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/footer.gif b/tools/Sandcastle/Presentation/hana/icons/footer.gif
deleted file mode 100644
index 7092cde..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/footer.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/greencheck.gif b/tools/Sandcastle/Presentation/hana/icons/greencheck.gif
deleted file mode 100644
index 4ba1751..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/greencheck.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/greychck.gif b/tools/Sandcastle/Presentation/hana/icons/greychck.gif
deleted file mode 100644
index adb8fa1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/greychck.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/header_prev_next.jpg b/tools/Sandcastle/Presentation/hana/icons/header_prev_next.jpg
deleted file mode 100644
index 2f53424..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/header_prev_next.jpg
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_blank.jpg b/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_blank.jpg
deleted file mode 100644
index aca0566..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_blank.jpg
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_logo.GIF b/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_logo.GIF
deleted file mode 100644
index e0b0bcc..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/header_sql_tutorial_logo.GIF
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw.gif b/tools/Sandcastle/Presentation/hana/icons/kw.gif
deleted file mode 100644
index 40a943c..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_adm.gif b/tools/Sandcastle/Presentation/hana/icons/kw_adm.gif
deleted file mode 100644
index 6e05cc8..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_adm.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_adm_arch.gif b/tools/Sandcastle/Presentation/hana/icons/kw_adm_arch.gif
deleted file mode 100644
index 162c7d8..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_adm_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev.gif b/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev.gif
deleted file mode 100644
index 2d67824..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev_arch.gif b/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev_arch.gif
deleted file mode 100644
index 358f2fa..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_adm_dev_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_arch.gif b/tools/Sandcastle/Presentation/hana/icons/kw_arch.gif
deleted file mode 100644
index ab5d3bb..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_dev.gif b/tools/Sandcastle/Presentation/hana/icons/kw_dev.gif
deleted file mode 100644
index 6ff27ed..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_dev.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/kw_dev_arch.gif b/tools/Sandcastle/Presentation/hana/icons/kw_dev_arch.gif
deleted file mode 100644
index 99f017a..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/kw_dev_arch.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/load.gif b/tools/Sandcastle/Presentation/hana/icons/load.gif
deleted file mode 100644
index 9492447..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/load.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/load_hover.gif b/tools/Sandcastle/Presentation/hana/icons/load_hover.gif
deleted file mode 100644
index 65f44aa..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/load_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/note.gif b/tools/Sandcastle/Presentation/hana/icons/note.gif
deleted file mode 100644
index 3393af3..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/note.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pencil.GIF b/tools/Sandcastle/Presentation/hana/icons/pencil.GIF
deleted file mode 100644
index 000dcb4..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pencil.GIF
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privclass.gif b/tools/Sandcastle/Presentation/hana/icons/privclass.gif
deleted file mode 100644
index 0939694..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privclass.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privdelegate.gif b/tools/Sandcastle/Presentation/hana/icons/privdelegate.gif
deleted file mode 100644
index d3aa8a6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privdelegate.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privenum.gif b/tools/Sandcastle/Presentation/hana/icons/privenum.gif
deleted file mode 100644
index 47f387e..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privenum.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privenumeration.gif b/tools/Sandcastle/Presentation/hana/icons/privenumeration.gif
deleted file mode 100644
index 47f387e..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privenumeration.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privevent.gif b/tools/Sandcastle/Presentation/hana/icons/privevent.gif
deleted file mode 100644
index 30db46d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privevent.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privfield.gif b/tools/Sandcastle/Presentation/hana/icons/privfield.gif
deleted file mode 100644
index cbf70f7..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privfield.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privinterface.gif b/tools/Sandcastle/Presentation/hana/icons/privinterface.gif
deleted file mode 100644
index f3b7950..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privinterface.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privmethod.gif b/tools/Sandcastle/Presentation/hana/icons/privmethod.gif
deleted file mode 100644
index 71f8822..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privmethod.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privproperty.gif b/tools/Sandcastle/Presentation/hana/icons/privproperty.gif
deleted file mode 100644
index b1e8074..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privproperty.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/privstructure.gif b/tools/Sandcastle/Presentation/hana/icons/privstructure.gif
deleted file mode 100644
index ed6d1ef..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/privstructure.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protclass.gif b/tools/Sandcastle/Presentation/hana/icons/protclass.gif
deleted file mode 100644
index 0f92942..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protclass.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protdelegate.gif b/tools/Sandcastle/Presentation/hana/icons/protdelegate.gif
deleted file mode 100644
index b209f2d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protdelegate.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protenum.gif b/tools/Sandcastle/Presentation/hana/icons/protenum.gif
deleted file mode 100644
index cc96bb6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protenum.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protenumeration.gif b/tools/Sandcastle/Presentation/hana/icons/protenumeration.gif
deleted file mode 100644
index cc96bb6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protenumeration.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protevent.gif b/tools/Sandcastle/Presentation/hana/icons/protevent.gif
deleted file mode 100644
index 0e510b2..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protevent.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protfield.gif b/tools/Sandcastle/Presentation/hana/icons/protfield.gif
deleted file mode 100644
index 9ae6833..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protfield.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protinterface.gif b/tools/Sandcastle/Presentation/hana/icons/protinterface.gif
deleted file mode 100644
index a1b96d2..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protinterface.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protmethod.gif b/tools/Sandcastle/Presentation/hana/icons/protmethod.gif
deleted file mode 100644
index 2bc9468..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protmethod.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protoperator.gif b/tools/Sandcastle/Presentation/hana/icons/protoperator.gif
deleted file mode 100644
index 2cb75ab..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protoperator.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protproperty.gif b/tools/Sandcastle/Presentation/hana/icons/protproperty.gif
deleted file mode 100644
index 55473d1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protproperty.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/protstructure.gif b/tools/Sandcastle/Presentation/hana/icons/protstructure.gif
deleted file mode 100644
index af356a1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/protstructure.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubclass.gif b/tools/Sandcastle/Presentation/hana/icons/pubclass.gif
deleted file mode 100644
index 1a968ab..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubclass.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubdelegate.gif b/tools/Sandcastle/Presentation/hana/icons/pubdelegate.gif
deleted file mode 100644
index 0a43eb2..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubdelegate.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubenum.gif b/tools/Sandcastle/Presentation/hana/icons/pubenum.gif
deleted file mode 100644
index 46888ad..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubenum.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubenumeration.gif b/tools/Sandcastle/Presentation/hana/icons/pubenumeration.gif
deleted file mode 100644
index 46888ad..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubenumeration.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubevent.gif b/tools/Sandcastle/Presentation/hana/icons/pubevent.gif
deleted file mode 100644
index b9226da..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubevent.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubfield.gif b/tools/Sandcastle/Presentation/hana/icons/pubfield.gif
deleted file mode 100644
index 5aed175..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubfield.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubinterface.gif b/tools/Sandcastle/Presentation/hana/icons/pubinterface.gif
deleted file mode 100644
index c38a4c4..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubinterface.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubmethod.gif b/tools/Sandcastle/Presentation/hana/icons/pubmethod.gif
deleted file mode 100644
index 2c72988..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubmethod.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/puboperator.gif b/tools/Sandcastle/Presentation/hana/icons/puboperator.gif
deleted file mode 100644
index 0ebe10a..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/puboperator.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubproperty.gif b/tools/Sandcastle/Presentation/hana/icons/pubproperty.gif
deleted file mode 100644
index dfad7b4..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubproperty.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/pubstructure.gif b/tools/Sandcastle/Presentation/hana/icons/pubstructure.gif
deleted file mode 100644
index 1344416..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/pubstructure.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/r_select.gif b/tools/Sandcastle/Presentation/hana/icons/r_select.gif
deleted file mode 100644
index a66334b..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/r_select.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/r_select_hover.gif b/tools/Sandcastle/Presentation/hana/icons/r_select_hover.gif
deleted file mode 100644
index 58444d6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/r_select_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/r_unselect.gif b/tools/Sandcastle/Presentation/hana/icons/r_unselect.gif
deleted file mode 100644
index 8c5a85d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/r_unselect.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/r_unselect_hover.gif b/tools/Sandcastle/Presentation/hana/icons/r_unselect_hover.gif
deleted file mode 100644
index 58444d6..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/r_unselect_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/requirements1a.gif b/tools/Sandcastle/Presentation/hana/icons/requirements1a.gif
deleted file mode 100644
index 3b08793..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/requirements1a.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/requirements1c.gif b/tools/Sandcastle/Presentation/hana/icons/requirements1c.gif
deleted file mode 100644
index d62bda3..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/requirements1c.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/save.gif b/tools/Sandcastle/Presentation/hana/icons/save.gif
deleted file mode 100644
index 6a5177e..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/save.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/save_hover.gif b/tools/Sandcastle/Presentation/hana/icons/save_hover.gif
deleted file mode 100644
index 7b62e92..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/save_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/security.gif b/tools/Sandcastle/Presentation/hana/icons/security.gif
deleted file mode 100644
index 48661ce..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/security.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/seealso1a.gif b/tools/Sandcastle/Presentation/hana/icons/seealso1a.gif
deleted file mode 100644
index 2f5d50a..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/seealso1a.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/seealso1c.gif b/tools/Sandcastle/Presentation/hana/icons/seealso1c.gif
deleted file mode 100644
index 84f79e7..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/seealso1c.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/static.gif b/tools/Sandcastle/Presentation/hana/icons/static.gif
deleted file mode 100644
index c54022b..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/static.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_cnr.gif b/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_cnr.gif
deleted file mode 100644
index 9653f83..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_cnr.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_grad.gif b/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_grad.gif
deleted file mode 100644
index be9c0c5..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_sel_lft_grad.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_cnr.gif b/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_cnr.gif
deleted file mode 100644
index ba65c4e..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_cnr.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_grad.gif b/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_grad.gif
deleted file mode 100644
index 50fee8d..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_sel_rt_grad.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_cnr.gif b/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_cnr.gif
deleted file mode 100644
index 989a051..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_cnr.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_grad.gif b/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_grad.gif
deleted file mode 100644
index 1b5c283..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_lft_grad.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_cnr.gif b/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_cnr.gif
deleted file mode 100644
index d748332..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_cnr.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_grad.gif b/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_grad.gif
deleted file mode 100644
index 31d4f87..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/tab_unsel_rt_grad.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/twirl_selected.gif b/tools/Sandcastle/Presentation/hana/icons/twirl_selected.gif
deleted file mode 100644
index 4cfa69b..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/twirl_selected.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/twirl_selected_hover.gif b/tools/Sandcastle/Presentation/hana/icons/twirl_selected_hover.gif
deleted file mode 100644
index f54afa1..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/twirl_selected_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/twirl_unselected.gif b/tools/Sandcastle/Presentation/hana/icons/twirl_unselected.gif
deleted file mode 100644
index 97a1ea8..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/twirl_unselected.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/twirl_unselected_hover.gif b/tools/Sandcastle/Presentation/hana/icons/twirl_unselected_hover.gif
deleted file mode 100644
index 5a7352a..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/twirl_unselected_hover.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/icons/xna.gif b/tools/Sandcastle/Presentation/hana/icons/xna.gif
deleted file mode 100644
index 9e6a9d4..0000000
--- a/tools/Sandcastle/Presentation/hana/icons/xna.gif
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/Presentation/hana/transforms/globalTemplates.xsl b/tools/Sandcastle/Presentation/hana/transforms/globalTemplates.xsl
deleted file mode 100644
index abf6d2d..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/globalTemplates.xsl
+++ /dev/null
@@ -1,125 +0,0 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:template name="autogenSeeAlsoLinks">
-
- <!-- a link to the containing type on all list and member topics -->
- <xsl:if test="$group='member' or $group='list'">
- <div class="seeAlsoStyle">
- <include item="SeeAlsoTypeLinkText">
- <parameter>
- <referenceLink target="{$typeId}" />
- <!--<xsl:value-of select="$typeName"/> -->
- </parameter>
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@subgroup"/>
- </parameter>
- </include>
- </div>
- </xsl:if>
-
- <!-- a link to the namespace topic -->
- <xsl:if test="normalize-space($namespaceId)">
- <div class="seeAlsoStyle">
- <include item="SeeAlsoNamespaceLinkText">
- <parameter>
- <referenceLink target="{$namespaceId}" />
- <!--<xsl:value-of select="/document/reference/containers/namespace/apidata/@name"/> -->
- </parameter>
- </include>
- </div>
- </xsl:if>
-
- </xsl:template>
-
- <xsl:variable name="typeId">
- <xsl:choose>
- <xsl:when test="/document/reference/topicdata[@group='api'] and /document/reference/apidata[@group='type']">
- <xsl:value-of select="$key"/>
- </xsl:when>
- <xsl:when test="/document/reference/topicdata/@typeTopicId">
- <xsl:value-of select="/document/reference/topicdata/@typeTopicId"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/containers/type/@api"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="namespaceId">
- <xsl:value-of select="/document/reference/containers/namespace/@api"/>
- </xsl:variable>
-
- <!-- indent by 2*n spaces -->
- <xsl:template name="indent">
- <xsl:param name="count" />
- <xsl:if test="$count &gt; 1">
- <xsl:text>&#160;&#160;</xsl:text>
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="$count - 1" />
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <!-- Gets the substring after the last occurence of a period in a given string -->
- <xsl:template name="subString">
- <xsl:param name="name" />
-
- <xsl:choose>
- <xsl:when test="contains($name, '.')">
- <xsl:call-template name="subString">
- <xsl:with-param name="name" select="substring-after($name, '.')" />
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$name" />
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
-
- <xsl:template name="codeSection">
-
- <table width="100%" cellspacing="0" cellpadding="0">
- <tr>
- <th>
- <span class="copyCode" onclick="CopyCode(this)" onkeypress="CopyCode_CheckKey(this, event)" onmouseover="ChangeCopyCodeIcon(this)" onmouseout="ChangeCopyCodeIcon(this)" tabindex="0">
- <img class="copyCodeImage" name="ccImage" align="absmiddle">
- <includeAttribute name="title" item="copyImage" />
- <includeAttribute name="src" item="iconPath">
- <parameter>copycode.gif</parameter>
- </includeAttribute>
- </img>
- <include item="copyCode"/>
- </span>
- </th>
- </tr>
- <tr>
- <td colspan="2">
- <pre><xsl:text/><xsl:copy-of select="node()"/><xsl:text/></pre>
- </td>
- </tr>
- </table>
-
- </xsl:template>
-
- <xsl:template name="languageCheck">
- <xsl:param name="codeLanguage"/>
-
- <xsl:if test="$languages != 'false'">
- <xsl:if test="count($languages/language) &gt; 0">
- <xsl:for-each select="$languages/language">
- <xsl:if test="$codeLanguage = @name">
- <xsl:value-of select="@style"/>
- </xsl:if>
- </xsl:for-each>
- </xsl:if>
- </xsl:if>
- </xsl:template>
-
-</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/hana/transforms/htmlBody.xsl b/tools/Sandcastle/Presentation/hana/transforms/htmlBody.xsl
deleted file mode 100644
index 64fb50e..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/htmlBody.xsl
+++ /dev/null
@@ -1,507 +0,0 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:import href="globalTemplates.xsl"/>
- <xsl:template name="upperBodyStuff">
- <input type="hidden" id="userDataCache" class="userDataStyle"/>
- <input type="hidden" id="hiddenScrollOffset"/>
-
- <xsl:call-template name="commonImages"/>
-
- <xsl:call-template name="bodyHeader"/>
-
- </xsl:template>
-
- <xsl:template name="bodyHeader">
- <div id="header">
- <xsl:call-template name="bodyHeaderTopTable"/>
- </div>
- </xsl:template>
-
- <xsl:template name="bodyHeaderTopTable">
- <table id="topTable">
- <tr id="headerTableRow3">
- <td>
- <xsl:call-template name="headerRowLinks"/>
- </td>
- </tr>
- <tr id="headerTableRow1">
- <td align="left">
- <span id="runningHeaderText">
- <xsl:call-template name="runningHeader" />
- </span>
- </td>
- </tr>
- <tr id="headerTableRow2">
- <td align="left">
- <span id="nsrTitle">
- <xsl:call-template name="topicTitleDecorated"/>
- </span>
- </td>
- </tr>
- <tr>
- <td class="nsrBottom">
- <includeAttribute name="background" item="iconPath">
- <parameter>NSRbottomgrad.gif</parameter>
- </includeAttribute>
- </td>
- </tr>
- </table>
- </xsl:template>
-
- <xsl:template name="headerRowLinks">
- <!-- most mref topics get autogenerated see also links to see also section -->
-
- <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage, event)" tabindex="0">
- <img ID="toggleAllImage" class="toggleAll">
- <includeAttribute name="src" item="iconPath">
- <parameter>collall.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="collapseAllImage" />
- </img>
- <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
- <include item="collapseAll"/>
- </label>
- <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
- <include item="expandAll"/>
- </label>
- <xsl:text>&#160;</xsl:text>
- </span>
-
- <xsl:if test="$languages != 'false'">
- <xsl:if test="count($languages/language) &gt; 0">
- <xsl:text>&#160;|&#160;</xsl:text>
- <xsl:call-template name="languageFilterToolTip"/>
- <xsl:call-template name="languageSpan"/>
- </xsl:if>
- </xsl:if>
-
-
- <!-- include Example link if there's an Example section -->
- <xsl:choose>
- <xsl:when test="$examplesSection">
- <xsl:text>&#160;|&#160;</xsl:text>
- <a href="#exampleToggle" onclick="OpenSection(exampleToggle)">
- <xsl:text/>
- <include item="Example"/>
- <xsl:text/>
- </a>
- </xsl:when>
- </xsl:choose>
-
- <!-- class, structure, and interface About topics get link to Members topic (unless the doc model has the all members lists on the type topic) -->
- <xsl:choose>
- <xsl:when test="normalize-space(/document/reference/topicdata/@allMembersTopicId)">
- <xsl:text>&#160;|&#160;</xsl:text>
- <referenceLink target="{/document/reference/topicdata/@allMembersTopicId}">
- <include item="allMembersTitle"/>
- </referenceLink>
- </xsl:when>
- <xsl:when test="count(/document/reference/elements/element) &gt; 0 and ($subgroup='class' or $subgroup='structure' or $subgroup='interface')">
- <xsl:text>&#160;|&#160;</xsl:text>
- <a href="#membersToggle" onclick="OpenSection(membersToggle)">
- <xsl:text/>
- <include item="allMembersTitle"/>
- <xsl:text/>
- </a>
- </xsl:when>
- </xsl:choose>
-
- <xsl:if test="$hasSeeAlsoSection">
- <xsl:text>&#160;|&#160;</xsl:text>
- <a href="#seeAlsoToggle" onclick="OpenSection(seeAlsoToggle)">
- <xsl:text/>
- <include item="SeeAlso"/>
- <xsl:text/>
- </a>
- </xsl:if>
-
- <!--all members only -->
- <xsl:if test="$subgroup='members'">
- <xsl:variable name="visibility">
- <xsl:for-each select="/document/reference/elements/element">
- <xsl:choose>
- <xsl:when test="memberdata[@visibility = 'public']">
- <xsl:choose>
- <xsl:when test="not(apidata[@subsubgroup])">
- <xsl:value-of select="concat('Public', apidata/@subgroup, ';')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Public', apidata/@subsubgroup, ';')"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="memberdata[@visibility = 'private'] and not(proceduredata[@virtual = 'true'])">
- <xsl:choose>
- <xsl:when test="not(apidata[@subsubgroup])">
- <xsl:value-of select="concat('Private', apidata/@subgroup, ';')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Private', apidata/@subsubgroup, ';')"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="memberdata[@visibility = 'private'] and proceduredata[@virtual = 'true']">
- explicit;
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="not(apidata[@subsubgroup])">
- <xsl:value-of select="concat('Protected', apidata/@subgroup, ';')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Protected', apidata/@subsubgroup, ';')"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </xsl:variable>
-
-
- <xsl:for-each select="/document/reference/elements/element">
- <xsl:variable name="subgroup" select="apidata/@subgroup"/>
- <xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
- <xsl:if test="not(preceding-sibling::element[apidata[@subgroup=$subgroup]]) and not($subsubgroup='attachedProperty' or $subsubgroup='attachedEvent')">
- <xsl:if test="not($subsubgroup)">
- <xsl:variable name="elementVisibility">
- <xsl:choose>
- <xsl:when test="contains($visibility, concat('Public', $subgroup))">
- <xsl:value-of select="concat('Public', $subgroup)"/>
- </xsl:when>
- <xsl:when test="contains($visibility, concat('Private', $subgroup))">
- <xsl:value-of select="concat('Private', $subgroup)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Protected', $subgroup)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <!-- add a link to the member list section for this subgroup -->
- <a href="#{$elementVisibility}Toggle" onclick="OpenSection({$elementVisibility}Toggle)">
- <xsl:text/>
- <include item="{$subgroup}Group"/>
- <xsl:text/>
- </a>&#160;
- </xsl:if>
- </xsl:if>
- <xsl:if test="not(preceding-sibling::element[apidata[@subsubgroup=$subsubgroup]]) and ($subsubgroup='attachedProperty' or $subsubgroup='attachedEvent')">
- <xsl:variable name="elementVisibility">
- <xsl:choose>
- <xsl:when test="contains($visibility, concat('Public', $subsubgroup))">
- <xsl:value-of select="concat('Public', $subsubgroup)"/>
- </xsl:when>
- <xsl:when test="contains($visibility, concat('Private', $subsubgroup))">
- <xsl:value-of select="concat('Private', $subsubgroup)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat('Protected', $subsubgroup)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <!-- add a link to the member list section for this subgroup -->
- <a href="#{$elementVisibility}Toggle" onclick="OpenSection({$elementVisibility}Toggle)">
- <xsl:text/>
- <include item="{$subsubgroup}Group"/>
- <xsl:text/>
- </a>&#160;
- </xsl:if>
- </xsl:for-each>
-
- <xsl:if test="contains($visibility, 'explicit')">
- <a href="#ExplicitInterfaceImplementationToggle" onclick="OpenSection(ExplicitInterfaceImplementationSection)">
- <xsl:text/>
- <include item="ExplicitInterfaceImplementation"/>
- <xsl:text/>
- </a>&#160;
- </xsl:if>
- </xsl:if>
-
- </xsl:template>
-
- <xsl:template name="bodyHeaderBottomTable">
- <table id="bottomTable" cellspacing="0" cellpadding="0">
- <tr>
- <td>
- <span onclick="ExpandCollapseAll(toggleAllImage)" style="cursor:default;" onkeypress="ExpandCollapseAll_CheckKey(toggleAllImage, event)" tabindex="0">
- <img ID="toggleAllImage" class="toggleAll">
- <includeAttribute name="src" item="iconPath">
- <parameter>collall.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="collapseAllImage" />
- </img>
- <label id="collapseAllLabel" for="toggleAllImage" style="display: none;">
- <include item="collapseAll"/>
- </label>
- <label id="expandAllLabel" for="toggleAllImage" style="display: none;">
- <include item="expandAll"/>
- </label>
- <xsl:text>&#160;</xsl:text>
- </span>
-
- <xsl:text>&#160;</xsl:text>
-
- <xsl:call-template name="languageFilterToolTip"/>
-
- </td>
- </tr>
- </table>
- </xsl:template>
-
- <xsl:template name="languageFilterToolTip">
- <span id="languageFilterToolTip" style="cursor:default;" onmouseover="languageFilterImage.src=dropDownHoverImage.src;" onmouseout="languageFilterImage.src=dropDownImage.src;" tabindex="0">
- <img id="languageFilterImage">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_unselected.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="dropDownImage" />
- </img>
- <xsl:for-each select="$languages/language">
- <label id="{@name}Label" for="languageFilterImage" style="display: none;">
- <include item="languageFilter">
- <parameter>
- <include item="{@label}Label"/>
- </parameter>
- </include>
- </label>
- </xsl:for-each>
- </span>
- </xsl:template>
-
- <xsl:template name="membersOptionsSpan">
- <div id="membersOptionsSpan">
- <input id="inheritedCheckbox" type='checkbox' name="membersOptionsFilter" onClick="SetMembersOptions(this)"/>
- <label class="membersOptionsFilter" for="inheritedCheckbox">
- <include item="includeInheritedMembers"/>
- </label>
- <br/>
- <input id="protectedCheckbox" type='checkbox' name="membersOptionsFilter" onClick="SetMembersOptions(this)"/>
- <label class="membersOptionsFilter" for="protectedCheckbox">
- <include item="includeProtectedMembers"/>
- </label>
- <br/>
- <input id="netcfCheckbox" type='checkbox' name="membersOptionsFilter" onClick="SetMembersOptions(this)"/>
- <label class="membersOptionsFilter" for="netcfCheckbox">
- <include item="netcfMembersOnly"/>
- </label>
- <br/>
- <!-- add a checkbox for XNA filtering -->
- <input id="netXnaCheckbox" type='checkbox' name="membersOptionsFilter" onClick="SetMembersOptions(this)"/>
- <label class="membersOptionsFilter" for="netXnaCheckbox">
- <include item="netXnaMembersOnly"/>
- </label>
- </div>
- </xsl:template>
-
- <xsl:template name="membersOptionsFilterToolTip">
- <span id="membersOptionsFilterToolTip" style="cursor:default;" onmouseover="membersOptionsFilterImage.src=dropDownHoverImage.src;" onmouseout="membersOptionsFilterImage.src=dropDownImage.src;" tabindex="0">
- <img id="membersOptionsFilterImage">
- <includeAttribute name="src" item="iconPath">
- <parameter>drpdown.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="dropDownImage" />
- </img>
- <label id="showAllMembersLabel" for="membersOptionsFilterImage" style="display: none;">
- <include item="membersOptionsShowAll"/>
- </label>
- <label id="filteredMembersLabel" for="membersOptionsFilterImage" style="display: none;">
- <include item="membersOptionsFiltered"/>
- </label>
- </span>
- </xsl:template>
-
- <xsl:template name="languageSpan">
- <div id="languageSpan">
- <xsl:for-each select="$languages/language">
- <div id="{@name}" onclick="languageFilter.changeLanguage(data, '{@name}', '{@style}');">
- <img id="{@name}Image" onmouseover="mouseOverCheck({@name}Image,radioSelectImage,radioUnSelectImage,radioSelectHoverImage,radioUnSelectHoverImage)" onmouseout="mouseOutCheck({@name}Image,radioSelectImage,radioUnSelectImage,radioSelectHoverImage,radioUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>r_unselect.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="{@label}Label" />
- </div>
- <br />
- </xsl:for-each>
- <script>var languageFilter = new Selector('languageSpan');languageFilter.register(codeBlockHandler); languageFilter.register(styleSheetHandler); languageFilter.register(persistenceHandler);languageFilter.register(languageHandler);toggleLanguage('languageSpan', 'x-lang', 'CSharp');toggleInlineStyle('cs');</script>
- </div>
- </xsl:template>
-
-
-
- <!-- image links
-current ndppick XSLT behavior:
-expandAllImage - all
-dropDownImage - not namespace or derivedTypeList
-dropDownHoverImage - not namespace or derivedTypeList
-collapseImage - all
-expandImage - all
-collapseAllImage - all
-copyImage - overview (not namespace); list (only overload lists ctor, method, prop)
-copyHoverImage - overview (not namespace); list (only overload lists ctor, method, prop)
- -->
- <xsl:template name="commonImages">
- <img id="collapseImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>collapse_all.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="collapseImage" />
- </img>
- <img id="expandImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>expand_all.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="expandImage" />
- </img>
- <img id="collapseAllImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>collall.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="collapseAllImage" />
- </img>
- <img id="expandAllImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>expall.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="expandAllImage" />
- </img>
- <img id="dropDownImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_unselected.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="dropDownImage" />
- </img>
- <img id="dropDownHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_unselected_hover.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="dropDownHoverImage" />
- </img>
- <img id="copyImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>copycode.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="copyImage" />
- </img>
- <img id="copyHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>copycodeHighlight.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="copyHoverImage" />
- </img>
- <img id="checkBoxSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <img id="checkBoxUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_unselected.gif</parameter>
- </includeAttribute>
- </img>
- <img id="checkBoxSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="checkBoxUnSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_unselected_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="radioSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>r_select.gif</parameter>
- </includeAttribute>
- </img>
- <img id="radioUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>r_unselect.gif</parameter>
- </includeAttribute>
- </img>
- <img id="radioSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>r_select_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="radioUnSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>r_unselect_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="curvedLeftSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_sel_lft_cnr.gif</parameter>
- </includeAttribute>
- </img>
- <img id="curvedRightSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_sel_rt_cnr.gif</parameter>
- </includeAttribute>
- </img>
- <img id="curvedLeftUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_unsel_lft_cnr.gif</parameter>
- </includeAttribute>
- </img>
- <img id="curvedRightUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_unsel_rt_cnr.gif</parameter>
- </includeAttribute>
- </img>
- <img id="gradLeftSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_sel_lft_grad.gif</parameter>
- </includeAttribute>
- </img>
- <img id="gradRightSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_sel_rt_grad.gif</parameter>
- </includeAttribute>
- </img>
- <img id="gradLeftUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_unsel_lft_grad.gif</parameter>
- </includeAttribute>
- </img>
- <img id="gradRightUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>tab_unsel_rt_grad.gif</parameter>
- </includeAttribute>
- </img>
- <img id="twirlSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_selected.gif</parameter>
- </includeAttribute>
- </img>
- <img id="twirlUnSelectImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_unselected.gif</parameter>
- </includeAttribute>
- </img>
- <img id="twirlSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_selected_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="twirlUnSelectHoverImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_unselected_hover.gif</parameter>
- </includeAttribute>
- </img>
- <img id="NSRBottomImage" style="display:none; height:0; width:0;">
- <includeAttribute name="src" item="iconPath">
- <parameter>NSRbottomgrad.gif</parameter>
- </includeAttribute>
- </img>
- </xsl:template>
-
-
-</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/hana/transforms/main_conceptual.xsl b/tools/Sandcastle/Presentation/hana/transforms/main_conceptual.xsl
deleted file mode 100644
index 9c67ca5..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/main_conceptual.xsl
+++ /dev/null
@@ -1,455 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:output method="xml" indent="no" encoding="utf-8" />
-
- <xsl:include href="htmlBody.xsl" />
- <xsl:include href="utilities_dduexml.xsl" />
-
- <xsl:variable name="hasSeeAlsoSection" select="boolean(count(/document/topic/*/ddue:relatedTopics/*[local-name()!='sampleRef']) > 0)"/>
- <xsl:variable name="examplesSection" select="boolean(string-length(/document/topic/*/ddue:codeExample[normalize-space(.)]) > 0)"/>
- <xsl:variable name="languageFilterSection" select="normalize-space(/document/topic/*/ddue:codeExample)
- or normalize-space(/document/topic/*//ddue:snippets/ddue:snippet)
- or /document/topic/ddue:developerSampleDocument/ddue:relatedTopics/ddue:sampleRef[@srcID]" />
- <xsl:variable name="group" select="/document/reference/apidata/@group" />
- <xsl:variable name="subgroup" select="/document/reference/apidata/@subgroup" />
- <xsl:variable name="subsubgroup" select="/document/reference/apidata/@subsubgroup" />
- <xsl:variable name="pseudo" select="boolean(/document/reference/apidata[@pseudo='true'])"/>
- <!-- key parameter is the api identifier string -->
- <xsl:param name="key" />
- <xsl:param name="metadata" value="false" />
- <xsl:param name="languages">false</xsl:param>
-
- <xsl:template match="/document">
- <html>
- <head>
- <META NAME="save" CONTENT="history"/>
- <title>
- <xsl:call-template name="topicTitlePlain"/>
- </title>
- <xsl:call-template name="insertStylesheets" />
- <xsl:call-template name="insertScripts" />
- <xsl:call-template name="insertMetadata" />
- </head>
- <body>
- <xsl:call-template name="upperBodyStuff"/>
- <xsl:call-template name="main"/>
- <script type="text/javascript">
- var data = new DataStore('docs');
- registerEventHandler(window, 'load', function() {languageFilter.select(data)});
- </script>
- </body>
- </html>
- </xsl:template>
-
- <!-- document head -->
-
- <xsl:template name="insertStylesheets">
- <link rel="stylesheet" type="text/css" href="../styles/presentation.css" />
- <!-- make mshelp links work -->
- <link rel="stylesheet" type="text/css" href="ms-help://Hx/HxRuntime/HxLink.css" />
- <link rel="stylesheet" type="text/css" href="ms-help://Dx/DxRuntime/DxLink.css" />
- </xsl:template>
-
- <xsl:template name="insertScripts">
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>EventUtilities.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>SplitScreen.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>Dropdown.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>script_manifold.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>LanguageFilter.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>DataStore.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>CommonUtilities.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>MemberFilter.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- </xsl:template>
-
- <xsl:template name="insertMetadata">
- <xsl:if test="$metadata='true'">
- <xml>
- <!-- mshelp metadata -->
-
- <!-- insert toctitle -->
- <MSHelp:TOCTitle Title="{/document/metadata/tableOfContentsTitle}" />
-
- <!-- link index -->
- <MSHelp:Keyword Index="A" Term="{$key}" />
-
- <!-- authored K -->
- <xsl:variable name="docset" select="translate(/document/metadata/attribute[@name='DocSet'][1]/text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz ')"/>
- <xsl:for-each select="/document/metadata/keyword[@index='K']">
- <xsl:variable name="nestedKeywordText">
- <xsl:call-template name="nestedKeywordText"/>
- </xsl:variable>
- <MSHelp:Keyword Index="K">
- <xsl:choose>
- <xsl:when test="normalize-space($docset)='' or contains(text(),'[')">
- <xsl:attribute name="Term">
- <xsl:value-of select="concat(text(),$nestedKeywordText)"/>
- </xsl:attribute>
- </xsl:when>
- <xsl:otherwise>
- <includeAttribute name="Term" item="kIndexTermWithTechQualifier">
- <parameter><xsl:value-of select="text()"/></parameter>
- <parameter><xsl:value-of select="$docset"/></parameter>
- <parameter><xsl:value-of select="$nestedKeywordText"/></parameter>
- </includeAttribute>
- </xsl:otherwise>
- </xsl:choose>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored F -->
- <xsl:for-each select="/document/metadata/keyword[@index='F']">
- <MSHelp:Keyword Index="F">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='F']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored B -->
- <xsl:for-each select="/document/metadata/keyword[@index='B']">
- <MSHelp:Keyword Index="B">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='B']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- Topic version -->
- <MSHelp:Attr Name="RevisionNumber" Value="{/document/topic/@revisionNumber}" />
-
- <!-- Asset ID -->
- <MSHelp:Attr Name="AssetID" Value="{/document/topic/@id}" />
-
- <!-- Abstract -->
- <xsl:variable name="abstract" select="string(/document/topic//ddue:para[1])" />
- <xsl:choose>
- <xsl:when test="string-length($abstract) &gt; 254">
- <MSHelp:Attr Name="Abstract" Value="{concat(substring($abstract,1,250), ' ...')}" />
- </xsl:when>
- <xsl:when test="string-length($abstract) &gt; 0">
- <MSHelp:Attr Name="Abstract" Value="{$abstract}" />
- </xsl:when>
- </xsl:choose>
-
- <!-- authored attributes -->
- <xsl:for-each select="/document/metadata/attribute">
- <MSHelp:Attr Name="{@name}" Value="{text()}" />
- </xsl:for-each>
-
- <!-- TopicType attribute -->
- <xsl:for-each select="/document/topic/*[1]">
- <MSHelp:Attr Name="TopicType">
- <includeAttribute name="Value" item="TT_{local-name()}"/>
- </MSHelp:Attr>
- </xsl:for-each>
-
- <!-- Locale attribute -->
- <MSHelp:Attr Name="Locale">
- <includeAttribute name="Value" item="locale"/>
- </MSHelp:Attr>
-
- </xml>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="nestedKeywordText">
- <xsl:for-each select="keyword[@index='K']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:template>
-
- <!-- document body -->
-
- <!-- Title in topic -->
-
- <xsl:template name="topicTitleDecorated">
- <xsl:call-template name="topicTitle" />
- </xsl:template>
-
- <xsl:template name="topicTitlePlain">
- <xsl:call-template name="topicTitle" />
- </xsl:template>
-
- <xsl:template name="topicTitle">
- <xsl:choose>
- <xsl:when test="normalize-space(/document/metadata/title)">
- <xsl:value-of select="normalize-space(/document/metadata/title)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="normalize-space(/document/topic/*/ddue:title)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- Title in TOC -->
-
- <!-- Index entry -->
-
- <!-- main window -->
-
- <xsl:template name="main">
- <div id="mainSection">
-
- <div id="mainBody">
- <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()"/>
- <xsl:call-template name="head" />
- <xsl:call-template name="body" />
- <xsl:call-template name="foot" />
- </div>
- </div>
-
- </xsl:template>
-
- <xsl:template name="head">
- <include item="header" />
- </xsl:template>
-
- <xsl:template name="body">
- <xsl:apply-templates select="topic" />
- </xsl:template>
-
- <!-- sections that behave differently in conceptual and reference -->
-
- <xsl:template match="ddue:title">
- <!-- don't print title -->
- </xsl:template>
-
- <xsl:template match="ddue:introduction">
- <xsl:apply-templates select="@address" />
- <div class="introduction">
- <xsl:apply-templates />
- </div>
- </xsl:template>
-
- <xsl:template match="ddue:parameters">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'parameters'"/>
- <xsl:with-param name="title"><include item="parametersTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:returnValue">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'returnValue'"/>
- <xsl:with-param name="title"><include item="returnValueTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:exceptions">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'ddueExceptions'"/>
- <xsl:with-param name="title"><include item="exceptionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:relatedSections">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'relatedSections'"/>
- <xsl:with-param name="title"><include item="relatedSectionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:relatedTopics">
- <xsl:if test="$hasSeeAlsoSection">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'seeAlso'"/>
- <xsl:with-param name="title">
- <include item="relatedTopicsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
-
- <!-- Concepts sub-section -->
- <xsl:if test="normalize-space(ddue:link) or normalize-space(ddue:dynamicLink[@type='inline'])">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoConcepts"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'link' or (name() = 'dynamicLink' and @type = 'inline') or (name() = 'legacyLink' and not(starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Reference sub-section -->
- <xsl:if test="normalize-space(ddue:codeEntityReference)">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoReference"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'codeEntityReference' or (name() = 'legacyLink' and (starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Other Resources sub-section -->
- <xsl:if test="ddue:externalLink">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoOtherResources"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'externalLink'">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:codeExample">
- <!-- create Example section for the first codeExample node -->
- <xsl:if test="not(preceding-sibling::ddue:codeExample) and ../ddue:codeExample[normalize-space(.)!='']">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'example'"/>
- <xsl:with-param name="title">
- <include item="Example" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- <!-- if there are additional codeExample nodes, put them inside this section -->
- <xsl:for-each select="following-sibling::ddue:codeExample">
- <xsl:apply-templates />
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:codeReference">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template name="runningHeader">
- <xsl:variable name="runningHeaderText">
- <xsl:value-of select="/document/metadata/runningHeaderText/@uscid"/>
- </xsl:variable>
- <include item="{$runningHeaderText}" />
- </xsl:template>
-
- <!-- Footer stuff -->
-
- <xsl:template name="foot">
- <div id="footer">
- <div class="footerLine">
- <img width="100%" height="3px">
- <includeAttribute name="src" item="iconPath">
- <parameter>footer.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="footerImage" />
- </img>
- </div>
-
- <include item="footer">
- <parameter>
- <xsl:value-of select="$key"/>
- </parameter>
- <parameter>
- <xsl:call-template name="topicTitlePlain"/>
- </parameter>
- </include>
- </div>
- </xsl:template>
-
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/main_reference.xsl b/tools/Sandcastle/Presentation/hana/transforms/main_reference.xsl
deleted file mode 100644
index 57d36dc..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/main_reference.xsl
+++ /dev/null
@@ -1,447 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <!-- stuff specific to comments authored in DDUEXML -->
-
- <xsl:include href="utilities_reference.xsl" />
- <xsl:include href="utilities_dduexml.xsl" />
- <xsl:include href="htmlBody.xsl"/>
-
- <xsl:variable name="summary" select="normalize-space(/document/comments/ddue:dduexml/ddue:summary)" />
-
- <xsl:variable name="abstractSummary">
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:summary">
- <xsl:apply-templates select="." mode="abstract" />
- </xsl:for-each>
- </xsl:variable>
-
- <xsl:variable name="hasSeeAlsoSection"
- select="boolean(
- (count(/document/comments/ddue:dduexml/ddue:relatedTopics/*) > 0) or
- ($group='type' or $group='member' or $group='list')
- )"/>
- <xsl:variable name="examplesSection" select="boolean(string-length(/document/comments/ddue:dduexml/ddue:codeExamples[normalize-space(.)]) > 0)"/>
- <xsl:variable name="languageFilterSection" select="boolean(string-length(/document/comments/ddue:dduexml/ddue:codeExamples[normalize-space(.)]) > 0)" />
- <xsl:template name="body">
-
- <!--internalOnly boilerplate -->
- <xsl:call-template name="internalOnly"/>
-
- <!-- obsolete boilerplate -->
- <xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:call-template name="obsoleteSection" />
- </xsl:if>
-
- <!-- HostProtectionAttribute boilerplate -->
- <xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <p>
- <include item="hostProtectionAttributeLong">
- <parameter>
- <xsl:value-of select="concat($subgroup, 'Lower')"/>
- </parameter>
- <parameter>
- <b>
- <xsl:for-each select="/document/reference/attributes/attribute[type[@api='T:System.Security.Permissions.HostProtectionAttribute']]/assignment">
- <xsl:value-of select="@name"/>
- <xsl:if test="position() != last()">
- <xsl:text> | </xsl:text>
- </xsl:if>
- </xsl:for-each>
- </b>
- </parameter>
- </include>
- </p>
- </xsl:if>
-
- <!-- summary -->
- <span data="authoredSummary">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:summary[1]" />
- </span>
- <xsl:if test="$group='namespace'">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:remarks" />
- </xsl:if>
-
- <!-- assembly information -->
- <xsl:if test="not($group='list' or $group='root' or $group='namespace')">
- <xsl:call-template name="requirementsInfo"/>
- </xsl:if>
-
- <!-- syntax -->
- <xsl:if test="not($group='list' or $group='namespace')">
- <xsl:apply-templates select="/document/syntax" />
- </xsl:if>
-
- <!-- show authored Dependency Property Information section for properties -->
- <xsl:if test="$subgroup='property'">
- <xsl:apply-templates select="//ddue:section[starts-with(@address,'dependencyPropertyInfo')]" mode="section"/>
- </xsl:if>
-
- <!-- show authored Routed Event Information section for events -->
- <xsl:if test="$subgroup='event'">
- <xsl:apply-templates select="//ddue:section[starts-with(@address,'routedEventInfo')]" mode="section"/>
- </xsl:if>
-
- <!-- members -->
- <xsl:choose>
- <xsl:when test="$group='root'">
- <xsl:apply-templates select="/document/reference/elements" mode="root" />
- </xsl:when>
- <xsl:when test="$group='namespace'">
- <xsl:apply-templates select="/document/reference/elements" mode="namespace" />
- </xsl:when>
- <xsl:when test="$subgroup='enumeration'">
- <xsl:apply-templates select="/document/reference/elements" mode="enumeration" />
- </xsl:when>
- <xsl:when test="$group='type'">
- <xsl:apply-templates select="/document/reference/elements" mode="type" />
- </xsl:when>
- <xsl:when test="$group='list'">
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:apply-templates select="/document/reference/elements" mode="overload" />
- </xsl:when>
- <xsl:when test="$subgroup='DerivedTypeList'">
- <xsl:apply-templates select="/document/reference/elements" mode="derivedType" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates select="/document/reference/elements" mode="member" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- <!-- exceptions -->
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:exceptions" />
- <!-- remarks -->
- <xsl:if test="not($group='namespace')">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:remarks[1]" />
- </xsl:if>
- <!-- example -->
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:codeExamples" />
- <!-- permissions -->
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:permissions" />
- <!-- inheritance -->
- <xsl:apply-templates select="/document/reference/family" />
- <!-- other comment sections -->
- <xsl:if test="$subgroup='class' or $subgroup='structure'">
- <xsl:call-template name="threadSafety" />
- </xsl:if>
- <xsl:if test="not($group='list' or $group='namespace' or $group='root')">
- <!--platforms-->
- <xsl:apply-templates select="/document/reference/platforms" />
- <!--versions-->
- <xsl:apply-templates select="/document/reference/versions" />
- </xsl:if>
- <!-- see also -->
- <xsl:call-template name="seeAlsoSection"/>
-
- </xsl:template>
-
- <xsl:template name="obsoleteSection">
- <p>
- <include item="ObsoleteBoilerPlate">
- <parameter>
- <xsl:value-of select="$subgroup"/>
- </parameter>
- </include>
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:obsoleteCodeEntity">
- <xsl:text> </xsl:text>
- <include item="nonobsoleteAlternative">
- <parameter><xsl:apply-templates select="ddue:codeEntityReference" /></parameter>
- </include>
- </xsl:for-each>
- </p>
- </xsl:template>
-
- <xsl:template name="internalOnly">
- <xsl:if test="/document/comments/ddue:dduexml/ddue:internalOnly or /document/reference/containers/ddue:internalOnly">
- <div id="internalonly" class="seeAlsoNoToggleSection">
- <p/>
- <include item="internalOnly" />
- </div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="getParameterDescription">
- <xsl:param name="name" />
- <span data="authoredParameterSummary">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:parameters/ddue:parameter[string(ddue:parameterReference)=$name]/ddue:content" />
- </span>
- </xsl:template>
-
- <xsl:template match="returns">
- <xsl:if test="normalize-space(/document/comments/ddue:dduexml/ddue:returnValue)">
- <div id="returns">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include>
- <xsl:attribute name="item">
- <xsl:value-of select="$subgroup" />
- <xsl:text>ValueTitle</xsl:text>
- </xsl:attribute>
- </include>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="getReturnsDescription" />
- </xsl:with-param>
- </xsl:call-template>
- </div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="getReturnsDescription">
- <xsl:choose>
- <xsl:when test="type">
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="type/@api" />
- <xsl:with-param name="qualified" select="true()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates select="*[1]" />
- </xsl:otherwise>
- </xsl:choose>
- <br/>
- <span data="authoredValueSummary">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:returnValue" />
- </span>
- </xsl:template>
-
- <xsl:template match="templates">
- <div id="genericParameters">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title"><include item="templatesTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="template">
- <xsl:variable name="parameterName" select="@name" />
- <dl paramName="{$parameterName}">
- <dt>
- <span class="parameter"><xsl:value-of select="$parameterName"/></span>
- </dt>
- <dd>
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:genericParameters/ddue:genericParameter[string(ddue:parameterReference)=$parameterName]/ddue:content" />
- </dd>
- </dl>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </div>
- </xsl:template>
-
- <xsl:template name="getElementDescription">
- <span data="memberAuthoredSummary">
- <xsl:apply-templates select="ddue:summary[1]/ddue:para/node()" />
- </span>
- </xsl:template>
-
- <xsl:template name="getInternalOnlyDescription">
- <xsl:choose>
- <xsl:when test="ddue:internalOnly">
- <include item="infraStructure" />
- </xsl:when>
- <xsl:when test="count(element) &gt; 0">
- <xsl:variable name="internal">
- <xsl:for-each select="element">
- <xsl:if test="not(ddue:internalOnly)">
- <xsl:text>no</xsl:text>
- </xsl:if>
- </xsl:for-each>
- </xsl:variable>
- <xsl:if test="not(normalize-space($internal))">
- <include item="infraStructure" />
- </xsl:if>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="getOverloadSummary">
-
- </xsl:template>
-
- <xsl:template name="getOverloadSections">
-
- </xsl:template>
-
- <xsl:template match="syntax">
- <xsl:if test="count(*) > 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'syntax'" />
- <xsl:with-param name="title">
- <include item="syntaxTitle"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="syntaxBlocks" />
-
- <!-- parameters & return value -->
- <xsl:apply-templates select="/document/reference/templates" />
- <xsl:apply-templates select="/document/reference/parameters" />
- <xsl:apply-templates select="/document/reference/returns" />
- <xsl:apply-templates select="/document/reference/implements" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
-
- <!-- DDUEXML elements that behave differently in conceptual and reference -->
-
- <xsl:template match="ddue:exceptions">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'ddueExceptions'"/>
- <xsl:with-param name="title"><include item="exceptionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:choose>
- <xsl:when test="ddue:exception">
- <div class="listSection">
- <table class="members" width="100%" cellspacing="0" frame="lhs">
- <tr>
- <th class="exceptionNameColumn"><include item="exceptionNameHeader" /></th>
- <th class="exceptionConditionColumn"><include item="exceptionConditionHeader" /></th>
- </tr>
- <xsl:for-each select="ddue:exception">
- <tr>
- <td>
- <xsl:apply-templates select="ddue:codeEntityReference" />
- </td>
- <td>
- <xsl:apply-templates select="ddue:content" />
- </td>
- </tr>
- </xsl:for-each>
- </table>
- </div>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:permissions">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'permissions'" />
- <xsl:with-param name="title">
- <include item="permissionsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <ul>
- <xsl:for-each select="ddue:permission">
- <li>
- <xsl:apply-templates select="ddue:codeEntityReference" />
- <xsl:text> </xsl:text>
- <xsl:apply-templates select="ddue:content" />
- </li>
- </xsl:for-each>
- </ul>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:codeExample">
- <xsl:apply-templates />
- </xsl:template>
-
- <xsl:template name="runningHeader">
- <include item="runningHeaderText" />
- </xsl:template>
-
- <xsl:template name="memberIntro">
- <xsl:if test="$subgroup='members'">
- <p>
- <xsl:apply-templates select="/document/reference/containers/ddue:summary"/>
- </p>
- </xsl:if>
-
- <xsl:if test="/document/reference/elements/element/memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly']">
- <!-- if there are exposed members, show a boilerplate intro p -->
- <xsl:variable name="introTextItemId">
- <xsl:choose>
- <xsl:when test="/document/reference/containers/type/templates">genericExposedMembersTableText</xsl:when>
- <xsl:otherwise>exposedMembersTableText</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <p>
- <include item="{$introTextItemId}">
- <parameter>
- <referenceLink target="{$typeId}" />
- </parameter>
- <parameter>
- <xsl:value-of select="$subgroup"/><xsl:text>Subgroup</xsl:text>
- </parameter>
- </include>
- </p>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="mshelpCodelangAttributes">
-
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/ddue:snippets/ddue:snippet">
-
- <xsl:if test="not(@language=preceding::*/@language)">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'VBScript' or @language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'VisualBasic' or @language = 'vb' or @language = 'vb#' or @language = 'VB' or @language = 'kbLangVB'" >
- <xsl:text>kbLangVB</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'CSharp' or @language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'ManagedCPlusPlus' or @language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++' or @language = 'kbLangCPP'" >
- <xsl:text>kbLangCPP</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JSharp' or @language = 'j#' or @language = 'jsharp' or @language = 'VJ#'">
- <xsl:text>VJ#</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JScript' or @language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript' or @language = 'kbJScript'">
- <xsl:text>kbJScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xml</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$codeLang='other'" />
- <xsl:otherwise>
- <xsl:call-template name="codeLang">
- <xsl:with-param name="codeLang" select="$codeLang" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
-
- </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="ddue:codeEntityReference" mode="abstract">
- <xsl:call-template name="subString">
- <xsl:with-param name="name" select="." />
- </xsl:call-template>
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/main_sandcastle.xsl b/tools/Sandcastle/Presentation/hana/transforms/main_sandcastle.xsl
deleted file mode 100644
index cd9ac6b..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/main_sandcastle.xsl
+++ /dev/null
@@ -1,710 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
-
- <!-- stuff specified to comments authored in DDUEXML -->
-
-
- <xsl:include href="htmlBody.xsl"/>
- <xsl:include href="utilities_reference.xsl" />
-
- <xsl:variable name="summary" select="normalize-space(/document/comments/summary)" />
- <xsl:variable name="abstractSummary" select="/document/comments/summary" />
- <xsl:variable name="hasSeeAlsoSection" select="boolean((count(/document/comments/seealso | /document/comments/summary/seealso) > 0) or
- ($group='type' or $group='member' or $group='list'))"/>
- <xsl:variable name="examplesSection" select="boolean(string-length(/document/comments/example[normalize-space(.)]) > 0)"/>
- <xsl:variable name="languageFilterSection" select="boolean(string-length(/document/comments/example[normalize-space(.)]) > 0)" />
-
- <xsl:template name="body">
-
- <!-- auto-inserted info -->
- <!-- <xsl:apply-templates select="/document/reference/attributes" /> -->
- <xsl:apply-templates select="/document/comments/preliminary" />
- <xsl:apply-templates select="/document/comments/summary" />
- <xsl:if test="$subgroup='overload'">
- <xsl:apply-templates select="/document/reference/elements" mode="overloadSummary" />
- </xsl:if>
- <!-- assembly information -->
- <xsl:if test="not($group='list' or $group='root' or $group='namespace')">
- <xsl:call-template name="requirementsInfo"/>
- </xsl:if>
- <!-- syntax -->
- <xsl:if test="not($group='list' or $group='namespace')">
- <xsl:apply-templates select="/document/syntax" />
- </xsl:if>
-
- <!-- members -->
- <xsl:choose>
- <xsl:when test="$group='root'">
- <xsl:apply-templates select="/document/reference/elements" mode="root" />
- </xsl:when>
- <xsl:when test="$group='namespace'">
- <xsl:apply-templates select="/document/reference/elements" mode="namespace" />
- </xsl:when>
- <xsl:when test="$subgroup='enumeration'">
- <xsl:apply-templates select="/document/reference/elements" mode="enumeration" />
- </xsl:when>
- <xsl:when test="$group='type'">
- <xsl:apply-templates select="/document/reference/elements" mode="type" />
- </xsl:when>
- <xsl:when test="$group='list'">
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:apply-templates select="/document/reference/elements" mode="overload" />
- </xsl:when>
- <xsl:when test="$subgroup='DerivedTypeList'">
- <xsl:apply-templates select="/document/reference/elements" mode="derivedType" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates select="/document/reference/elements" mode="member" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- <!-- remarks -->
- <xsl:apply-templates select="/document/comments/remarks" />
- <!-- example -->
- <xsl:apply-templates select="/document/comments/example" />
- <!-- other comment sections -->
- <!-- permissions -->
- <xsl:call-template name="permissions" />
- <!-- exceptions -->
- <xsl:call-template name="exceptions" />
- <!-- inheritance -->
- <xsl:apply-templates select="/document/reference/family" />
- <xsl:apply-templates select="/document/comments/threadsafety" />
- <!--versions-->
- <xsl:if test="not($group='list' or $group='namespace' or $group='root' )">
- <xsl:apply-templates select="/document/reference/versions" />
- </xsl:if>
- <!-- see also -->
- <xsl:call-template name="seealso" />
-
- </xsl:template>
-
- <xsl:template name="getParameterDescription">
- <xsl:param name="name" />
- <xsl:apply-templates select="/document/comments/param[@name=$name]" />
- </xsl:template>
-
- <xsl:template name="getReturnsDescription">
- <xsl:param name="name" />
- <xsl:apply-templates select="/document/comments/param[@name=$name]" />
- </xsl:template>
-
- <xsl:template name="getElementDescription">
- <xsl:apply-templates select="summary[1]" />
- </xsl:template>
-
- <xsl:template name="getOverloadSummary">
- <xsl:apply-templates select="overloads" mode="summary"/>
- </xsl:template>
-
- <xsl:template name="getOverloadSections">
- <xsl:apply-templates select="overloads" mode="sections"/>
- </xsl:template>
-
- <xsl:template name="getInternalOnlyDescription">
-
- </xsl:template>
-
-
- <!-- block sections -->
-
- <xsl:template match="summary">
- <div class="summary">
- <xsl:apply-templates />
- </div>
- </xsl:template>
-
- <xsl:template match="overloads" mode="summary">
- <xsl:choose>
- <xsl:when test="count(summary) > 0">
- <xsl:apply-templates select="summary" />
- </xsl:when>
- <xsl:otherwise>
- <div class="summary">
- <xsl:apply-templates/>
- </div>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="overloads" mode="sections">
- <xsl:apply-templates select="remarks" />
- <xsl:apply-templates select="example"/>
- </xsl:template>
-
- <xsl:template match="value">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="fieldValueTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="returns">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="methodValueTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="templates">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'templates'" />
- <xsl:with-param name="title">
- <include item="templatesTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <dl>
- <xsl:for-each select="template">
- <xsl:variable name="templateName" select="@name" />
- <dt>
- <span class="parameter">
- <xsl:value-of select="$templateName"/>
- </span>
- </dt>
- <dd>
- <xsl:apply-templates select="/document/comments/typeparam[@name=$templateName]" />
- </dd>
- </xsl:for-each>
- </dl>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="remarks">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'remarks'"/>
- <xsl:with-param name="title"><include item="remarksTitle" /></xsl:with-param>
- <xsl:with-param name="content"><xsl:apply-templates /></xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="example">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'example'" />
- <xsl:with-param name="title"><include item="examplesTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:choose>
- <xsl:when test="code/@language">
- <xsl:variable name="codeId" select="generate-id()" />
- <table class="filter">
- <tr id="curvedTabs_{$codeId}">
- <xsl:for-each select="code">
- <td class="leftTab" x-lang="{@language}">&#xa0;</td>
- <td class="middleTab" x-lang="{@language}">&#xa0;</td>
- <td class="rightTab" x-lang="{@language}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- <tr class="tabs" id="ct_{$codeId}">
- <xsl:for-each select="code">
-
- <xsl:variable name="style">
- <xsl:call-template name="languageCheck">
- <xsl:with-param name="codeLanguage" select="@language" />
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="languageEvent">
- <xsl:choose>
- <xsl:when test="$style != ''">
- <xsl:text>languageFilter.changeLanguage(data, '</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>', '</xsl:text><xsl:value-of select="$style" />
- <xsl:text>');</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>toggleClass('ct_</xsl:text><xsl:value-of select="$codeId" />
- <xsl:text>','x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>','activeTab','tab'); curvedToggleClass('curvedTabs_</xsl:text><xsl:value-of select="$codeId"/>
- <xsl:text>','x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>'); toggleStyle('cb_</xsl:text><xsl:value-of select="$codeId"/>
- <xsl:text>', 'x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>','display','block','none');</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <td class="leftGrad" x-lang="{@language}">&#xa0;</td>
- <td class="tab" x-lang="{@language}" onclick="{$languageEvent}">
- <include item="{@language}Label" />
- </td>
- <td class="rightGrad" x-lang="{@language}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- </table>
- <div id="cb_{$codeId}">
- <xsl:for-each select="code">
- <div class="code" x-lang="{@language}">
- <xsl:call-template name="codeSection" />
- </div>
- </xsl:for-each>
- </div>
- <script type="text/javascript">
- <xsl:if test="$languages != 'false'">
- languageFilter.registerTabbedArea(<xsl:text>'curvedTabs_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>','ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>','cb_</xsl:text><xsl:value-of select="$codeId"/><xsl:text>'</xsl:text>);
- </xsl:if>
- toggleClass(<xsl:text>'ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>'</xsl:text>,'x-lang','CSharp','activeTab','tab');
- curvedToggleClass(<xsl:text>'curvedTabs_</xsl:text><xsl:value-of select="$codeId"/><xsl:text>'</xsl:text>,'x-lang', 'CSharp');
- toggleStyle(<xsl:text>'cb_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>'</xsl:text>,'x-lang','CSharp','display','block','none');
- </script>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="para">
- <p><xsl:apply-templates /></p>
- </xsl:template>
-
- <xsl:template match="code">
- <div class="code">
- <xsl:call-template name="codeSection" />
- </div>
- </xsl:template>
- <xsl:template name="exceptions">
- <xsl:if test="count(/document/comments/exception) &gt; 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'exceptions'"/>
- <xsl:with-param name="title"><include item="exceptionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="members" width="100%" cellspacing="0" frame="lhs" >
- <tr>
- <th class="exceptionNameColumn"><include item="exceptionNameHeader" /></th>
- <th class="exceptionConditionColumn"><include item="exceptionConditionHeader" /></th>
- </tr>
- <xsl:for-each select="/document/comments/exception">
- <tr>
- <td><referenceLink target="{@cref}" qualified="true" /></td>
- <td>
- <xsl:apply-templates select="." />
- </td>
- </tr>
- </xsl:for-each>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="permissions">
- <xsl:if test="count(/document/comments/permission) &gt; 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'permissions'" />
- <xsl:with-param name="title">
- <include item="permissionsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="members" width="100%" cellspacing="0" frame="lhs" >
- <tr>
- <th class="permissionNameColumn">
- <include item="permissionNameHeader" />
- </th>
- <th class="permissionDescriptionColumn">
- <include item="permissionDescriptionHeader" />
- </th>
- </tr>
- <xsl:for-each select="/document/comments/permission">
- <tr>
- <td>
- <referenceLink target="{@cref}" qualified="true" />
- </td>
- <td>
- <xsl:apply-templates select="." />
- </td>
- </tr>
- </xsl:for-each>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="seealso">
- <xsl:if test="$hasSeeAlsoSection">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'seeAlso'" />
- <xsl:with-param name="title">
- <include item="relatedTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="autogenSeeAlsoLinks"/>
- <xsl:for-each select="/document/comments/seealso | /document/comments/summary/seealso">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="." />
- </div>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="list[@type='bullet']">
- <ul>
- <xsl:for-each select="item">
- <li><xsl:apply-templates /></li>
- </xsl:for-each>
- </ul>
- </xsl:template>
-
- <xsl:template match="list[@type='number']">
- <ol>
- <xsl:for-each select="item">
- <li><xsl:apply-templates /></li>
- </xsl:for-each>
- </ol>
- </xsl:template>
-
- <xsl:template match="list[@type='table']">
- <div class="listSection">
- <table class="members" width="100%" cellspacing="0" frame="lhs" >
- <xsl:for-each select="listheader">
- <tr>
- <xsl:for-each select="*">
- <th><xsl:apply-templates /></th>
- </xsl:for-each>
- </tr>
- </xsl:for-each>
- <xsl:for-each select="item">
- <tr>
- <xsl:for-each select="*">
- <td>
- <xsl:apply-templates />
- </td>
- </xsl:for-each>
- </tr>
- </xsl:for-each>
- </table>
- </div>
- </xsl:template>
-
- <!-- inline tags -->
-
- <xsl:template match="see[@cref]">
- <xsl:choose>
- <xsl:when test="normalize-space(.)">
- <referenceLink target="{@cref}">
- <xsl:value-of select="." />
- </referenceLink>
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@cref}"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="seealso[@href]">
- <xsl:choose>
- <xsl:when test="normalize-space(.)">
- <a>
- <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
- <xsl:value-of select="." />
- </a>
- </xsl:when>
- <xsl:otherwise>
- <a>
- <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
- <xsl:value-of select="@href" />
- </a>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="see[@langword]">
- <span class="keyword">
- <xsl:choose>
- <xsl:when test="@langword='null' or @langword='Nothing' or @langword='nullptr'">
- <span class="cs">null</span>
- <span class="vb">Nothing</span>
- <span class="cpp">nullptr</span>
- </xsl:when>
- <xsl:when test="@langword='static' or @langword='Shared'">
- <span class="cs">static</span>
- <span class="vb">Shared</span>
- <span class="cpp">static</span>
- </xsl:when>
- <xsl:when test="@langword='virtual' or @langword='Overridable'">
- <span class="cs">virtual</span>
- <span class="vb">Overridable</span>
- <span class="cpp">virtual</span>
- </xsl:when>
- <xsl:when test="@langword='true' or @langword='True'">
- <span class="cs">true</span>
- <span class="vb">True</span>
- <span class="cpp">true</span>
- </xsl:when>
- <xsl:when test="@langword='false' or @langword='False'">
- <span class="cs">false</span>
- <span class="vb">False</span>
- <span class="cpp">false</span>
- </xsl:when>
- <xsl:when test="@langword='abstract'">
- <span class="cs">abstract</span>
- <span class="vb">MustInherit</span>
- <span class="cpp">abstract</span>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@langword" />
- </xsl:otherwise>
- </xsl:choose>
- </span>
- </xsl:template>
-
-
- <xsl:template match="seealso">
- <xsl:choose>
- <xsl:when test="normalize-space(.)">
- <referenceLink target="{@cref}" qualified="true">
- <xsl:value-of select="." />
- </referenceLink>
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@cref}" qualified="true" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="c">
- <span class="code">
- <xsl:value-of select="." />
- </span>
- </xsl:template>
-
- <xsl:template match="paramref">
- <span class="parameter">
- <xsl:value-of select="@name" />
- </span>
- </xsl:template>
-
- <xsl:template match="typeparamref">
- <span class="typeparameter">
- <xsl:value-of select="@name" />
- </span>
- </xsl:template>
-
- <xsl:template match="syntax">
- <xsl:if test="count(*) > 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'syntax'" />
- <xsl:with-param name="title">
- <include item="syntaxTitle"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <div id="syntaxCodeBlocks">
- <xsl:call-template name="syntaxBlocks" />
- </div>
- <!-- parameters & return value -->
- <xsl:apply-templates select="/document/reference/parameters" />
- <xsl:apply-templates select="/document/reference/templates" />
- <xsl:apply-templates select="/document/comments/value" />
- <xsl:apply-templates select="/document/comments/returns" />
- <xsl:apply-templates select="/document/reference/implements" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="runningHeader">
- <include item="runningHeaderText" />
- </xsl:template>
-
- <!-- pass through html tags -->
-
- <xsl:template match="p|ol|ul|li|dl|dt|dd|table|tr|th|td|a|img|b|i|strong|em|del|sub|sup|br|hr|h1|h2|h3|h4|h5|h6|pre|div|span|blockquote|abbr|acronym|u|font">
- <xsl:copy>
- <xsl:copy-of select="@*" />
- <xsl:apply-templates />
- </xsl:copy>
- </xsl:template>
-
- <!-- extra tag support -->
-
- <xsl:template match="threadsafety">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'threadSafety'" />
- <xsl:with-param name="title">
- <include item="threadSafetyTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:choose>
- <xsl:when test="normalize-space(.)">
- <xsl:apply-templates />
- </xsl:when>
- <xsl:otherwise>
- <xsl:if test="@static='true'">
- <include item="staticThreadSafe" />
- </xsl:if>
- <xsl:if test="@static='false'">
- <include item="staticNotThreadSafe" />
- </xsl:if>
- <xsl:if test="@instance='true'">
- <include item="instanceThreadSafe" />
- </xsl:if>
- <xsl:if test="@instance='false'">
- <include item="instanceNotThreadSafe" />
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="note">
- <div class="alert">
- <img>
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="noteAltText"/>
- </img>
- <xsl:text> </xsl:text>
- <include item="noteTitle" />
- <xsl:apply-templates />
- </div>
- </xsl:template>
-
- <xsl:template match="preliminary">
- <div class="preliminary">
- <include item="preliminaryText" />
- </div>
- </xsl:template>
-
- <!-- move these off into a shared file -->
-
- <xsl:template name="createReferenceLink">
- <xsl:param name="id" />
- <xsl:param name="qualified" select="false()" />
-
- <referenceLink target="{$id}" qualified="{$qualified}" />
-
- </xsl:template>
-
- <xsl:template name="section">
- <xsl:param name="toggleSwitch" />
- <xsl:param name="title" />
- <xsl:param name="content" />
-
- <xsl:variable name="toggleTitle" select="concat($toggleSwitch,'Toggle')" />
- <xsl:variable name="toggleSection" select="concat($toggleSwitch,'Section')" />
-
- <h1 class="heading">
- <span onclick="ExpandCollapse({$toggleTitle})" style="cursor:default;" onkeypress="ExpandCollapse_CheckKey({$toggleTitle}, event)" tabindex="0">
- <img id="{$toggleTitle}" onload="OnLoadImage(event)" class="toggle" name="toggleSwitch">
- <includeAttribute name="src" item="iconPath">
- <parameter>collapse_all.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:copy-of select="$title" />
- </span>
- </h1>
-
- <div id="{$toggleSection}" class="section" name="collapseableSection" style="">
- <xsl:copy-of select="$content" />
- </div>
-
- </xsl:template>
-
- <xsl:template name="subSection">
- <xsl:param name="title" />
- <xsl:param name="content" />
-
- <h4 class="subHeading">
- <xsl:copy-of select="$title" />
- </h4>
- <xsl:copy-of select="$content" />
-
- </xsl:template>
-
- <xsl:template name="memberIntro">
- <xsl:if test="$subgroup='members'">
- <p>
- <xsl:apply-templates select="/document/reference/containers/summary"/>
- </p>
- </xsl:if>
- <xsl:if test="/document/reference/elements/element/memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly']">
- <!-- if there are exposed members, show a boilerplate intro p -->
- <xsl:variable name="introTextItemId">
- <xsl:choose>
- <xsl:when test="/document/reference/containers/type/templates">genericExposedMembersTableText</xsl:when>
- <xsl:otherwise>exposedMembersTableText</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <p>
- <include item="{$introTextItemId}">
- <parameter>
- <referenceLink target="{$typeId}" />
- </parameter>
- <parameter>
- <xsl:value-of select="$subgroup"/><xsl:text>Subgroup</xsl:text>
- </parameter>
- </include>
- </p>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="mshelpCodelangAttributes">
- <xsl:for-each select="/document/comments/example/code">
-
- <xsl:if test="not(@language=preceding::*/@language)">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'VBScript' or @language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'VisualBasic' or @language = 'vb' or @language = 'vb#' or @language = 'VB' or @language = 'kbLangVB'" >
- <xsl:text>kbLangVB</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'CSharp' or @language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'ManagedCPlusPlus' or @language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++' or @language = 'kbLangCPP'" >
- <xsl:text>kbLangCPP</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JSharp' or @language = 'j#' or @language = 'jsharp' or @language = 'VJ#'">
- <xsl:text>VJ#</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JScript' or @language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript' or @language = 'kbJScript'">
- <xsl:text>kbJScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xml</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$codeLang='other'" />
- <xsl:otherwise>
- <xsl:call-template name="codeLang">
- <xsl:with-param name="codeLang" select="$codeLang" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
-
- </xsl:for-each>
- </xsl:template>
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/skeleton.xml b/tools/Sandcastle/Presentation/hana/transforms/skeleton.xml
deleted file mode 100644
index 4d699b9..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/skeleton.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<document>
- <reference />
- <syntax />
- <USyntax />
- <comments />
- <metadata />
-</document>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/skeleton_conceptual.xml b/tools/Sandcastle/Presentation/hana/transforms/skeleton_conceptual.xml
deleted file mode 100644
index 6de97d4..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/skeleton_conceptual.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<document>
- <metadata />
-</document>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/utilities_dduexml.xsl b/tools/Sandcastle/Presentation/hana/transforms/utilities_dduexml.xsl
deleted file mode 100644
index e652388..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/utilities_dduexml.xsl
+++ /dev/null
@@ -1,1293 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:import href="../../shared/transforms/utilities_dduexml.xsl" />
-
- <!-- sections -->
-
- <!-- the Remarks section includes content from these nodes, excluding the xaml sections are captured in the xaml syntax processing -->
- <xsl:template name="HasRemarksContent">
- <xsl:choose>
- <xsl:when test="normalize-space(ddue:content)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForImplementers)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForCallers)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForInheritors)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:platformNotes)">true</xsl:when>
- <xsl:when test="normalize-space(ddue:sections/ddue:section[not(
- starts-with(@address,'xamlValues') or
- starts-with(@address,'xamlTextUsage') or
- starts-with(@address,'xamlAttributeUsage') or
- starts-with(@address,'xamlPropertyElementUsage') or
- starts-with(@address,'xamlImplicitCollectionUsage') or
- starts-with(@address,'xamlObjectElementUsage') or
- starts-with(@address,'dependencyPropertyInfo') or
- starts-with(@address,'routedEventInfo')
- )])">true</xsl:when>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="ddue:remarks">
- <xsl:variable name="hasRemarks">
- <xsl:call-template name="HasRemarksContent"/>
- </xsl:variable>
- <xsl:if test="$hasRemarks='true'">
- <xsl:choose>
- <xsl:when test="not($group = 'namespace')">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'remarks'"/>
- <xsl:with-param name="title"><include item="remarksTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- <xsl:apply-templates select="../ddue:notesForImplementers"/>
- <xsl:apply-templates select="../ddue:notesForCallers"/>
- <xsl:apply-templates select="../ddue:notesForInheritors"/>
- <xsl:apply-templates select="../ddue:platformNotes"/>
- <include item="mshelpKTable">
- <parameter>
- <xsl:text>tt_</xsl:text>
- <xsl:value-of select="$key"/>
- </parameter>
- </include>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:codeExamples">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'example'"/>
- <xsl:with-param name="title">
- <include item="examplesTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- <xsl:call-template name="moreCodeSection"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <!--
- **************************************************************
- CODE EXAMPLES section
- **************************************************************
- -->
- <!-- tasks/task nodes are inserted by TaskGrabberComponent which gets content from HowTo topics -->
- <!-- these nodes are handled below in the moreCodeSection -->
- <xsl:template match="ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/tasks"/>
-
- <xsl:template name="moreCodeSection">
- <xsl:variable name="gotCodeAlready" select="boolean(
- (ddue:codeExample/ddue:legacy/ddue:content[ddue:codeReference[ddue:sampleCode] | ddue:code | ddue:snippets/ddue:snippet]) or
- (ddue:codeExample[ddue:codeReference[ddue:sampleCode] | ddue:code | ddue:snippets/ddue:snippet])
- )"/>
-
- <xsl:variable name="gotMoreCode" select="(count(ddue:codeExample/ddue:legacy/ddue:content/tasks/task)&gt;1) or
- ($gotCodeAlready and count(ddue:codeExample/ddue:legacy/ddue:content/tasks/task)&gt;0)"/>
-
- <!-- if no preceding code in the code examples section, display the tasks[1]/task[1] -->
- <xsl:if test="not($gotCodeAlready)">
- <xsl:for-each select="ddue:codeExample/ddue:legacy/ddue:content/tasks[1]/task[1]">
- <xsl:apply-templates select="ddue:introduction | ddue:codeExample"/>
- </xsl:for-each>
- </xsl:if>
-
- <xsl:if test="$gotMoreCode">
- <sections>
- <h4 class="subHeading">
- <include item="mrefTaskMoreCodeHeading" />
- </h4>
- <div class="subsection">
- <div class="listSection">
- <table class="members" width="100%" cellspacing="0">
- <xsl:for-each select="ddue:codeExample/ddue:legacy/ddue:content/tasks/task">
- <xsl:choose>
- <xsl:when test="not($gotCodeAlready) and position()=1"/>
- <xsl:otherwise>
- <tr valign="top">
- <td>
- <conceptualLink target="{@topicId}">
- <xsl:value-of select="ddue:title"/>
- </conceptualLink>
- </td>
- <td>
- <xsl:choose>
- <xsl:when test="ddue:introduction/ddue:para[1][normalize-space(.)!='']">
- <xsl:apply-templates select="ddue:introduction/ddue:para[1]/node()"/>
- </xsl:when>
- <xsl:when test="ddue:codeExample/ddue:legacy/ddue:content/ddue:para[1][normalize-space(.)!='']">
- <xsl:apply-templates select="ddue:codeExample/ddue:legacy/ddue:content/ddue:para[1]/node()"/>
- </xsl:when>
- </xsl:choose>
- </td>
- </tr>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
- </table>
- </div>
- </div>
- </sections>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="threadSafety">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'threadSafety'"/>
- <xsl:with-param name="title"><include item="threadSafetyTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:choose>
- <xsl:when test="/document/comments/ddue:dduexml/ddue:threadSafety">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:threadSafety"/>
- </xsl:when>
- <xsl:otherwise>
- <include item="ThreadSafetyBP"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="ddue:notesForImplementers">
- <p/>
- <b>
- <include item="NotesForImplementers"/>
- </b>
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:notesForCallers">
- <p/>
- <b>
- <include item="NotesForCallers"/>
- </b>
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:notesForInheritors">
- <p/>
- <b>
- <include item="NotesForInheritors"/>
- </b>
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:platformNotes">
- <xsl:for-each select="ddue:platformNote[normalize-space(ddue:content)]">
- <p>
- <include item="PlatformNote">
- <parameter>
- <xsl:for-each select="ddue:platforms/ddue:platform">
- <xsl:variable name="platformName"><xsl:value-of select="."/></xsl:variable>
- <include item="{$platformName}"/>
- <xsl:if test="position() != last()">, </xsl:if>
- </xsl:for-each>
- </parameter>
- <parameter><xsl:apply-templates select="ddue:content"/></parameter>
- </include>
- </p>
- </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="ddue:schemaHierarchy">
- <xsl:for-each select="ddue:link">
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="position()"/>
- </xsl:call-template>
- <xsl:apply-templates select="."/>
- <br/>
- </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="ddue:syntaxSection">
- <div id="syntaxSection" class="section">
- <div id="syntaxCodeBlocks">
- <xsl:for-each select="ddue:legacySyntax">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb' or @language = 'vb#' or @language = 'VB'" >
- <xsl:text>VisualBasic</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++'" >
- <xsl:text>ManagedCPlusPlus</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'j#' or @language = 'jsharp'">
- <xsl:text>JSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript'">
- <xsl:text>JScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xmlLang</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <span codeLanguage="{$codeLang}">
- <table width="100%" cellspacing="0" cellpadding="0">
- <tr>
- <th align="left">
- <include item="{$codeLang}"/>
- </th>
- </tr>
- <tr>
- <td>
- <pre>
- <xsl:apply-templates xml:space="preserve"/>
- </pre>
- </td>
- </tr>
- </table>
- </span>
-
- </xsl:for-each>
- </div>
- </div>
- </xsl:template>
-
- <xsl:template name="seeAlsoSection">
-
- <xsl:if test="$hasSeeAlsoSection">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'seeAlso'"/>
- <xsl:with-param name="title"><include item="relatedTitle" /></xsl:with-param>
- <xsl:with-param name="content">
-
- <!-- Concepts sub-section -->
- <xsl:if test="normalize-space(ddue:link) or normalize-space(ddue:dynamicLink[@type='inline'])">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoConcepts"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'link' or (name() = 'dynamicLink' and @type = 'inline') or (name() = 'legacyLink' and not(starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Reference sub-section (always one of these in an API topic) -->
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoReference"/>
- </xsl:with-param>
-
- <xsl:with-param name="content">
- <xsl:call-template name="autogenSeeAlsoLinks"/>
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'codeEntityReference' or (name() = 'legacyLink' and (starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
-
- <!-- Other Resources sub-section -->
- <xsl:if test="ddue:externalLink">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoOtherResources"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'externalLink'">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <!-- just skip over these -->
- <xsl:template match="ddue:content | ddue:legacy">
- <xsl:apply-templates />
- </xsl:template>
-
- <!-- block elements -->
-
- <xsl:template match="ddue:table">
- <div class="listSection">
- <table class="members" width="50%" cellspacing="0" frame="lhs">
- <xsl:apply-templates />
- </table>
- </div>
- </xsl:template>
-
- <xsl:template match="ddue:tableHeader">
- <xsl:apply-templates />
- </xsl:template>
-
- <xsl:template match="ddue:row">
- <tr>
- <xsl:apply-templates />
- </tr>
- </xsl:template>
-
- <xsl:template match="ddue:entry">
- <td>
- <xsl:apply-templates />
- </td>
- </xsl:template>
-
- <xsl:template match="ddue:tableHeader/ddue:row/ddue:entry">
- <th>
- <xsl:apply-templates />
- </th>
- </xsl:template>
-
- <xsl:template match="ddue:definitionTable">
- <dl>
- <xsl:apply-templates />
- </dl>
- </xsl:template>
-
- <xsl:template match="ddue:definedTerm">
- <dt><span class="nonLinkTerm"><xsl:apply-templates /></span></dt>
- </xsl:template>
-
- <xsl:template match="ddue:definition">
- <dd>
- <xsl:apply-templates />
- </dd>
- </xsl:template>
-
- <xsl:template match="ddue:code">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb' or @language = 'vb#' or @language = 'VB'" >
- <xsl:text>VisualBasic</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++'" >
- <xsl:text>ManagedCPlusPlus</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'j#' or @language = 'jsharp'">
- <xsl:text>JSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript'">
- <xsl:text>JScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xmlLang</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="titleName" select="../../ddue:title"/>
-
- <xsl:choose>
- <xsl:when test="(($titleName = 'Output') or ($titleName = 'Input') or ($titleName = 'SampleOutput'))">
- <div class="code">
- <table width="100%" cellspacing="0" cellpadding="0">
- <tr>
- <th>
- <xsl:text>&#xa0;</xsl:text>
- </th>
-
- </tr>
- <tr>
- <td colspan="2">
- <pre>
- <xsl:apply-templates/>
- </pre>
- </td>
- </tr>
- </table>
- </div>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="codeSection">
- <xsl:with-param name="codeLang" select="$codeLang" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
-
- <xsl:template match="ddue:sampleCode">
- <div><b><xsl:value-of select="@language"/></b></div>
- <div class="code"><pre><xsl:apply-templates /></pre></div>
- </xsl:template>
-
- <xsl:template name="composeCode">
- <xsl:copy-of select="." />
- <xsl:variable name="next" select="following-sibling::*[1]" />
- <xsl:if test="boolean($next/@language) and boolean(local-name($next)=local-name())">
- <xsl:for-each select="$next">
- <xsl:call-template name="composeCode" />
- </xsl:for-each>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:alert">
- <div class="alert">
- <table width="100%" cellspacing="0" cellpadding="0">
- <tr>
- <th align="left">
- <xsl:choose>
- <xsl:when test="@class='tip'">
- <img class="note">
- <includeAttribute name="title" item="tipAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="tipTitle" />
- </xsl:when>
- <xsl:when test="@class='caution' or @class='warning'">
- <img class="note">
- <includeAttribute name="title" item="cautionAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_caution.gif</parameter>
- </includeAttribute>
- </img>
- <include item="cautionTitle" />
- </xsl:when>
- <xsl:when test="@class='security note'">
- <img class="note">
- <includeAttribute name="title" item="securityAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_security.gif</parameter>
- </includeAttribute>
- </img>
- <include item="securityTitle" />
- </xsl:when>
- <xsl:when test="@class='important'">
- <img class="note">
- <includeAttribute name="title" item="importantAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_caution.gif</parameter>
- </includeAttribute>
- </img>
- <include item="importantTitle" />
- </xsl:when>
- <xsl:when test="@class='visual basic note'">
- <img class="note">
- <includeAttribute name="title" item="visualBasicAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="visualBasicTitle" />
- </xsl:when>
- <xsl:when test="@class='visual c# note'">
- <img class="note">
- <includeAttribute name="title" item="visualC#AltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="visualC#Title" />
- </xsl:when>
- <xsl:when test="@class='visual c++ note'">
- <img class="note">
- <includeAttribute name="title" item="visualC++AltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="visualC++Title" />
- </xsl:when>
- <xsl:when test="@class='visual j# note'">
- <img class="note">
- <includeAttribute name="title" item="visualJ#AltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="visualJ#Title" />
- </xsl:when>
- <xsl:when test="@class='note'">
- <img class="note">
- <includeAttribute name="title" item="noteAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="noteTitle" />
- </xsl:when>
- <xsl:otherwise>
- <img class="note">
- <includeAttribute name="title" item="noteAltText" />
- <includeAttribute item="iconPath" name="src">
- <parameter>alert_note.gif</parameter>
- </includeAttribute>
- </img>
- <include item="{@class}" />
- </xsl:otherwise>
- </xsl:choose>
- </th>
- </tr>
- <tr>
- <td>
- <xsl:apply-templates/>
- </td>
- </tr>
- </table>
- </div>
- </xsl:template>
-
- <xsl:template match="ddue:sections">
- <xsl:apply-templates select="ddue:section" />
- </xsl:template>
-
- <xsl:template match="ddue:section">
- <xsl:if test="descendant::ddue:content[normalize-space(.)]">
- <xsl:apply-templates select="@address" />
- <!-- Count all the possible ancestor root nodes -->
- <xsl:variable name="a1" select="count(ancestor::ddue:attributesandElements)" />
- <xsl:variable name="a2" select="count(ancestor::ddue:codeExample)" />
- <xsl:variable name="a3" select="count(ancestor::ddue:dotNetFrameworkEquivalent)" />
- <xsl:variable name="a4" select="count(ancestor::ddue:elementInformation)" />
- <xsl:variable name="a5" select="count(ancestor::ddue:exceptions)" />
- <xsl:variable name="a6" select="count(ancestor::ddue:introduction)" />
- <xsl:variable name="a7" select="count(ancestor::ddue:languageReferenceRemarks)" />
- <xsl:variable name="a8" select="count(ancestor::ddue:nextSteps)" />
- <xsl:variable name="a9" select="count(ancestor::ddue:parameters)" />
- <xsl:variable name="a10" select="count(ancestor::ddue:prerequisites)" />
- <xsl:variable name="a11" select="count(ancestor::ddue:procedure)" />
- <xsl:variable name="a12" select="count(ancestor::ddue:relatedTopics)" />
- <xsl:variable name="a13" select="count(ancestor::ddue:remarks)" />
- <xsl:variable name="a14" select="count(ancestor::ddue:requirements)" />
- <xsl:variable name="a15" select="count(ancestor::ddue:schemaHierarchy)" />
- <xsl:variable name="a16" select="count(ancestor::ddue:syntaxSection)" />
- <xsl:variable name="a17" select="count(ancestor::ddue:textValue)" />
- <xsl:variable name="a18" select="count(ancestor::ddue:type)" />
- <xsl:variable name="a19" select="count(ancestor::ddue:section)" />
- <xsl:variable name="total" select="$a1+$a2+$a3+$a4+$a5+$a6+$a7+$a8+$a9+$a10+$a11+$a12+$a13+$a14+$a15+$a16+$a17+$a18+$a19" />
- <xsl:choose>
- <xsl:when test="$total = 0">
- <xsl:variable name="sectionCount">
- <xsl:value-of select="count(preceding-sibling::ddue:section)"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="ddue:title">
- <h1 class="heading">
- <span onclick="ExpandCollapse(sectionToggle{$sectionCount})" style="cursor:default;" onkeypress="ExpandCollapse_CheckKey(sectionToggle{$sectionCount}, event)" tabindex="0">
- <img id="sectionToggle{$sectionCount}" onload="OnLoadImage(event)" class="toggle" name="toggleSwitch">
- <includeAttribute name="src" item="iconPath">
- <parameter>collapse_all.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:value-of select="ddue:title" />
- </span>
- </h1>
- <div id="sectionSection{$sectionCount}" class="section" name="collapseableSection" style="">
- <xsl:apply-templates select="ddue:content"/>
- <xsl:apply-templates select="ddue:sections" />
- </div>
- </xsl:when>
- <xsl:otherwise>
- <div id="sectionSection{$sectionCount}" class="seeAlsoNoToggleSection">
- <xsl:apply-templates select="ddue:content"/>
- <xsl:apply-templates select="ddue:sections"/>
- </div>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$total = 1">
- <h3 class="subHeading">
- <xsl:value-of select="ddue:title"/>
- </h3>
- <div class="subsection">
- <xsl:apply-templates select="ddue:content"/>
- <xsl:apply-templates select="ddue:sections" />
- </div>
- </xsl:when>
- <xsl:otherwise>
- <h4 class="subHeading">
- <xsl:value-of select="ddue:title"/>
- </h4>
- <div class="subsection">
- <xsl:apply-templates select="ddue:content"/>
- <xsl:apply-templates select="ddue:sections" />
- </div>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-<!--
- <xsl:template match="@address">
- <a name="{string(.)}" />
- </xsl:template>
--->
- <xsl:template match="ddue:mediaLink|ddue:mediaLinkInline">
- <span class="media">
- <xsl:if test="ddue:caption">
- <div class="caption">
- <xsl:apply-templates select="ddue:caption" />
- </div>
- <br />
- </xsl:if>
- <artLink target="{ddue:image/@xlink:href}" />
- </span>
- </xsl:template>
-
- <xsl:template match="ddue:procedure">
- <xsl:if test="normalize-space(ddue:title)">
- <h3 class="procedureSubHeading">
- <xsl:value-of select="ddue:title"/>
- </h3>
- </xsl:if>
- <div class="subSection">
- <xsl:apply-templates select="ddue:steps"/>
- <xsl:apply-templates select="ddue:conclusion"/>
- </div>
- </xsl:template>
-
- <xsl:template match="ddue:steps">
- <xsl:choose>
- <xsl:when test="@class = 'ordered'">
- <xsl:variable name="temp">
- <xsl:value-of select="count(ddue:step)"/>
- </xsl:variable>
- <xsl:if test="$temp = 1">
- <ul>
- <xsl:apply-templates select="ddue:step"/>
- </ul>
- </xsl:if>
- <xsl:if test="$temp &gt; 1">
- <ol>
- <xsl:apply-templates select="ddue:step"/>
- </ol>
- </xsl:if>
- </xsl:when>
- <xsl:when test="@class='bullet'">
- <ul>
- <xsl:apply-templates select="ddue:step" />
- </ul>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="ddue:step">
- <li><xsl:apply-templates /></li>
- </xsl:template>
-
-
- <xsl:template match="ddue:inThisSection">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'inThisSection'"/>
- <xsl:with-param name="title"><include item="inThisSectionTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:buildInstructions">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'buildInstructions'"/>
- <xsl:with-param name="title"><include item="buildInstructionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:nextSteps">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'nextSteps'"/>
- <xsl:with-param name="title"><include item="nextStepsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:requirements">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'requirementsTitle'"/>
- <xsl:with-param name="title"><include item="requirementsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <!-- inline elements -->
-
- <xsl:template match="ddue:languageKeyword">
- <xsl:variable name="word" select="." />
- <span class="keyword" data="langKeyword" value="{$word}">
- <xsl:choose>
- <xsl:when test="$word='null' or $word='Nothing' or $word='nullptr'">
- <span class="cs">null</span>
- <span class="vb">Nothing</span>
- <span class="cpp">nullptr</span>
- </xsl:when>
- <xsl:when test="$word='static' or $word='Shared'">
- <span class="cs">static</span>
- <span class="vb">Shared</span>
- <span class="cpp">static</span>
- </xsl:when>
- <xsl:when test="$word='virtual' or $word='Overridable'">
- <span class="cs">virtual</span>
- <span class="vb">Overridable</span>
- <span class="cpp">virtual</span>
- </xsl:when>
- <xsl:when test="$word='true' or $word='True'">
- <span class="cs">true</span>
- <span class="vb">True</span>
- <span class="cpp">true</span>
- </xsl:when>
- <xsl:when test="$word='false' or $word='False'">
- <span class="cs">false</span>
- <span class="vb">False</span>
- <span class="cpp">false</span>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="." />
- </xsl:otherwise>
- </xsl:choose>
- </span>
- </xsl:template>
-
- <!-- links -->
-
- <xsl:template match="ddue:dynamicLink[@type='inline']">
- <MSHelp:ktable disambiguator='span' indexMoniker='!DefaultDynamicLinkIndex'>
- <xsl:attribute name="keywords">
- <xsl:for-each select="ddue:keyword">
- <xsl:value-of select="."/>
- <xsl:if test="position() != last()">;</xsl:if>
- </xsl:for-each>
- </xsl:attribute>
- <includeAttribute name="prefix" item="dynamicLinkInlinePreFixText" />
- <includeAttribute name="postfix" item="dynamicLinkInlinePostFixText" />
- <includeAttribute name="separator" item="dynamicLinkInlineSeperatorText" />
- </MSHelp:ktable>
- </xsl:template>
-
- <xsl:template match="ddue:dynamicLink[@type='table']">
- <include item="mshelpKTable">
- <parameter>
- <xsl:for-each select="ddue:keyword">
- <xsl:value-of select="."/>
- <xsl:if test="position() != last()">;</xsl:if>
- </xsl:for-each>
- </parameter>
- </include>
- </xsl:template>
-
- <xsl:template match="ddue:dynamicLink[@type='bulleted']">
- <MSHelp:ktable disambiguator='span' indexMoniker='!DefaultDynamicLinkIndex'>
- <xsl:attribute name="keywords">
- <xsl:for-each select="ddue:keyword">
- <xsl:value-of select="."/>
- <xsl:if test="position() != last()">;</xsl:if>
- </xsl:for-each>
- </xsl:attribute>
- <xsl:attribute name="prefix">&lt;ul&gt;&lt;li&gt;</xsl:attribute>
- <xsl:attribute name="postfix">&lt;/li&gt;&lt;/ul&gt;</xsl:attribute>
- <xsl:attribute name="separator">&lt;/li&gt;&lt;li&gt;</xsl:attribute>
- </MSHelp:ktable>
- </xsl:template>
-
- <xsl:template match="ddue:codeFeaturedElement">
- <xsl:if test="normalize-space(.)">
- <xsl:if test="count(preceding::ddue:codeFeaturedElement) &gt; 0"><br/></xsl:if>
- <b><xsl:apply-templates/></b>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:languageReferenceRemarks">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'languageReferenceRemarks'"/>
- <xsl:with-param name="title">
- <include item="remarksTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:attributesandElements">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'attributesAndElements'"/>
- <xsl:with-param name="title">
- <include item="attributesAndElements" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:attributes">
- <xsl:if test="normalize-space(.)">
- <h4 class="subHeading">
- <include item="attributes"/>
- </h4>
- <xsl:apply-templates/>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:attribute">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:attribute/ddue:title">
- <h4 class="subHeading">
- <xsl:apply-templates/>
- </h4>
- </xsl:template>
-
- <xsl:template match="ddue:childElement">
- <xsl:if test="normalize-space(.)">
- <h4 class="subHeading">
- <include item="childElement"/>
- </h4>
- <xsl:apply-templates/>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:parentElement">
- <xsl:if test="normalize-space(.)">
- <h4 class="subHeading">
- <include item="parentElement"/>
- </h4>
- <xsl:apply-templates/>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:textValue">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'textValue'"/>
- <xsl:with-param name="title">
- <include item="textValue" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:elementInformation">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'elementInformation'"/>
- <xsl:with-param name="title">
- <include item="elementInformation" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:dotNetFrameworkEquivalent">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'dotNetFrameworkEquivalent'"/>
- <xsl:with-param name="title">
- <include item="dotNetFrameworkEquivalent" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:prerequisites">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'prerequisites'"/>
- <xsl:with-param name="title">
- <include item="prerequisites" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:type">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:robustProgramming">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'robustProgramming'"/>
- <xsl:with-param name="title">
- <include item="robustProgramming" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:security">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'security'"/>
- <xsl:with-param name="title">
- <include item="securitySection" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:externalResources">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'externalResources'"/>
- <xsl:with-param name="title">
- <include item="externalResources" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:demonstrates">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'demonstrates'"/>
- <xsl:with-param name="title">
- <include item="demonstrates" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:appliesTo">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'appliesTo'"/>
- <xsl:with-param name="title">
- <include item="appliesTo" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:conclusion">
- <xsl:apply-templates/>
- </xsl:template>
-
- <xsl:template match="ddue:background">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'background'"/>
- <xsl:with-param name="title">
- <include item="background" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:whatsNew">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'whatsNew'"/>
- <xsl:with-param name="title">
- <include item="whatsNew" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:reference">
- <xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'reference'"/>
- <xsl:with-param name="title">
- <include item="reference" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:developerErrorMessageDocument">
- <xsl:for-each select="*">
- <xsl:choose>
- <xsl:when test="name() = 'secondaryErrorTitle'">
- <xsl:if test="not(../ddue:nonLocErrorTitle)">
- <xsl:apply-templates select=".">
- <xsl:with-param name="newSection">yes</xsl:with-param>
- </xsl:apply-templates>
- </xsl:if>
- </xsl:when>
-
- <xsl:otherwise><xsl:apply-templates select="." /></xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-
- </xsl:template>
-
- <xsl:template match="ddue:nonLocErrorTitle">
- <xsl:if test="string-length(../ddue:nonLocErrorTitle[normalize-space(.)]) > 0 or string-length(../ddue:secondaryErrorTitle[normalize-space(.)]) > 0">
- <div id="errorTitleSection" class="section">
- <xsl:if test="../ddue:secondaryErrorTitle">
- <h4 class="subHeading"><include item="errorMessage"/></h4>
- <xsl:apply-templates select="../ddue:secondaryErrorTitle">
- <xsl:with-param name="newSection">no</xsl:with-param>
- </xsl:apply-templates>
- </xsl:if>
- <xsl:apply-templates/><p/>
- </div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="ddue:secondaryErrorTitle">
- <xsl:param name="newSection"/>
- <xsl:if test="string-length(../ddue:secondaryErrorTitle[normalize-space(.)]) > 0">
- <xsl:choose>
- <xsl:when test="$newSection = 'yes'">
- <div id="errorTitleSection" class="section">
- <xsl:apply-templates/><p/>
- </div>
- </xsl:when>
- <xsl:otherwise><xsl:apply-templates/><br/></xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
-
- <xsl:template name="createReferenceLink">
- <xsl:param name="id" />
- <xsl:param name="qualified" select="false()" />
- <referenceLink target="{$id}" qualified="{$qualified}" />
- </xsl:template>
-
- <xsl:template match="ddue:snippets">
- <xsl:variable name="codeId" select="generate-id()" />
- <table class="filter" cellspacing="0" cellpadding="0">
- <tr id="curvedTabs_{$codeId}">
- <xsl:for-each select="ddue:snippet">
- <td class="leftTab" x-lang="{@language}">&#xa0;</td>
- <td class="middleTab" x-lang="{@language}">&#xa0;</td>
- <td class="rightTab" x-lang="{@language}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- <tr class="tabs" id="ct_{$codeId}">
- <xsl:for-each select="ddue:snippet">
-
- <xsl:variable name="style">
- <xsl:call-template name="languageCheck">
- <xsl:with-param name="codeLanguage" select="@language" />
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="languageEvent">
- <xsl:choose>
- <xsl:when test="$style != ''">
- <xsl:text>languageFilter.changeLanguage(data, '</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>', '</xsl:text><xsl:value-of select="$style" />
- <xsl:text>');</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>toggleClass('ct_</xsl:text><xsl:value-of select="$codeId" />
- <xsl:text>','x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>','activeTab','tab'); curvedToggleClass('curvedTabs_</xsl:text><xsl:value-of select="$codeId"/>
- <xsl:text>','x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>'); toggleStyle('cb_</xsl:text><xsl:value-of select="$codeId"/>
- <xsl:text>', 'x-lang','</xsl:text><xsl:value-of select="@language"/>
- <xsl:text>','display','block','none');</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <td class="leftGrad" x-lang="{@language}">&#xa0;</td>
- <td class="tab" x-lang="{@language}" onclick="{$languageEvent}">
- <include item="{@language}Label" />
- </td>
- <td class="rightGrad" x-lang="{@language}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- </table>
- <div id="cb_{$codeId}">
- <xsl:for-each select="ddue:snippet">
- <div class="code" x-lang="{@language}">
- <xsl:call-template name="codeSection" />
- </div>
- </xsl:for-each>
- </div>
- <script type="text/javascript">
- <xsl:if test="$languages != 'false'">
- languageFilter.registerTabbedArea(<xsl:text>'curvedTabs_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>','ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>','cb_</xsl:text><xsl:value-of select="$codeId"/><xsl:text>'</xsl:text>);
- </xsl:if>
- toggleClass(<xsl:text>'ct_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>'</xsl:text>,'x-lang','CSharp','activeTab','tab');
- curvedToggleClass(<xsl:text>'curvedTabs_</xsl:text><xsl:value-of select="$codeId"/><xsl:text>'</xsl:text>,'x-lang', 'CSharp');
- toggleStyle(<xsl:text>'cb_</xsl:text><xsl:value-of select="$codeId" /><xsl:text>'</xsl:text>,'x-lang','CSharp','display','block','none');
- </script>
- </xsl:template>
-
- <xsl:template name="section">
- <xsl:param name="toggleSwitch" />
- <xsl:param name="title" />
- <xsl:param name="content" />
-
- <xsl:variable name="toggleTitle" select="concat($toggleSwitch,'Toggle')" />
- <xsl:variable name="toggleSection" select="concat($toggleSwitch,'Section')" />
-
- <h1 class="heading">
- <span onclick="ExpandCollapse({$toggleTitle})" style="cursor:default;" onkeypress="ExpandCollapse_CheckKey({$toggleTitle}, event)" tabindex="0">
- <img id="{$toggleTitle}" onload="OnLoadImage(event)" class="toggle" name="toggleSwitch">
- <includeAttribute name="src" item="iconPath">
- <parameter>collapse_all.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:copy-of select="$title" />
- </span>
- </h1>
-
- <div id="{$toggleSection}" class="section" name="collapseableSection" style="">
- <xsl:copy-of select="$content" />
- </div>
-
- </xsl:template>
-
- <xsl:template name="subSection">
- <xsl:param name="title" />
- <xsl:param name="content" />
-
- <h4 class="subHeading">
- <xsl:copy-of select="$title" />
- </h4>
- <xsl:copy-of select="$content" />
-
- </xsl:template>
-
- <!-- capture authored glossary <link> nodes -->
- <xsl:template match="ddue:link[starts-with(.,'GTMT#')]">
- <!-- not supporting popup definitions; just show the display text -->
- <span data="link">
- <xsl:value-of select="substring-after(.,'GTMT#')"/>
- </span>
- </xsl:template>
-
-
- <!-- fail if any unknown elements are encountered -->
- <!--
- <xsl:template match="*">
- <xsl:message terminate="yes">
- <xsl:text>An unknown element was encountered.</xsl:text>
- </xsl:message>
- </xsl:template>
--->
-
- <xsl:template match="ddue:developerSampleDocument">
- <!-- show the topic intro -->
- <xsl:apply-templates select="ddue:introduction"/>
-
- <!-- the sample download list section from dsSample -->
- <xsl:if test="ddue:relatedTopics/ddue:sampleRef">
- <include item="{ddue:relatedTopics/ddue:sampleRef/@srcID}"/>
- </xsl:if>
-
- <!-- then the rest of the topic's content -->
- <xsl:for-each select="*">
- <xsl:choose>
- <!-- introduction was already captured above -->
- <xsl:when test="name() = 'introduction'"/>
-
- <xsl:otherwise>
- <xsl:apply-templates select="." />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:for-each>
-
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/utilities_metadata.xsl b/tools/Sandcastle/Presentation/hana/transforms/utilities_metadata.xsl
deleted file mode 100644
index 8da8e5e..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/utilities_metadata.xsl
+++ /dev/null
@@ -1,928 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:import href="../../shared/transforms/utilities_metadata.xsl" />
-
- <xsl:template name="insertMetadata">
- <xsl:if test="$metadata='true'">
- <xml>
- <xsl:call-template name="mshelpTitles" />
- <MSHelp:Attr Name="AssetID" Value="{$key}" />
- <!-- toc metadata -->
- <xsl:call-template name="linkMetadata" />
- <xsl:call-template name="indexMetadata" />
- <xsl:call-template name="helpMetadata" />
- <xsl:call-template name="helpPriorityMetadata" />
- <xsl:call-template name="apiTaggingMetadata" />
- <xsl:call-template name="mshelpDevlangAttributes" />
- <MSHelp:Attr Name="Locale">
- <includeAttribute name="Value" item="locale" />
- </MSHelp:Attr>
- <!-- attribute to allow F1 help integration -->
- <MSHelp:Attr Name="TopicType">
- <includeAttribute name="Value" item="TT_ManagedReference"/>
- </MSHelp:Attr>
-
- <!-- Abstract -->
- <xsl:choose>
- <xsl:when test="string-length($abstractSummary) &gt; 254">
- <MSHelp:Attr Name="Abstract" Value="{normalize-space(concat(substring($abstractSummary,1,250), ' ...'))}" />
- </xsl:when>
- <xsl:when test="string-length($abstractSummary) &gt; 0">
- <MSHelp:Attr Name="Abstract" Value="{normalize-space($abstractSummary)}" />
- </xsl:when>
- </xsl:choose>
-
- <xsl:call-template name="mshelpCodelangAttributes" />
- <xsl:call-template name="versionMetadata" />
- <xsl:call-template name="authoredMetadata" />
- </xml>
- </xsl:if>
- </xsl:template>
-
- <!-- add DocSet and Technology attributes depending on the versions that support this api -->
- <xsl:template name="versionMetadata">
- <xsl:variable name="supportedOnCf">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:variable>
- <xsl:if test="count(/document/reference/versions/versions[@name='netfw']/version) &gt; 0">
- <MSHelp:Attr Name="Technology">
- <includeAttribute name="Value" item="desktopTechnologyAttribute" />
- </MSHelp:Attr>
- </xsl:if>
- <xsl:if test="count(/document/reference/versions/versions[@name='netcfw']/version) &gt; 0 or normalize-space($supportedOnCf)!=''">
- <MSHelp:Attr Name="Technology">
- <includeAttribute name="Value" item="netcfTechnologyAttribute" />
- </MSHelp:Attr>
- <MSHelp:Attr Name="DocSet">
- <includeAttribute name="Value" item="netcfDocSetAttribute" />
- </MSHelp:Attr>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="authoredMetadata">
-
- <!-- authored attributes -->
- <xsl:for-each select="/document/metadata/attribute">
- <MSHelp:Attr Name="{@name}" Value="{text()}" />
- </xsl:for-each>
-
- <!-- authored K -->
- <xsl:for-each select="/document/metadata/keyword[@index='K']">
- <MSHelp:Keyword Index="K">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='K']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored F -->
- <xsl:for-each select="/document/metadata/keyword[@index='F']">
- <MSHelp:Keyword Index="F">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='F']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored B -->
- <xsl:for-each select="/document/metadata/keyword[@index='B']">
- <MSHelp:Keyword Index="B">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='B']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- </xsl:template>
-
- <xsl:template name="mshelpTitles">
-
- <!-- Toc List title-->
- <MSHelp:TOCTitle>
- <includeAttribute name="Title" item="tocTitle">
- <parameter>
- <xsl:call-template name="topicTitlePlain" />
- </parameter>
- </includeAttribute>
- </MSHelp:TOCTitle>
-
- <!-- The Results List title -->
- <MSHelp:RLTitle>
- <includeAttribute name="Title" item="rlTitle">
- <parameter>
- <xsl:call-template name="topicTitlePlain">
- <xsl:with-param name="qualifyMembers" value="true()" />
- </xsl:call-template>
- </parameter>
- <parameter>
- <xsl:value-of select="$namespaceName"/>
- </parameter>
- </includeAttribute>
- </MSHelp:RLTitle>
-
- </xsl:template>
-
- <xsl:template name="apiTaggingMetadata">
- <xsl:if test="($group='type' or $group='member')">
- <MSHelp:Attr Name="APIType" Value="Managed" />
- <MSHelp:Attr Name="APILocation" Value="{/document/reference/containers/library/@assembly}.dll" />
- <xsl:choose>
- <xsl:when test="$group='type'">
- <xsl:variable name="apiTypeName">
- <xsl:value-of select="concat(/document/reference/containers/namespace/apidata/@name,'.',/document/reference/apidata/@name)" />
- <xsl:if test="count(/document/reference/templates/template) > 0">
- <xsl:value-of select="concat('`',count(/document/reference/templates/template))" />
- </xsl:if>
- </xsl:variable>
- <!-- Namespace + Type -->
- <MSHelp:Attr Name="APIName" Value="{$apiTypeName}" />
- <xsl:choose>
- <xsl:when test="boolean($subgroup='delegate')">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.ctor')}" />
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','Invoke')}" />
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','BeginInvoke')}" />
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','EndInvoke')}" />
- </xsl:when>
- <xsl:when test="$subgroup='enumeration'">
- <xsl:for-each select="/document/reference/elements/element">
- <MSHelp:Attr Name="APIName" Value="{substring(@api,3)}" />
- </xsl:for-each>
- <!-- Namespace + Type + Member for each member -->
- </xsl:when>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="$group='member'">
- <xsl:variable name="apiTypeName">
- <xsl:value-of select="concat(/document/reference/containers/namespace/apidata/@name,'.',/document/reference/containers/type/apidata/@name)" />
- <xsl:if test="count(/document/reference/templates/template) > 0">
- <xsl:value-of select="concat('`',count(/document/reference/templates/template))" />
- </xsl:if>
- </xsl:variable>
- <!-- Namespace + Type + Member -->
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.',/document/reference/apidata/@name)}" />
- <xsl:choose>
- <xsl:when test="boolean($subgroup='property')">
- <!-- Namespace + Type + get_Member if get-able -->
- <!-- Namespace + Type + set_Member if set-able -->
- </xsl:when>
- <xsl:when test="boolean($subgroup='event')">
- <!-- Namespace + Type + add_Member -->
- <!-- Namespace + Type + remove_Member -->
- </xsl:when>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="linkMetadata">
- <!-- code entity reference keyword -->
- <MSHelp:Keyword Index="A" Term="{$key}" />
-
- <xsl:if test="$subgroup='enumeration'">
- <xsl:for-each select="/document/reference/elements/element">
- <MSHelp:Keyword Index="A" Term="{@api}" />
- </xsl:for-each>
- </xsl:if>
-
- <!-- frlrf keywords -->
- <xsl:choose>
- <xsl:when test="$group='namespace'">
- <MSHelp:Keyword Index="A" Term="{translate(concat('frlrf',/document/reference/apidata/@name),'.','')}" />
- </xsl:when>
- <!-- types & members, too -->
- <xsl:when test="$group='type'">
- <MSHelp:Keyword Index="A" Term="{translate(concat('frlrf',/document/reference/containers/namespace/apidata/@name, /document/reference/apidata/@name, 'ClassTopic'),'.','')}" />
- </xsl:when>
- <xsl:when test="$group='list'">
- <MSHelp:Keyword Index="A" Term="{translate(concat('frlrf',/document/reference/containers/namespace/apidata/@name, /document/reference/topicdata/@name, 'MembersTopic'),'.','')}" />
- </xsl:when>
- <xsl:when test="$group='member'">
- <MSHelp:Keyword Index="A" Term="{translate(concat('frlrf',/document/reference/containers/namespace/apidata/@name, /document/reference/containers/type/apidata/@name, 'Class', /document/reference/apidata/@name, 'Topic'),'.','')}" />
- </xsl:when>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="$group='namespace'">
- <MSHelp:Keyword Index="A" Term="{concat('frlrf',translate(@name,'.',''))}" />
- </xsl:when>
- <!-- types & members, too -->
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="oldIndexMetadata">
- <!-- K keywords -->
- <xsl:choose>
- <xsl:when test="$group='namespace'">
- <!-- namespace -->
- <xsl:variable name="namespace" select="/document/reference/apidata/@name" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="namespaceIndexEntry">
- <parameter><xsl:value-of select="$namespace" /></parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:if>
- </xsl:when>
- <xsl:when test="$group='type'">
- <!-- type -->
- <xsl:choose>
- <xsl:when test="count(/document/reference/templates/template) = 0">
- <!-- non-generic type -->
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter><xsl:value-of select="/document/reference/apidata/@name" /></parameter>
- <parameter><xsl:value-of select="$subgroup" /></parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter><xsl:value-of select="concat(/document/reference/containers/namespace[@api]/apidata/@name,'.',/document/reference/apidata/@name)" /></parameter>
- <parameter><xsl:value-of select="$subgroup" /></parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:when>
- <xsl:otherwise>
- <!-- generic type -->
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name" />
- <xsl:for-each select="/document/reference/templates"><xsl:call-template name="csTemplatesInIndex" /></xsl:for-each>
- </parameter>
- <parameter>
- <xsl:value-of select="$subgroup" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name" />
- <xsl:for-each select="/document/reference/templates">
- <xsl:call-template name="vbTemplates">
- <xsl:with-param name="seperator" select="string('%2C ')" />
- </xsl:call-template>
- </xsl:for-each>
- </parameter>
- <parameter><xsl:value-of select="$subgroup" /></parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:otherwise>
- </xsl:choose>
- <!-- an entry like: "FileClassifier class, about FileClassifier class" -->
- <xsl:if test="$subgroup='class' or $subgroup='structure' or $subgroup='interface'">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="aboutTypeIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </parameter>
- <parameter>
- <xsl:value-of select="$subgroup"/>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:if>
- <!-- for enums, an entry for each enum member, e.g. "Sunken enumeration member" -->
- <xsl:if test="$subgroup='enumeration'">
- <xsl:for-each select="/document/reference/elements/element">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="apidata/@name" />
- </parameter>
- <parameter>
- <xsl:text>enumMember</xsl:text>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- </xsl:if>
- </xsl:when>
- <xsl:when test="($group='member') and (starts-with($key,'Overload:') or not(/document/reference/memberdata/@overload))">
- <!-- member -->
- <xsl:variable name="indexEntryItem">
- <xsl:choose>
- <xsl:when test="boolean($subsubgroup)">
- <xsl:value-of select="$subsubgroup" />
- </xsl:when>
- <xsl:when test="boolean($subgroup)">
- <xsl:value-of select="$subgroup" />
- </xsl:when>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="count(/document/reference/templates/template) = 0">
- <!-- non-generic member -->
- <MSHelp:Keyword Index="K">
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <includeAttribute name="Term" item="listTopicIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@name"/>
- </parameter>
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@subgroup"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:when>
- <xsl:otherwise>
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:otherwise>
- </xsl:choose>
- </MSHelp:Keyword>
- </xsl:when>
- <xsl:otherwise>
- <!-- generic member -->
- <MSHelp:Keyword Index="K">
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <includeAttribute name="Term" item="listTopicIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@name"/>
- <xsl:for-each select="/document/reference/templates">
- <xsl:call-template name="csTemplatesInIndex" />
- </xsl:for-each>
- </parameter>
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@subgroup"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:when>
- <xsl:otherwise>
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name"/>
- <xsl:for-each select="/document/reference/templates">
- <xsl:call-template name="csTemplatesInIndex" />
- </xsl:for-each>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:otherwise>
- </xsl:choose>
- </MSHelp:Keyword>
- <MSHelp:Keyword Index="K">
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <includeAttribute name="Term" item="listTopicIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@name"/>
- <xsl:for-each select="/document/reference/templates">
- <xsl:call-template name="vbTemplates">
- <xsl:with-param name="seperator" select="string('%2C ')" />
- </xsl:call-template>
- </xsl:for-each>
- </parameter>
- <parameter>
- <xsl:value-of select="/document/reference/containers/type/apidata/@subgroup"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:when>
- <xsl:otherwise>
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name"/>
- <xsl:for-each select="/document/reference/templates">
- <xsl:call-template name="vbTemplates">
- <xsl:with-param name="seperator" select="string('%2C ')" />
- </xsl:call-template>
- </xsl:for-each>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </xsl:otherwise>
- </xsl:choose>
- </MSHelp:Keyword>
- </xsl:otherwise>
- </xsl:choose>
- <!-- type + member -->
- <xsl:choose>
- <xsl:when test="count(/document/reference/containers/namespace[@api]/templates/template) = 0">
- <!-- non-generic type -->
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="concat(/document/reference/containers/type/apidata/@name,'.',/document/reference/containers/type/apidata/@name)" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat(/document/reference/containers/namespace[@api]/apidata/@name,'.',/document/reference/apidata/@name)" />
- </xsl:otherwise>
- </xsl:choose>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:when>
- <xsl:otherwise>
- <!-- generic type -->
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/containers/namespace[@api]/apidata/@name"/>
- <xsl:for-each select="/document/reference/containers/namespace[@api]/templates">
- <xsl:call-template name="vbTemplates">
- <xsl:with-param name="seperator" select="string('%2C ')" />
- </xsl:call-template>
- </xsl:for-each>
- <xsl:text>.</xsl:text>
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="/document/reference/type/apidata/@name" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="nameSubgroupIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/containers/namespace[@api]/apidata/@name"/>
- <xsl:for-each select="/document/reference/containers/namespace[@api]/templates">
- <xsl:call-template name="csTemplatesInIndex" />
- </xsl:for-each>
- <xsl:text>.</xsl:text>
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="/document/reference/type/apidata/@name" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </parameter>
- <parameter>
- <xsl:value-of select="$indexEntryItem" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="($group='members' or $group='derivedtype')">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="listTopicIndexEntry">
- <parameter>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </parameter>
- <parameter>
- <xsl:value-of select="/document/reference/containers/type[@api]/apidata/@subgroup"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$subgroup" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="helpMetadata">
- <!-- F keywords -->
- <xsl:choose>
- <!-- namespace pages get the namespace keyword, if it exists -->
- <xsl:when test="$group='namespace'">
- <xsl:variable name="namespace" select="/document/reference/apidata/@name" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="F" Term="{$namespace}" />
- </xsl:if>
- </xsl:when>
- <!-- type overview and member list pages get type and namespace.type keywords -->
- <xsl:when test="$group='type' or ($group='list' and $subgroup='members')">
- <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
- <xsl:variable name="type">
- <xsl:for-each select="/document/reference[1]">
- <xsl:call-template name="typeNamePlain">
- <xsl:with-param name="annotated" select="true()" />
- </xsl:call-template>
- </xsl:for-each>
- </xsl:variable>
- <MSHelp:Keyword Index="F" Term="{$type}" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="F" Term="{concat($namespace,'.',$type)}" />
- </xsl:if>
- <xsl:if test="$subgroup = 'enumeration'">
- <xsl:for-each select="/document/reference/elements/element">
- <MSHelp:Keyword Index="F" Term="{concat($type, '.', apidata/@name)}" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="F" Term="{concat($namespace,'.',$type, '.', apidata/@name)}" />
- </xsl:if>
- </xsl:for-each>
- </xsl:if>
- <xsl:call-template name="xamlMSHelpFKeywords"/>
- </xsl:when>
- <!-- member pages get member, type.member, and namepsace.type.member keywords -->
- <xsl:when test="$group='member'">
- <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
- <xsl:variable name="type">
- <xsl:for-each select="/document/reference/containers/type[1]">
- <xsl:call-template name="typeNamePlain">
- <xsl:with-param name="annotate" select="true()" />
- </xsl:call-template>
- </xsl:for-each>
- </xsl:variable>
- <xsl:variable name="member">
- <xsl:choose>
- <!-- if the member is a constructor, use the member name for the type name -->
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="$type" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <!--
- <xsl:choose>
- -->
- <!--
- <xsl:when test="$subgroup='constructor'">
- <MSHelp:Keyword Index="F" Term="{$type}" />
- <MSHelp:Keyword Index="F" Term="{concat($type, '.', $type)}" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="F" Term="{concat($namespace, '.', $type, '.', $type)}" />
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- -->
- <MSHelp:Keyword Index="F" Term="{$member}" />
- <MSHelp:Keyword Index="F" Term="{concat($type, '.', $member)}" />
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="F" Term="{concat($namespace, '.', $type, '.', $member)}" />
- </xsl:if>
- <!--
- </xsl:otherwise>
- </xsl:choose>
- -->
- </xsl:when>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template name="helpPriorityMetadata">
- <xsl:choose>
- <xsl:when test="$group='namespace' or $subgroup='members'">
- <MSHelp:Attr Name="HelpPriority" Value="1"/>
- </xsl:when>
- <xsl:when test="$group='type'">
- <MSHelp:Attr Name="HelpPriority" Value="2"/>
- </xsl:when>
- </xsl:choose>
- </xsl:template>
-
- <!--
- <xsl:template name="apiName">
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="/document/reference/containers/type/apidata/@name" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- -->
-
- <xsl:template name="codeLang">
- <xsl:param name="codeLang" />
- <MSHelp:Attr Name="codelang" Value="{$codeLang}" />
- </xsl:template>
-
- <xsl:template name="mshelpDevlangAttributes">
- <xsl:for-each select="/document/syntax/div[@codeLanguage]">
- <xsl:if test="not(@codeLanguage=preceding::*/@codeLanguage)">
- <xsl:variable name="devlang">
- <xsl:choose>
- <xsl:when test="@codeLanguage = 'CSharp' or @codeLanguage = 'c#' or @codeLanguage = 'cs' or @codeLanguage = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'ManagedCPlusPlus' or @codeLanguage = 'cpp' or @codeLanguage = 'cpp#' or @codeLanguage = 'c' or @codeLanguage = 'c++' or @codeLanguage = 'C++' or @codeLanguage = 'kbLangCPP'" >
- <xsl:text>C++</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'JScript' or @codeLanguage = 'js' or @codeLanguage = 'jscript#' or @codeLanguage = 'jscript' or @codeLanguage = 'JScript' or @codeLanguage = 'kbJScript'">
- <xsl:text>JScript</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'VisualBasic' or @codeLanguage = 'vb' or @codeLanguage = 'vb#' or @codeLanguage = 'VB' or @codeLanguage = 'kbLangVB'" >
- <xsl:text>VB</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'VBScript' or @codeLanguage = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'JSharp' or @codeLanguage = 'j#' or @codeLanguage = 'jsharp' or @codeLanguage = 'VJ#'">
- <xsl:text>VJ#</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'xaml' or @codeLanguage = 'XAML'">
- <xsl:text>XAML</xsl:text>
- </xsl:when>
- <xsl:when test="@codeLanguage = 'xml' or @codeLanguage = 'XML'">
- <xsl:text>XML</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$devlang='other'" />
- <xsl:otherwise>
- <MSHelp:Attr Name="DevLang" Value="{$devlang}" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:for-each>
- </xsl:template>
-
- <!--
- Additional F1 keywords for class, struct, and enum topics in a set of WPF namespaces.
- This template inserts the MSHelp:Keyword nodes.
- The keyword prefixes and the WPF namespaces are hard-coded in variables.
- -->
- <xsl:variable name="var_wpf_f1index_prefix_1">http://schemas.microsoft.com/winfx/2006/xaml/presentation#</xsl:variable>
- <xsl:variable name="var_wpf_f1index_prefix_1_namespaces">N:System.Windows.Controls#N:System.Windows.Documents#N:System.Windows.Shapes#N:System.Windows.Navigation#N:System.Windows.Data#N:System.Windows#N:System.Windows.Controls.Primitives#N:System.Windows.Media.Animation#N:System.Windows.Annotations#N:System.Windows.Annotations.Anchoring#N:System.Windows.Annotations.Storage#N:System.Windows.Media#N:System.Windows.Media.Animation#N:System.Windows.Media.Media3D#N:</xsl:variable>
-
- <xsl:template name="xamlMSHelpFKeywords">
- <xsl:if test="$subgroup='class' or $subgroup='enumeration' or $subgroup='structure'">
- <xsl:if test="boolean(contains($var_wpf_f1index_prefix_1_namespaces, concat('#',/document/reference/containers/namespace/@api,'#'))
- or starts-with($var_wpf_f1index_prefix_1_namespaces, concat(/document/reference/containers/namespace/@api,'#')))">
- <MSHelp:Keyword Index="F" Term="{concat($var_wpf_f1index_prefix_1, /document/reference/apidata/@name)}"/>
- </xsl:if>
- </xsl:if>
- </xsl:template>
-
- <!-- Index Logic -->
-
- <xsl:template name="indexMetadata">
- <xsl:choose>
- <!-- namespace topics get one unqualified index entry -->
- <xsl:when test="$group='namespace'">
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="namespaceIndexEntry">
- <parameter>
- <xsl:value-of select="msxsl:node-set($names)/name" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:when>
- <!-- type overview topics get unqualified about -->
- <xsl:when test="$group='type'">
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
- <xsl:for-each select="msxsl:node-set($names)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$subgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- <xsl:if test="boolean($namespace)">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$subgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="$namespace"/>
- <xsl:text>.</xsl:text>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:if>
- <xsl:if test="$subgroup = 'class' or $subgroup= 'structure' or $subgroup= 'interface'">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="aboutTypeIndexEntry">
- <parameter>
- <include item="{$subgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </include>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:if>
- </xsl:for-each>
- <xsl:if test="$subgroup = 'enumeration'">
- <xsl:for-each select="/document/reference/elements/element">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$subgroup}MemberIndexEntry">
- <parameter>
- <xsl:value-of select="apidata/@name" />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- </xsl:if>
- </xsl:when>
- <!-- all member lists get unqualified entries, qualified entries, and unqualified sub-entries -->
- <xsl:when test="$group='list' and $subgroup='members'">
- <xsl:variable name="typeSubgroup" select="/document/reference/apidata/@subgroup" />
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($names)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$typeSubgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="membersIndexEntry">
- <parameter>
- <include item="{$typeSubgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </include>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- <xsl:variable name="qnames">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="qualifiedTextNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($qnames)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$typeSubgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- <!-- enumeration topics also get entries for each member -->
- </xsl:when>
- <!-- other member list pages get unqualified sub-entries -->
- <xsl:when test="$group='list' and not($subgroup = 'overload')">
- <xsl:variable name="typeSubgroup" select="/document/reference/apidata/@subgroup" />
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($names)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$subgroup}IndexEntry">
- <parameter>
- <include item="{$typeSubgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </include>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- </xsl:when>
- <!-- constructor (or constructor overload) topics get unqualified sub-entries using the type names -->
- <xsl:when test="($subgroup='constructor' and not(/document/reference/memberdata/@overload)) or ($subgroup='overload' and /document/reference/apidata/@subgroup = 'constructor')">
- <xsl:variable name="typeSubgroup" select="/document/reference/containers/type/apidata/@subgroup" />
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference/containers/type">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($names)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="constructorIndexEntry">
- <parameter>
- <include item="{$typeSubgroup}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </include>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- <xsl:variable name="qnames">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="qualifiedTextNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($qnames)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="constructorTypeIndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- </xsl:when>
- <!-- other member (or overload) topics get qualified and unqualified entries using the member names -->
- <xsl:when test="($group='member' and not(/document/reference/memberdata/@overload)) or $subgroup='overload'">
- <!-- no index entries for explicit interface implementations -->
- <xsl:if test="not(/document/reference/proceduredata/@virtual='true' and /document/reference/memberdata/@visibility='private')">
- <xsl:variable name="entryType">
- <xsl:choose>
- <xsl:when test="string($subsubgroup)">
- <xsl:value-of select="$subsubgroup" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:value-of select="/document/reference/apidata/@subgroup"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="names">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="textNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($names)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$entryType}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- <xsl:variable name="qnames">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="qualifiedTextNames" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:for-each select="msxsl:node-set($qnames)/name">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="{$entryType}IndexEntry">
- <parameter>
- <xsl:value-of select="." />
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:for-each>
- </xsl:if>
- </xsl:when>
- <!-- derived type lists get unqualified sub-entries -->
- </xsl:choose>
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/utilities_reference.xsl b/tools/Sandcastle/Presentation/hana/transforms/utilities_reference.xsl
deleted file mode 100644
index d35d378..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/utilities_reference.xsl
+++ /dev/null
@@ -1,2442 +0,0 @@
-<?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:import href="../../shared/transforms/utilities_reference.xsl"/>
-
- <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" />
-<!--
- <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" doctype-public="-//W3C//DTD HTML 4.0 Transitional//EN" doctype-system="http://www.w3.org/TR/html4/loose.dtd" />
--->
- <!-- key parameter is the api identifier string -->
- <xsl:param name="key" />
- <xsl:param name="metadata" value="false" />
- <xsl:param name="languages">false</xsl:param>
- <xsl:param name="useOverloadRowsInMemberlists" select="false()"/>
-
- <xsl:include href="utilities_metadata.xsl" />
- <xsl:include href="xamlSyntax.xsl"/>
-
- <xsl:template match="/">
- <html>
- <head>
- <META NAME="save" CONTENT="history"/>
- <title><xsl:call-template name="topicTitlePlain"/></title>
- <xsl:call-template name="insertStylesheets" />
- <xsl:call-template name="insertScripts" />
- <xsl:call-template name="insertFilename" />
- <xsl:call-template name="insertMetadata" />
- </head>
- <body>
-
- <xsl:call-template name="upperBodyStuff"/>
- <!--<xsl:call-template name="control"/>-->
- <xsl:call-template name="main"/>
- <xsl:if test="$languages != 'false'">
- <script type="text/javascript">
- var data = new DataStore('docs');
- registerEventHandler(window, 'load', function() {languageFilter.select(data)});
- </script>
- </xsl:if>
- </body>
- </html>
- </xsl:template>
-
- <!-- useful global variables -->
-
- <xsl:variable name="group">
- <xsl:choose>
- <xsl:when test="/document/reference/topicdata/@group = 'api'">
- <xsl:value-of select="/document/reference/apidata/@group" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/topicdata/@group" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="subgroup">
- <xsl:choose>
- <xsl:when test="/document/reference/topicdata/@group = 'api'">
- <xsl:value-of select="/document/reference/apidata/@subgroup" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/topicdata/@subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="subsubgroup">
- <xsl:choose>
- <xsl:when test="/document/reference/topicdata/@group = 'api'">
- <xsl:value-of select="/document/reference/apidata/@subsubgroup" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/topicdata/@subsubgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="pseudo" select="boolean(/document/reference/topicdata[@pseudo='true'])"/>
-
- <xsl:variable name="namespaceName">
- <xsl:value-of select="substring-after(/document/reference/containers/namespace/@api,':')"/>
- </xsl:variable>
-
-
- <!-- document head -->
-
- <xsl:template name="insertStylesheets">
- <link rel="stylesheet" type="text/css" href="../styles/presentation.css" />
- <!-- make mshelp links work -->
- <link rel="stylesheet" type="text/css" href="ms-help://Hx/HxRuntime/HxLink.css" />
- <link rel="stylesheet" type="text/css" href="ms-help://Dx/DxRuntime/DxLink.css" />
- </xsl:template>
-
- <xsl:template name="insertScripts">
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>EventUtilities.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>SplitScreen.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>Dropdown.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>script_manifold.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>LanguageFilter.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>DataStore.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath"><parameter>CommonUtilities.js</parameter></includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- <script type="text/javascript">
- <includeAttribute name="src" item="scriptPath">
- <parameter>MemberFilter.js</parameter>
- </includeAttribute>
- <xsl:text> </xsl:text>
- </script>
- </xsl:template>
-
- <xsl:template match="parameters">
- <div id="parameters">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="parametersTitle"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="parameter">
- <xsl:variable name="paramName" select="@name"/>
- <dl paramName="{$paramName}">
- <dt>
- <span class="parameter">
- <xsl:value-of select="$paramName"/>
- </span>
- </dt>
- <dd>
- <xsl:apply-templates select="*[1]" mode="link" />
- <!--
- <xsl:choose>
- <xsl:when test="type">
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="type/@api" />
- <xsl:with-param name="qualified" select="true()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates select="*[1]" />
- </xsl:otherwise>
- </xsl:choose>
- -->
- <br />
- <xsl:call-template name="getParameterDescription">
- <xsl:with-param name="name" select="@name" />
- </xsl:call-template>
- </dd>
- </dl>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </div>
- </xsl:template>
-
- <xsl:template match="implements">
- <xsl:if test="member">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="implementsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="member">
- <referenceLink target="{@api}" qualified="true" />
- <br />
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="element" mode="root">
- <tr>
- <td>
- <xsl:choose>
- <xsl:when test="apidata/@name = ''">
- <referenceLink target="{@api}" qualified="false">
- <include item="defaultNamespace" />
- </referenceLink>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="createReferenceLink">
- <xsl:with-param name="id" select="@api" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
- <xsl:call-template name="getElementDescription" />
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template match="element" mode="namespace">
- <xsl:variable name="typeVisibility">
- <xsl:choose>
- <xsl:when test="typedata/@visibility='family' or typedata/@visibility='family or assembly' or typedata/@visibility='assembly'">prot</xsl:when>
- <xsl:when test="typedata/@visibility='private'">priv</xsl:when>
- <xsl:otherwise>pub</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <tr>
- <xsl:attribute name="data">
- <xsl:value-of select="apidata/@subgroup" />
- <xsl:text>; public</xsl:text>
- </xsl:attribute>
- <td>
- <xsl:call-template name="typeIcon">
- <xsl:with-param name="typeVisibility" select="$typeVisibility" />
- </xsl:call-template>
- </td>
- <td>
- <xsl:call-template name="createReferenceLink">
- <xsl:with-param name="id" select="@api" />
- </xsl:call-template>
- </td>
- <td>
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:if test="attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:text> </xsl:text>
- <include item="hostProtectionAttributeShort" />
- </xsl:if>
- <xsl:call-template name="getElementDescription" />
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template match="element" mode="member">
- <xsl:variable name="inheritedMember">
- <xsl:call-template name="IsMemberInherited"/>
- </xsl:variable>
- <xsl:variable name="staticMember">
- <xsl:call-template name="IsMemberStatic"/>
- </xsl:variable>
- <xsl:variable name="supportedOnXna">
- <xsl:call-template name="IsMemberSupportedOnXna"/>
- </xsl:variable>
- <xsl:variable name="supportedOnCf">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:variable>
- <xsl:variable name="protectedMember">
- <xsl:call-template name="IsMemberProtected"/>
- </xsl:variable>
- <tr>
- <xsl:attribute name="data">
- <xsl:choose>
- <xsl:when test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
- <xsl:text>explicit</xsl:text>
- </xsl:when>
- <xsl:when test="apidata/@subsubgroup">
- <xsl:value-of select="apidata/@subsubgroup"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="apidata/@subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='public'">
- <xsl:text>; public</xsl:text>
- </xsl:when>
- <xsl:when test="normalize-space($protectedMember)!=''">
- <xsl:text>; protected</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; public</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="normalize-space($staticMember)!=''">
- <xsl:text>; static</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; instance</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="normalize-space($inheritedMember)!=''">
- <xsl:text>; inherited</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; declared</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="normalize-space($supportedOnCf)!=''">
- <xsl:text>; compact</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; none</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="normalize-space($supportedOnXna)!=''">
- <xsl:text>; xna</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; none</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:attribute>
- <td>
- <xsl:call-template name="memberIcons">
- <xsl:with-param name="memberVisibility">
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='family' or memberdata/@visibility='family or assembly' or memberdata/@visibility='assembly'">prot</xsl:when>
- <xsl:when test="memberdata/@visibility='private'">priv</xsl:when>
- <xsl:when test="memberdata[@visibility='public']">pub</xsl:when>
- <xsl:otherwise>pub</xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- <xsl:with-param name="staticMember" select="normalize-space($staticMember)" />
- <xsl:with-param name="supportedOnXna" select="normalize-space($supportedOnXna)"/>
- <xsl:with-param name="supportedOnCf" select="normalize-space($supportedOnCf)"/>
- </xsl:call-template>
- </td>
- <td>
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" />
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:if test="attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:text> </xsl:text>
- <include item="hostProtectionAttributeShort" />
- </xsl:if>
- <xsl:if test="memberdata[@overload='true']">
- <include item="Overloaded"/>
- <xsl:text> </xsl:text>
- </xsl:if>
- <xsl:call-template name="getElementDescription" />
- <xsl:choose>
- <xsl:when test="@signatureset">
- <!-- TODO add boilerplate for other members in the sig set -->
- </xsl:when>
- <xsl:when test="not(topicdata[@subgroup='overload'])">
- <xsl:choose>
- <xsl:when test="normalize-space($inheritedMember)!=''">
- <xsl:text> </xsl:text>
- <include item="inheritedFrom">
- <parameter>
- <xsl:apply-templates select="containers/type" mode="link" />
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="containers/type/@api" />
- <xsl:with-param name="qualified" select="false()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- -->
- </parameter>
- </include>
- </xsl:when>
- <xsl:when test="overrides/member">
- <xsl:text> </xsl:text>
- <include item="overridesMember">
- <parameter>
- <xsl:call-template name="createReferenceLink">
- <xsl:with-param name="id" select="overrides/member/@api"/>
- <xsl:with-param name="qualified" select="true()"/>
- </xsl:call-template>
- </parameter>
- </include>
- </xsl:when>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template match="element" mode="enumeration">
- <tr>
- <xsl:variable name="id" select="@api" />
- <td target="{$id}">
- <span class="referenceNoLink"><xsl:value-of select="apidata/@name"/></span>
- </td>
- <td>
- <xsl:call-template name="getElementDescription" />
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template match="element" mode="derivedType">
- <tr>
- <td>
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" />
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
-
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:if test="attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:text> </xsl:text>
- <include item="hostProtectionAttributeShort" />
- </xsl:if>
- <xsl:call-template name="getElementDescription" />
- <xsl:choose>
- <xsl:when test="($group != 'member') and ($subgroup != 'DerivedTypeList') and not(contains($key, containers/type/@api))">
- <xsl:text> </xsl:text>
- <include item="inheritedFrom">
- <parameter>
- <xsl:apply-templates select="containers/type" mode="link" />
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="containers/type/@api" />
- <xsl:with-param name="qualified" select="false()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- -->
- </parameter>
- </include>
- </xsl:when>
- <xsl:when test="overrides">
- <xsl:text> </xsl:text>
- <include item="overridesMember">
- <parameter>
- <xsl:apply-templates select="overrides/member" />
- </parameter>
- </include>
- </xsl:when>
- </xsl:choose>
- </td>
- </tr>
-
-
- </xsl:template>
-
- <xsl:template match="element" mode="overload">
- <tr>
- <xsl:attribute name="data">
- <xsl:value-of select="apidata/@subgroup" />
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='public'">
- <xsl:text>; public</xsl:text>
- </xsl:when>
- <xsl:when test="memberdata/@visibility='family'">
- <xsl:text>; protected</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; public</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="memberdata/@static = 'true'">
- <xsl:text>; static</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; instance</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="string(containers/type/@api) = $key">
- <xsl:text>; declared</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; inherited</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:attribute>
- <td>
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" />
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:if test="attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:text> </xsl:text>
- <include item="hostProtectionAttributeShort" />
- </xsl:if>
- <xsl:call-template name="getElementDescription" />
- <xsl:choose>
- <xsl:when test="($group != 'member') and ($subgroup != 'overload') and not(contains($key, containers/type/@api))">
- <xsl:text> </xsl:text>
- <include item="inheritedFrom">
- <parameter>
- <xsl:apply-templates select="containers/type" mode="link" />
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="containers/type/@api" />
- <xsl:with-param name="qualified" select="false()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- -->
- </parameter>
- </include>
- </xsl:when>
- <xsl:when test="overrides">
- <xsl:text> </xsl:text>
- <include item="overridesMember">
- <parameter>
- <xsl:apply-templates select="overrides/member" />
- </parameter>
- </include>
- </xsl:when>
- </xsl:choose>
-
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template name="insertFilename">
- <meta name="guid">
- <xsl:attribute name="content">
- <xsl:value-of select="/document/reference/file/@name" />
- </xsl:attribute>
- </meta>
- </xsl:template>
-
- <!-- writing templates -->
-
- <xsl:template name="csTemplates">
- <xsl:param name="seperator" select="string(',')" />
- <xsl:text>&lt;</xsl:text>
- <xsl:for-each select="template">
- <xsl:value-of select="@name" />
- <xsl:if test="not(position()=last())">
- <xsl:value-of select="$seperator" />
- </xsl:if>
- </xsl:for-each>
- <xsl:text>&gt;</xsl:text>
- </xsl:template>
-
- <xsl:template name="csTemplatesInIndex" >
- <xsl:text>%3C</xsl:text>
- <xsl:for-each select="template">
- <xsl:value-of select="@name" />
- <xsl:if test="not(position()=last())">
- <xsl:text>%2C </xsl:text>
- </xsl:if>
- </xsl:for-each>
- <xsl:text>%3E</xsl:text>
- </xsl:template>
-
- <xsl:template name="vbTemplates">
- <xsl:param name="seperator" select="string(',')" />
- <xsl:text>(Of </xsl:text>
- <xsl:for-each select="template">
- <xsl:value-of select="@name" />
- <xsl:if test="not(position()=last())">
- <xsl:value-of select="$seperator" />
- </xsl:if>
- </xsl:for-each>
- <xsl:text>)</xsl:text>
- </xsl:template>
-
- <xsl:template name="typeTitle">
- <xsl:if test="containers/container[@type]">
- <xsl:for-each select="containers/container[@type]">
- <xsl:call-template name="typeTitle" />
- </xsl:for-each>
- <xsl:text>.</xsl:text>
- </xsl:if>
- <xsl:value-of select="apidata/@name" />
- <xsl:if test="count(templates/template) > 0">
- <xsl:for-each select="templates"><xsl:call-template name="csTemplates" /></xsl:for-each>
- </xsl:if>
- </xsl:template>
-
- <!-- document body -->
-
- <!-- control window -->
-
- <xsl:template name="control">
- <div id="control">
- <span class="topicTitle"><xsl:call-template name="topicTitleDecorated" /></span><br/>
- </div>
- </xsl:template>
-
- <!-- Title in topic -->
-
- <!-- Title in topic -->
-
- <xsl:template name="topicTitlePlain">
- <xsl:param name="qualifyMembers" select="false()" />
- <include>
- <xsl:attribute name="item">
- <xsl:if test="boolean(/document/reference/templates) and not($group='list')">
- <xsl:text>generic_</xsl:text>
- </xsl:if>
- <xsl:choose>
- <xsl:when test="string($subsubgroup)">
- <xsl:value-of select="$subsubgroup" />
- </xsl:when>
- <xsl:when test="string($subgroup)">
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:value-of select="/document/reference/apidata/@subgroup"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$group" />
- </xsl:otherwise>
- </xsl:choose>
- <xsl:text>TopicTitle</xsl:text>
- </xsl:attribute>
- <parameter>
- <xsl:call-template name="shortNamePlain">
- <xsl:with-param name="qualifyMembers" select="$qualifyMembers" />
- </xsl:call-template>
- </parameter>
- <parameter>
- <xsl:if test="document/reference/memberdata/@overload" >
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="parameterTypesPlain" />
- </xsl:for-each>
- </xsl:if>
- </parameter>
- </include>
- </xsl:template>
-
- <xsl:template name="topicTitleDecorated">
- <xsl:param name="titleType" />
- <include>
- <xsl:attribute name="item">
- <xsl:choose>
- <xsl:when test="$titleType = 'tocTitle' and $group='namespace'">
- <xsl:text>tocTitle</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="string($subsubgroup)">
- <xsl:value-of select="$subsubgroup" />
- </xsl:when>
- <xsl:when test="string($subgroup)">
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:value-of select="/document/reference/apidata/@subgroup" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$group" />
- </xsl:otherwise>
- </xsl:choose>
- <xsl:text>TopicTitle</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:attribute>
- <parameter>
- <xsl:call-template name="shortNameDecorated">
- <xsl:with-param name="titleType" select="$titleType" />
- </xsl:call-template>
- </parameter>
- <parameter>
- <xsl:if test="document/reference/memberdata/@overload" >
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="parameterTypesDecorated" />
- </xsl:for-each>
- </xsl:if>
- </parameter>
- </include>
- </xsl:template>
-
-
- <!-- Title in TOC -->
-
- <!-- Index entry -->
-
- <!-- main window -->
-
- <xsl:template name="main">
- <div id="mainSection">
-
- <div id="mainBody">
- <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()"/>
- <xsl:call-template name="head" />
- <xsl:call-template name="body" />
- <xsl:call-template name="foot" />
- </div>
- </div>
-
- </xsl:template>
-
- <xsl:template name="head">
- <include item="header" />
- </xsl:template>
-
- <xsl:template name="syntaxBlocks">
- <table class="filter" cellspacing="0" cellpadding="0">
- <tr id="curvedSyntaxTabs">
- <xsl:for-each select="div[@codeLanguage]">
- <td class="leftTab" x-lang="{@codeLanguage}">&#xa0;</td>
- <td class="middleTab" x-lang="{@codeLanguage}">&#xa0;</td>
- <td class="rightTab" x-lang="{@codeLanguage}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- <tr class="tabs" id="syntaxTabs">
- <xsl:for-each select="div[@codeLanguage]">
-
- <xsl:variable name="style">
- <xsl:call-template name="languageCheck">
- <xsl:with-param name="codeLanguage" select="@codeLanguage" />
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:variable name="languageEvent">
- <xsl:choose>
- <xsl:when test="$style != ''">
- <xsl:text>languageFilter.changeLanguage(data, '</xsl:text><xsl:value-of select="@codeLanguage"/>
- <xsl:text>', '</xsl:text><xsl:value-of select="$style" />
- <xsl:text>');</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>toggleClass('syntaxTabs','x-lang','</xsl:text><xsl:value-of select="@codeLanguage"/>
- <xsl:text>','activeTab','tab'); curvedToggleClass('curvedSyntaxTabs','x-lang','</xsl:text><xsl:value-of select="@codeLanguage"/>
- <xsl:text>');toggleStyle('syntaxBlocks','x-lang','</xsl:text><xsl:value-of select="@codeLanguage"/>
- <xsl:text>','display','block','none');</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <td class="leftGrad" x-lang="{@codeLanguage}">&#xa0;</td>
- <td class="tab" x-lang="{@codeLanguage}" onclick="{$languageEvent}"><include item="{@codeLanguage}Label" /></td>
- <td class="rightGrad" x-lang="{@codeLanguage}">&#xa0;</td>
- </xsl:for-each>
- </tr>
- </table>
- <div id="syntaxBlocks">
- <xsl:for-each select="div[@codeLanguage]">
- <xsl:variable name="language" select="@codeLanguage" />
- <div class="code" x-lang="{@codeLanguage}">
- <xsl:if test="/document/USyntax/div/@codeLanguage = $language">
- <div id="{$language}Declaration" onclick="toggleSelect({$language}DeclarationImage,{$language}DeclarationSection);">
- <img id="{$language}DeclarationImage" onmouseover="mouseOverCheck({$language}DeclarationImage,twirlSelectImage,twirlUnSelectImage,twirlSelectHoverImage,twirlUnSelectHoverImage)" onmouseout="mouseOutCheck({$language}DeclarationImage,twirlSelectImage,twirlUnSelectImage,twirlSelectHoverImage,twirlUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_selected.gif</parameter>
- </includeAttribute>
- <xsl:text>&#xa0;</xsl:text>
- <span class="syntaxLabel"><include item="declarationLabel" /></span>
- </img>
- </div>
- <br/>
- </xsl:if>
- <div id="{$language}DeclarationSection">
- <pre><xsl:copy-of select="./node()" /></pre>
- </div>
- <xsl:for-each select="/document/USyntax/div[@codeLanguage]">
- <xsl:if test="@codeLanguage = $language">
- <div id="{$language}Usage" onclick="toggleSelect({$language}UsageImage,{$language}UsageSection);">
- <img id="{$language}UsageImage" onmouseover="mouseOverCheck({$language}UsageImage,twirlSelectImage,twirlUnSelectImage,twirlSelectHoverImage,twirlUnSelectHoverImage)" onmouseout="mouseOutCheck({$language}UsageImage,twirlSelectImage,twirlUnSelectImage,twirlSelectHoverImage,twirlUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>twirl_selected.gif</parameter>
- </includeAttribute>
- <xsl:text>&#xa0;</xsl:text>
- <span class="syntaxLabel"><include item="usageLabel" /></span>
- </img>
- </div>
- <div id="{$language}UsageSection">
- <pre><xsl:copy-of select="./node()" /></pre>
- </div>
- </xsl:if>
- </xsl:for-each>
- </div>
- </xsl:for-each>
- </div>
- <script type="text/javascript">
- <xsl:text>
- toggleClass('syntaxTabs','x-lang','</xsl:text>
- <xsl:value-of select="div[1]/@codeLanguage" />
- <xsl:text>','activeTab','tab');
- toggleStyle('syntaxBlocks','x-lang','</xsl:text>
- <xsl:value-of select="div[1]/@codeLanguage" />
- <xsl:text>','display','block','none');
- curvedToggleClass('curvedSyntaxTabs', 'x-lang', '</xsl:text>
- <xsl:value-of select="div[1]/@codeLanguage" />
- <xsl:text>');
- </xsl:text>
- <xsl:if test="$languages != 'false'">
- languageFilter.registerTabbedArea('curvedSyntaxTabs', 'syntaxTabs', 'syntaxBlocks');
- </xsl:if>
- </script>
- </xsl:template>
-
- <xsl:template name="languageSyntaxBlock">
- <xsl:param name="language" select="@codeLanguage"/>
- <span codeLanguage="{$language}">
- <table>
- <tr>
- <th>
- <include item="{$language}" />
- </th>
- </tr>
- <tr>
- <td>
- <pre xml:space="preserve"><xsl:text/><xsl:copy-of select="node()"/><xsl:text/></pre>
- </td>
- </tr>
- </table>
- </span>
- </xsl:template>
-
- <xsl:template match="elements" mode="root">
- <xsl:if test="count(element) > 0">
-
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'namespaces'"/>
- <xsl:with-param name="title"><include item="namespacesTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <div class="listsection">
- <table class="members" id="memberList" frame="lhs" cellspacing="0">
- <tr>
- <th class="nameColumn">
- <include item="namespaceNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="namespaceDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select="element" mode="root">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="namespaceSection">
- <xsl:param name="listSubgroup" />
- <xsl:variable name="header" select="concat($listSubgroup, 'TypesFilterLabel')"/>
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="$listSubgroup"/>
- <xsl:with-param name="title">
- <include item="{$header}" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="namespaceList">
- <xsl:with-param name="listSubgroup" select="$listSubgroup" />
- </xsl:call-template>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template match="elements" mode="namespace">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'types'" />
- <xsl:with-param name="title">
- <include item="typesTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <table class="filter" cellspacing="0" cellpadding="0">
- <tr id="curvedTypeTabs">
- <td class="leftTab" value="all">&#xa0;</td>
- <td class="middleTab" value="all">&#xa0;</td>
- <td class="rightTab" value="all">&#xa0;</td>
- <xsl:if test="element/apidata[@subgroup='class']">
- <td class="leftTab" value="class">&#xa0;</td>
- <td class="middleTab" value="class">&#xa0;</td>
- <td class="rightTab" value="class">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='structure']">
- <td class="leftTab" value="structure">&#xa0;</td>
- <td class="middleTab" value="structure">&#xa0;</td>
- <td class="rightTab" value="structure">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='interface']">
- <td class="leftTab" value="interface">&#xa0;</td>
- <td class="middleTab" value="interface">&#xa0;</td>
- <td class="rightTab" value="interface">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='enumeration']">
- <td class="leftTab" value="enumeration">&#xa0;</td>
- <td class="middleTab" value="enumeration">&#xa0;</td>
- <td class="rightTab" value="enumeration">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='delegate']">
- <td class="leftTab" value="delegate">&#xa0;</td>
- <td class="middleTab" value="delegate">&#xa0;</td>
- <td class="rightTab" value="delegate">&#xa0;</td>
- </xsl:if>
- </tr>
- <tr class="tabs" id="typeFilter">
- <td class="leftGrad" value="all">&#xa0;</td>
- <td class="tab" value="all" onclick="toggleClass('typeFilter','value','all','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','all');tf.subgroup='all'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="allTypesFilterLabel" />
- </td>
- <td class="rightGrad" value="all">&#xa0;</td>
- <xsl:if test="element/apidata[@subgroup='class']">
- <td class="leftGrad" value="class">&#xa0;</td>
- <td class="tab" value="class" onclick="toggleClass('typeFilter','value','class','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','class'); tf.subgroup='class'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="classTypesFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubclass.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubClassAltText" />
- </img>
- </td>
- <td class="rightGrad" value="class">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='structure']">
- <td class="leftGrad" value="structure">&#xa0;</td>
- <td class="tab" value="structure" onclick="toggleClass('typeFilter','value','structure','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','structure'); tf.subgroup='structure'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="structureTypesFilterLabel" />
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubstructure.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubStructureAltText" />
- </img>
- </td>
- <td class="rightGrad" value="structure">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='interface']">
- <td class="leftGrad" value="interface">&#xa0;</td>
- <td class="tab" value="interface" onclick="toggleClass('typeFilter','value','interface','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','interface'); tf.subgroup='interface'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="interfaceTypesFilterLabel" />
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubinterface.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubInterfaceAltText" />
- </img>
- </td>
- <td class="rightGrad" value="interface">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='enumeration']">
- <td class="leftGrad" value="enumeration">&#xa0;</td>
- <td class="tab" value="enumeration" onclick="toggleClass('typeFilter','value','enumeration','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','enumeration'); tf.subgroup='enumeration'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="enumerationTypesFilterLabel" />
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubenum.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubEnumerationAltText" />
- </img>
- </td>
- <td class="rightGrad" value="enumeration">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='delegate']">
- <td class="leftGrad" value="delegate">&#xa0;</td>
- <td class="tab" value="delegate" onclick="toggleClass('typeFilter','value','delegate','activeTab','tab'); curvedToggleClass('curvedTypeTabs','value','delegate'); tf.subgroup='delegate'; process('typeList',getInstanceDelegate(tf,'filterElement'));">
- <include item="delegateTypesFilterLabel" />
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubdelegate.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubDelegateAltText" />
- </img>
- </td>
- <td class="rightGrad" value="delegate">&#xa0;</td>
- </xsl:if>
- </tr>
- </table>
- <div class="memberSection">
- <table id="typeList" class="members" cellspacing="0">
- <tr>
- <th class="iconColumn">
- <xsl:text>&#xa0;</xsl:text>
- </th>
- <th class="nameColumn">
- <include item="typeNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="typeDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select="element" mode="namespace">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- <script type="text/javascript">
- <xsl:text>
- var tf = new TypeFilter();
- toggleClass('typeFilter','value','all','activeTab','tab');
- curvedToggleClass('curvedTypeTabs','value','all');
- </xsl:text>
- </script>
- </xsl:with-param>
- </xsl:call-template>
-
- </xsl:template>
-
- <xsl:template name="namespaceList">
- <xsl:param name="listSubgroup" />
-
- <table id="typeList" class="members" frame="lhs">
- <tr>
- <th class="iconColumn">
- &#160;
- </th>
- <th class="nameColumn">
- <include item="{$listSubgroup}NameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="typeDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select="element[apidata/@subgroup=$listSubgroup]" mode="namespace">
- <xsl:sort select="@api" />
- </xsl:apply-templates>
- </table>
-
- </xsl:template>
-
- <xsl:template match="elements" mode="enumeration">
- <xsl:if test="count(element) > 0">
- <div id="enumerationSection">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'members'"/>
- <xsl:with-param name="title">
- <include item="enumMembersTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="members" id="memberList" frame="lhs" cellspacing="0">
- <tr>
- <th class="nameColumn">
- <include item="memberNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="memberDescriptionHeader" />
- </th>
- </tr>
- <!-- do not sort enumeration elements -->
- <xsl:apply-templates select="element" mode="enumeration"/>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </div>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="element" mode="members">
- <xsl:param name="subgroup"/>
- <xsl:if test="memberdata[@visibility='public'] and apidata[@subgroup=$subgroup]">
- public;
- </xsl:if>
- <xsl:if test="memberdata[@visibility='family' or @visibility='family or assembly' or @visibility='assembly'] and apidata[@subgroup=$subgroup]">
- protected;
- </xsl:if>
- <xsl:if test="memberdata[@visibility='private'] and apidata[@subgroup=$subgroup] and not(proceduredata[@virtual = 'true'])">
- private;
- </xsl:if>
- <xsl:if test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
- explicit;
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="elements" mode="member">
-
- <xsl:call-template name="memberIntro" />
-
- <xsl:if test="count(element) > 0">
- <xsl:variable name="header">
- <xsl:choose>
- <xsl:when test="element[apidata/@subsubgroup]">
- <xsl:value-of select="concat(element/apidata/@subsubgroup, 'MembersFilterLabel')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat(element/apidata/@subgroup, 'MembersFilterLabel')"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="$header" />
- <xsl:with-param name="title">
- <include item="{$header}" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="memberOptions">
- <tr>
- <td class="line">
- <div id="public" onclick="var checked=toggleCheck(publicImage); mf['public']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="publicImage" onmouseover="mouseOverCheck(publicImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(publicImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="publicMembersFilterLabel" />
- </div>
- <br />
- <div id="protected" onclick="var checked=toggleCheck(protectedImage); mf['protected']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="protectedImage" onmouseover="mouseOverCheck(protectedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(protectedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="protectedMembersFilterLabel" />
- </div>
- </td>
- <td class="line">
- <div id="instance" onclick="var checked=toggleCheck(instanceImage); mf['instance']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="instanceImage" onmouseover="mouseOverCheck(instanceImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(instanceImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="instanceMembersFilterLabel" />
- </div>
- <br />
- <div id="static" onclick="var checked=toggleCheck(staticImage); mf['static']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="staticImage" onmouseover="mouseOverCheck(staticImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(staticImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="staticMembersFilterLabel" />
- </div>
- </td>
- <td class="line">
- <div id="declared" onclick="var checked=toggleCheck(declaredImage); mf['declared']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="declaredImage" onmouseover="mouseOverCheck(declaredImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(declaredImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="declaredMembersFilterLabel" />
- </div>
- <br />
- <div id="inherited" onclick="var checked=toggleCheck(inheritedImage); mf['inherited']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="inheritedImage" onmouseover="mouseOverCheck(inheritedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(inheritedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="inheritedMembersFilterLabel" />
- </div>
- </td>
- <td class="line">
- <div id="xna" onclick="var checked=toggleCheck(xnaImage); mf['xna']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="xnaImage" onmouseover="mouseOverCheck(xnaImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(xnaImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="XNAFilterLabel" />
- </div>
- <br/>
- <div id="compact" onclick="var checked=toggleCheck(compactImage); mf['compact']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="compactImage" onmouseover="mouseOverCheck(compactImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(compactImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item=".NETCompactFilterLabel" />
- </div>
- </td>
- <td class="line">
- <br/>
- </td>
- </tr>
- </table>
- <table class="members" id="memberList" cellspacing="0" frame="lhs">
- <tr>
- <th class="iconColumn">
- <xsl:text>&#xa0;</xsl:text>
- </th>
- <th class="nameColumn">
- <include item="memberNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="memberDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select=".//element[not(child::element)]" mode="member">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- <script type="text/javascript">
- <xsl:text>
- var mf = new MemberFilter();
- </xsl:text>
- </script>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:template>
-
- <xsl:template name="memberlistSectionGroup">
- <xsl:param name="listSubgroup" />
-
- <xsl:if test="element[apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility='public']]">
- <xsl:call-template name="memberlistSection">
- <xsl:with-param name="listSubgroup" select="$listSubgroup" />
- <xsl:with-param name="listVisibility">public</xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:if test="element[apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility='protected']]">
- <xsl:call-template name="memberlistSection">
- <xsl:with-param name="listSubgroup" select="$listSubgroup" />
- <xsl:with-param name="listVisibility">protected</xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:template>
-
- <xsl:template name="memberlistSection">
- <xsl:param name="listSubgroup" />
- <xsl:param name="listSubsubgroup" />
- <xsl:param name="listVisibility" />
- <xsl:param name="explicit" />
-
- <xsl:variable name="header">
- <xsl:choose>
- <xsl:when test="$explicit='true'">ExplicitInterfaceImplementation</xsl:when>
- <xsl:when test="$listSubgroup='constructor'">constructorsTable</xsl:when>
- <xsl:when test="boolean($listSubsubgroup)">
- <xsl:value-of select="concat('Public', $listSubsubgroup)"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat($listVisibility, $listSubgroup)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="$header" />
- <xsl:with-param name="title">
- <include item="{$header}" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <table id="typeList" class="members" frame="lhs">
- <tr>
- <th class="iconColumn">
- &#160;
- </th>
- <th class="nameColumn">
- <include item="typeNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="typeDescriptionHeader" />
- </th>
- </tr>
-
- <xsl:choose>
- <xsl:when test="boolean($listSubgroup) and boolean($useOverloadRowsInMemberlists)">
- <xsl:apply-templates select="element[not(starts-with(@api,'Overload:'))][apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility=$listVisibility]]
- | element[starts-with(@api,'Overload:')][element[apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility=$listVisibility]]]"
- mode="memberlistRow">
- <xsl:sort select="apidata/@name" />
- <xsl:with-param name="listVisibility" select="$listVisibility"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:when test="boolean($listSubgroup)">
- <xsl:apply-templates select="element[not(starts-with(@api,'Overload:'))][apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility=$listVisibility]]
- | element[starts-with(@api,'Overload:')]/element[apidata[@subgroup=$listSubgroup and not(@subsubgroup)] and memberdata[@visibility=$listVisibility]]"
- mode="memberlistRow">
- <xsl:sort select="apidata/@name" />
- <xsl:with-param name="listVisibility" select="$listVisibility"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:when test="boolean($listSubsubgroup)">
- <xsl:apply-templates select="element[apidata[@subsubgroup=$listSubsubgroup]]" mode="memberlistRow">
- <xsl:sort select="apidata/@name" />
- <xsl:with-param name="listVisibility" select="$listVisibility"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:when test="$explicit='true'">
- <xsl:apply-templates select="element[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]" mode="memberlistRow">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </xsl:when>
- </xsl:choose>
- </table>
- </xsl:with-param>
- </xsl:call-template>
-
- </xsl:template>
-
- <xsl:template match="elements" mode="type">
- <xsl:if test="count(element) > 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'members'" />
- <xsl:with-param name="title">
- <include item="allMembersTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <table class="filter" cellspacing="0" cellpadding="0">
- <tr id="curvedMemberTabs">
- <td class="leftTab" value="all">&#xa0;</td>
- <td class="middleTab" value="all">&#xa0;</td>
- <td class="rightTab" value="all">&#xa0;</td>
- <xsl:if test="element/apidata[@subgroup='constructor']">
- <td class="leftTab" value="constructor">&#xa0;</td>
- <td class="middleTab" value="constructor">&#xa0;</td>
- <td class="rightTab" value="constructor">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='field']">
- <td class="leftTab" value="field">&#xa0;</td>
- <td class="middleTab" value="field">&#xa0;</td>
- <td class="rightTab" value="field">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='property']">
- <td class="leftTab" value="property">&#xa0;</td>
- <td class="middleTab" value="property">&#xa0;</td>
- <td class="rightTab" value="property">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='method']">
- <td class="leftTab" value="method">&#xa0;</td>
- <td class="middleTab" value="method">&#xa0;</td>
- <td class="rightTab" value="method">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='event']">
- <td class="leftTab" value="event">&#xa0;</td>
- <td class="middleTab" value="event">&#xa0;</td>
- <td class="rightTab" value="event">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subsubgroup='attachedProperty']">
- <td class="leftTab" value="attachedProperty">&#xa0;</td>
- <td class="middleTab" value="attachedProperty">&#xa0;</td>
- <td class="rightTab" value="attachedProperty">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subsubgroup='attachedEvent']">
- <td class="leftTab" value="attachedEvent">&#xa0;</td>
- <td class="middleTab" value="attachedEvent">&#xa0;</td>
- <td class="rightTab" value="attachedEvent">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]">
- <td class="leftTab" value="explicit">&#xa0;</td>
- <td class="middleTab" value="explicit">&#xa0;</td>
- <td class="rightTab" value="explicit">&#xa0;</td>
- </xsl:if>
- </tr>
- <tr class="tabs" id="memberTabs">
- <td class="leftGrad" value="all">&#xa0;</td>
- <td class="tab" value="all" onclick="toggleClass('memberTabs','value','all','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'all'); mf.subgroup='all'; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <include item="allMembersFilterLabel" />
- </td>
- <td class="rightGrad" value="all">&#xa0;</td>
- <xsl:if test="element/apidata[@subgroup='constructor']">
- <td class="leftGrad" value="constructor">&#xa0;</td>
- <td class="tab" value="constructor" onclick="toggleClass('memberTabs','value','constructor','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'constructor'); mf.subgroup='constructor'; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <include item="constructorMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubmethod.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubMethodAltText" />
- </img>
- </td>
- <td class="rightGrad" value="constructor">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='field']">
- <td class="leftGrad" value="field">&#xa0;</td>
- <td class="tab" value="field" onclick="toggleClass('memberTabs','value','field','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'field'); mf.subgroup='field'; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <include item="fieldMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubfield.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubFieldAltText" />
- </img>
- </td>
- <td class="rightGrad" value="field">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='property' and not(@subsubgroup)]">
- <td class="leftGrad" value="property">&#xa0;</td>
- <td class="tab" value="property" onclick="toggleClass('memberTabs','value','property','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'property'); mf.subgroup='property'; process('memberList', getInstanceDelegate(mf,'filterElement'));">
- <include item="propertyMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubproperty.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubPropertyAltText" />
- </img>
- </td>
- <td class="rightGrad" value="property">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='method']">
- <td class="leftGrad" value="method">&#xa0;</td>
- <td class="tab" value="method" onclick="toggleClass('memberTabs','value','method','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'method'); mf.subgroup='method'; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <include item="methodMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubmethod.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubMethodAltText" />
- </img>
- </td>
- <td class="rightGrad" value="method">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subgroup='event' and not(@subsubgroup)]">
- <td class="leftGrad" value="event">&#xa0;</td>
- <td class="tab" value="event" onclick="toggleClass('memberTabs','value','event','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'event'); mf.subgroup='event'; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <include item="eventMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubevent.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubEventAltText" />
- </img>
- </td>
- <td class="rightGrad" value="event">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subsubgroup='attachedProperty']">
- <td class="leftGrad" value="attachedProperty">&#xa0;</td>
- <td class="tab" value="attachedProperty" onclick="toggleClass('memberTabs','value','attachedProperty','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'attachedProperty'); mf.subgroup='attachedProperty'; process('memberList', getInstanceDelegate(mf,'filterElement'));">
- <include item="attachedPropertyMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubproperty.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubPropertyAltText" />
- </img>
- </td>
- <td class="rightGrad" value="attachedProperty">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element/apidata[@subsubgroup='attachedEvent']">
- <td class="leftGrad" value="attachedEvent">&#xa0;</td>
- <td class="tab" value="attachedEvent" onclick="toggleClass('memberTabs','value','attachedEvent','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'attachedEvent'); mf.subgroup='attachedEvent'; process('memberList', getInstanceDelegate(mf,'filterElement'));">
- <include item="attachedEventMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubevent.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="pubEventAltText" />
- </img>
- </td>
- <td class="rightGrad" value="attachedEvent">&#xa0;</td>
- </xsl:if>
- <xsl:if test="element[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]">
- <td class="leftGrad" value="explicit">&#xa0;</td>
- <td class="tab" value="explicit" onclick="toggleClass('memberTabs','value','explicit','activeTab','tab'); curvedToggleClass('curvedMemberTabs', 'value', 'explicit'); mf.subgroup='explicit'; process('memberList', getInstanceDelegate(mf,'filterElement'));">
- <include item="explicitInterfaceMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubinterface.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="ExplicitInterfaceAltText" />
- </img>
- </td>
- <td class="rightGrad" value="explicit">&#xa0;</td>
- </xsl:if>
- </tr>
- </table>
- <div class="memberSection">
- <table class="memberOptions">
- <tr>
- <td class="line">
- <div id="public" onclick="var checked=toggleCheck(publicImage); mf['public']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="publicImage" onmouseover="mouseOverCheck(publicImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(publicImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="publicMembersFilterLabel" />
- </div>
- <br />
- <div id="protected" onclick="var checked=toggleCheck(protectedImage); mf['protected']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="protectedImage" onmouseover="mouseOverCheck(protectedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(protectedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="protectedMembersFilterLabel" />
- </div>
- </td>
- <td class="line">
- <div id="instance" onclick="var checked=toggleCheck(instanceImage); mf['instance']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="instanceImage" onmouseover="mouseOverCheck(instanceImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(instanceImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="instanceMembersFilterLabel" />
- </div>
- <br />
- <div id="static" onclick="var checked=toggleCheck(staticImage); mf['static']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="staticImage" onmouseover="mouseOverCheck(staticImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(staticImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="staticMembersFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>static.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="staticAltText" />
- </img>
- </div>
- </td>
- <td class="line">
- <div id="declared" onclick="var checked=toggleCheck(declaredImage); mf['declared']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="declaredImage" onmouseover="mouseOverCheck(declaredImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(declaredImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="declaredMembersFilterLabel" />
- </div>
- <br />
- <div id="inherited" onclick="var checked=toggleCheck(inheritedImage); mf['inherited']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="inheritedImage" onmouseover="mouseOverCheck(inheritedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(inheritedImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="inheritedMembersFilterLabel" />
- </div>
- </td>
- <td class="line">
- <div id="xna" onclick="var checked=toggleCheck(xnaImage); mf['xna']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="xnaImage" onmouseover="mouseOverCheck(xnaImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(xnaImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item="XNAFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>xna.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="XNAFrameworkAltText" />
- </img>
- </div>
- <br/>
- <div id="compact" onclick="var checked=toggleCheck(compactImage); mf['compact']=checked; process('memberList',getInstanceDelegate(mf,'filterElement'));">
- <img id="compactImage" onmouseover="mouseOverCheck(compactImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)" onmouseout="mouseOutCheck(compactImage,checkBoxSelectImage,checkBoxUnSelectImage,checkBoxSelectHoverImage,checkBoxUnSelectHoverImage)">
- <includeAttribute name="src" item="iconPath">
- <parameter>ch_selected.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:text>&#xa0;</xsl:text>
- <include item=".NETCompactFilterLabel" />
- <xsl:text>&#xa0;</xsl:text>
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>CFW.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="compactFrameworkAltText" />
- </img>
- </div>
- </td>
- <td class="line">
- <br/>
- </td>
- </tr>
- </table>
- <table class="members" id="memberList" cellspacing="0" frame="lhs">
- <tr>
- <th class="iconColumn">
- <xsl:text>&#xa0;</xsl:text>
- </th>
- <th class="nameColumn">
- <include item="memberNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="memberDescriptionHeader" />
- </th>
- </tr>
- <!-- use select="element" to show overload-sets, select=".//element[not(parent::element)]" to show all overloads -->
- <xsl:apply-templates select=".//element[not(child::element)]" mode="member">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- <script type="text/javascript">
- <xsl:text>
- var mf = new MemberFilter();
- toggleClass('memberTabs','value','all','activeTab','tab');
- curvedToggleClass('curvedMemberTabs', 'value', 'all');
- </xsl:text>
- </script>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="IsMemberSupportedOnXna">
- <xsl:choose>
- <xsl:when test="element and not(@signatureset)">
- <xsl:for-each select="element">
- <xsl:call-template name="IsMemberSupportedOnXna"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:variable name="platformFilterExcludesXna" select="boolean(platforms and not(platforms/platform[.='Xbox360']))" />
- <xsl:if test="boolean(not($platformFilterExcludesXna) and @xnafw)">
- <xsl:text>supported</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="IsMemberSupportedOnCf">
- <xsl:choose>
- <xsl:when test="document/reference/topicdata[@subgroup='overload'] and document/reference/elements/element and not(@signatureset)">
- <xsl:for-each select="document/reference/elements/element">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:when test="element and not(@signatureset)">
- <xsl:for-each select="element">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:variable name="platformFilterExcludesCF" select="boolean( platforms and not(platforms[platform[.='PocketPC'] or platform[.='SmartPhone'] or platform[.='WindowsCE']]) )" />
- <xsl:if test="boolean(not($platformFilterExcludesCF) and @netcfw)">
- <xsl:text>yes</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="IsMemberStatic">
- <xsl:choose>
- <xsl:when test="element and not(@signatureset)">
- <xsl:for-each select="element">
- <xsl:call-template name="IsMemberStatic"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:when test="apidata[@subsubgroup='attachedProperty' or @subsubgroup='attachedEvent']"/>
- <xsl:otherwise>
- <xsl:if test="memberdata/@static='true'">
- <xsl:text>yes</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="IsMemberInherited">
- <xsl:choose>
- <xsl:when test="element and not(@signatureset)">
- <xsl:for-each select="element">
- <xsl:call-template name="IsMemberInherited"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:if test="not(contains($key, containers/type/@api))">
- <xsl:text>yes</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="IsMemberProtected">
- <xsl:choose>
- <xsl:when test="element and not(@signatureset)">
- <xsl:for-each select="element">
- <xsl:call-template name="IsMemberProtected"/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <xsl:if test="memberdata[@visibility='family' or @visibility='family or assembly' or @visibility='assembly']">
- <xsl:text>yes</xsl:text>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="element" mode="memberlistRow">
- <xsl:param name="listVisibility"/>
- <xsl:variable name="supportedOnXna">
- <xsl:call-template name="IsMemberSupportedOnXna"/>
- </xsl:variable>
- <xsl:variable name="supportedOnCf">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:variable>
- <xsl:variable name="staticMember">
- <xsl:call-template name="IsMemberStatic"/>
- </xsl:variable>
- <xsl:variable name="inheritedMember">
- <xsl:call-template name="IsMemberInherited"/>
- </xsl:variable>
- <xsl:variable name="protectedMember">
- <xsl:call-template name="IsMemberProtected"/>
- </xsl:variable>
- <tr>
- <xsl:if test="normalize-space($inheritedMember)!=''">
- <xsl:attribute name="name">inheritedMember</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($protectedMember)!=''">
- <xsl:attribute name="protected">true</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($supportedOnXna)=''">
- <xsl:attribute name="notSupportedOnXna">true</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($supportedOnCf)=''">
- <xsl:attribute name="notSupportedOn">netcf</xsl:attribute>
- </xsl:if>
-
- <td>
- <xsl:call-template name="memberIcons">
- <xsl:with-param name="memberVisibility">
- <xsl:choose>
- <xsl:when test="$listVisibility='public'">pub</xsl:when>
- <xsl:when test="$listVisibility='private'">priv</xsl:when>
- <xsl:when test="$listVisibility='protected'">prot</xsl:when>
- <xsl:otherwise>
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='family' or memberdata/@visibility='family or assembly' or memberdata/@visibility='assembly'">prot</xsl:when>
- <xsl:when test="memberdata/@visibility='private'">priv</xsl:when>
- <xsl:otherwise>pub</xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="memberdata[@visibility='public']">pub</xsl:when>
- </xsl:choose>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- <xsl:with-param name="staticMember" select="normalize-space($staticMember)" />
- <xsl:with-param name="supportedOnXna" select="normalize-space($supportedOnXna)"/>
- <xsl:with-param name="supportedOnCf" select="normalize-space($supportedOnCf)"/>
- </xsl:call-template>
- </td>
- <td>
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" show-parameters="false" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" show-parameters="false" />
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:if test="attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:text> </xsl:text>
- <include item="hostProtectionAttributeShort" />
- </xsl:if>
- <xsl:if test="topicdata[@subgroup='overload']">
- <include item="Overloaded"/>
- <xsl:text> </xsl:text>
- </xsl:if>
- <xsl:apply-templates select="element" mode="overloadSummary" />
- <xsl:call-template name="getElementDescription" />
- <xsl:choose>
- <xsl:when test="@signatureset">
- <!-- TODO add boilerplate for other members in the sig set -->
- </xsl:when>
- <xsl:when test="not(topicdata[@subgroup='overload'])">
- <xsl:choose>
- <xsl:when test="normalize-space($inheritedMember)!=''">
- <xsl:text> </xsl:text>
- <include item="inheritedFrom">
- <parameter>
- <xsl:apply-templates select="containers/type" mode="link" />
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="containers/type/@api" />
- <xsl:with-param name="qualified" select="false()" />
- <xsl:with-param name="specialization" select="boolean(type/specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- -->
- </parameter>
- </include>
- </xsl:when>
- <xsl:when test="overrides/member">
- <xsl:text> </xsl:text>
- <include item="overridesMember">
- <parameter>
- <xsl:call-template name="createReferenceLink">
- <xsl:with-param name="id" select="overrides/member/@api"/>
- <xsl:with-param name="qualified" select="true()"/>
- </xsl:call-template>
- </parameter>
- </include>
- </xsl:when>
- </xsl:choose>
- </xsl:when>
- </xsl:choose>
- </td>
- </tr>
- </xsl:template>
-
- <xsl:template match="elements" mode="derivedType">
- <xsl:if test="count(element) > 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'DerivedClasses'"/>
- <xsl:with-param name="title">
- <include item="derivedClasses" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="members" id="memberList" frame="lhs" cellspacing="0">
- <tr>
- <th class="nameColumn">
- <include item="memberNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="memberDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select="element" mode="derivedType">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template match="elements" mode="overload">
- <xsl:if test="count(element) > 0">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'overloadMembers'"/>
- <xsl:with-param name="title"><include item="membersTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <div class="listSection">
- <table class="members" id="memberList" frame="lhs" cellspacing="0">
- <tr>
- <th class="nameColumn">
- <include item="typeNameHeader"/>
- </th>
- <th class="descriptionColumn">
- <include item="typeDescriptionHeader" />
- </th>
- </tr>
- <xsl:apply-templates select="element" mode="overload">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </table>
- </div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <xsl:apply-templates select="element" mode="overloadSections">
- <xsl:sort select="apidata/@name" />
- </xsl:apply-templates>
- </xsl:template>
-
- <xsl:template match="elements" mode="overloadSummary">
- <xsl:apply-templates select="element" mode="overloadSummary" >
- <xsl:sort select="apidata/@name"/>
- </xsl:apply-templates>
- </xsl:template>
-
- <xsl:template match="element" mode="overloadSummary">
- <xsl:call-template name="getOverloadSummary" />
- </xsl:template>
-
- <xsl:template match="element" mode="overloadSections">
- <xsl:call-template name="getOverloadSections" />
- </xsl:template>
-
- <xsl:template name="typeIcon">
- <xsl:param name="typeVisibility" />
-
- <xsl:variable name="typeSubgroup" select="apidata/@subgroup" />
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>
- <xsl:value-of select="concat($typeVisibility,$typeSubgroup,'.gif')" />
- </parameter>
- </includeAttribute>
- <includeAttribute name="title" item="{concat($typeVisibility,$typeSubgroup,'AltText')}" />
- </img>
-
- </xsl:template>
-
- <xsl:template name="memberIcons">
- <xsl:param name="memberVisibility" />
- <xsl:param name="staticMember" />
- <xsl:param name="supportedOnXna"/>
- <xsl:param name="supportedOnCf"/>
-
- <xsl:variable name="memberSubgroup">
- <xsl:choose>
- <xsl:when test="apidata/@subgroup='constructor'">
- <xsl:text>method</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="apidata/@subgroup" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <!-- test for explicit interface implementations, which get the interface icon -->
- <xsl:if test="memberdata/@visibility='private' and proceduredata/@virtual='true'">
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>pubinterface.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="ExplicitInterfaceAltText" />
- </img>
- </xsl:if>
-
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>
- <xsl:value-of select="concat($memberVisibility,$memberSubgroup,'.gif')" />
- </parameter>
- </includeAttribute>
- <includeAttribute name="title" item="{concat($memberVisibility,$memberSubgroup,'AltText')}" />
- </img>
-
- <xsl:if test="$staticMember!=''">
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>static.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="staticAltText" />
- </img>
- </xsl:if>
-
- <xsl:if test="$supportedOnCf!=''">
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>CFW.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="CompactFrameworkAltText" />
- </img>
- </xsl:if>
-
- <xsl:if test="$supportedOnXna!=''">
- <img>
- <includeAttribute name="src" item="iconPath">
- <parameter>xna.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="XNAFrameworkAltText" />
- </img>
- </xsl:if>
- </xsl:template>
-
- <!-- Footer stuff -->
-
- <xsl:template name="foot">
- <div id="footer">
- <div class="footerLine">
- <img width="100%" height="3px">
- <includeAttribute name="src" item="iconPath">
- <parameter>footer.gif</parameter>
- </includeAttribute>
- <includeAttribute name="title" item="footerImage" />
- </img>
- </div>
-
- <include item="footer">
- <parameter>
- <xsl:value-of select="$key"/>
- </parameter>
- <parameter>
- <xsl:call-template name="topicTitlePlain"/>
- </parameter>
- </include>
- </div>
- </xsl:template>
-
- <!-- Assembly information -->
-
- <xsl:template name="requirementsInfo">
- <p/>
- <include item="requirementsNamespaceLayout" />
- <xsl:text>&#xa0;</xsl:text>
- <referenceLink target="{/document/reference/containers/namespace/@api}" />
- <br/>
- <xsl:call-template name="assembliesInfo"/>
-
- <!-- some apis display a XAML xmlns uri -->
- <xsl:call-template name="xamlXmlnsInfo"/>
- </xsl:template>
-
- <xsl:template name="assemblyNameAndModule">
- <xsl:param name="library" select="/document/reference/containers/library"/>
- <include item="assemblyNameAndModule">
- <parameter>
- <span data="assembly">
- <xsl:value-of select="$library/@assembly"/>
- </span>
- </parameter>
- <parameter>
- <xsl:value-of select="$library/@module"/>
- </parameter>
- <parameter>
- <xsl:choose>
- <xsl:when test="$library/@kind = 'DynamicallyLinkedLibrary'">
- <xsl:text>dll</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>exe</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </parameter>
- </include>
- </xsl:template>
-
- <xsl:template name="assembliesInfo">
- <xsl:choose>
- <xsl:when test="count(/document/reference/containers/library)&gt;1">
- <include item="requirementsAssembliesLabel"/>
- <xsl:for-each select="/document/reference/containers/library">
- <xsl:text>&#xa0;&#xa0;</xsl:text>
- <xsl:call-template name="assemblyNameAndModule">
- <xsl:with-param name="library" select="."/>
- </xsl:call-template>
- <br/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <include item="requirementsAssemblyLabel"/>
- <xsl:text>&#xa0;</xsl:text>
- <xsl:call-template name="assemblyNameAndModule"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- Platform information -->
-
- <xsl:template match="platforms">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'platformsTitle'"/>
- <xsl:with-param name="title">
- <include item="platformsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <p>
- <xsl:for-each select="platform">
- <include item="{.}" /><xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>
- </xsl:for-each>
- </p>
- <p>
- <include item="developmentPlatformsLayout"/>
- </p>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <!-- Version information -->
-
- <xsl:template match="versions">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'versionsTitle'"/>
- <xsl:with-param name="title">
- <include item="versionsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="processVersions" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template name="processVersions">
- <xsl:choose>
- <xsl:when test="versions">
- <xsl:for-each select="versions">
- <!-- $platformFilterExcluded is based on platform filtering information -->
- <xsl:variable name="platformFilterExcluded" select="boolean(/document/reference/platforms and ( (@name='netcfw' and not(/document/reference/platforms/platform[.='PocketPC']) and not(/document/reference/platforms/platform[.='SmartPhone']) and not(/document/reference/platforms/platform[.='WindowsCE']) ) or (@name='xnafw' and not(/document/reference/platforms/platform[.='Xbox360']) ) ) )" />
- <xsl:if test="not($platformFilterExcluded) and count(version) &gt; 0">
- <h4 class ="subHeading">
- <include item="{@name}" />
- </h4>
- <xsl:call-template name="processVersions" />
- </xsl:if>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <!-- show the versions in which the api is supported, if any -->
- <xsl:variable name="supportedCount" select="count(version[not(@obsolete)])"/>
- <xsl:if test="$supportedCount &gt; 0">
- <include item="supportedIn_{$supportedCount}">
- <xsl:for-each select="version[not(@obsolete)]">
- <parameter>
- <include item="{@name}" />
- </parameter>
- </xsl:for-each>
- </include>
- <br/>
- </xsl:if>
- <!-- show the versions in which the api is obsolete with a compiler warning, if any -->
- <xsl:for-each select="version[@obsolete='warning']">
- <include item="obsoleteWarning">
- <parameter>
- <include item="{@name}" />
- </parameter>
- </include>
- <br/>
- </xsl:for-each>
- <!-- show the versions in which the api is obsolete and does not compile, if any -->
- <xsl:for-each select="version[@obsolete='error']">
- <xsl:if test="position()=last()">
- <include item="obsoleteError">
- <parameter>
- <include item="{@name}" />
- </parameter>
- </include>
- <br/>
- </xsl:if>
- </xsl:for-each>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- Inheritance hierarchy -->
-
- <xsl:template match="family">
-
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'family'"/>
- <xsl:with-param name="title">
- <include item="familyTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:variable name="ancestorCount" select="count(ancestors/*)" />
- <xsl:variable name="childCount" select="count(descendents/*)" />
-
- <xsl:for-each select="ancestors/type">
- <xsl:sort select="position()" data-type="number" order="descending" />
-
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="position()" />
- </xsl:call-template>
-
- <xsl:apply-templates select="self::type" mode="link">
- <xsl:with-param name="qualified" select="true()" />
- </xsl:apply-templates>
-
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="@api" />
- <xsl:with-param name="qualified" select="true()" />
- <xsl:with-param name="specialization" select="boolean(specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="type/specialization" />
- -->
- <br/>
- </xsl:for-each>
-
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="$ancestorCount + 1" />
- </xsl:call-template>
-
- <referenceLink target="{$key}" qualified="true"/>
- <br/>
-
- <xsl:choose>
-
- <xsl:when test="descendents/@derivedTypes">
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="$ancestorCount + 2" />
- </xsl:call-template>
- <referenceLink target="{descendents/@derivedTypes}" qualified="true">
- <include item="derivedClasses"/>
- </referenceLink>
- </xsl:when>
- <xsl:otherwise>
-
- <xsl:for-each select="descendents/type">
- <xsl:call-template name="indent">
- <xsl:with-param name="count" select="$ancestorCount + 2" />
- </xsl:call-template>
-
- <xsl:apply-templates select="self::type" mode="link">
- <xsl:with-param name="qualified" select="true()" />
- </xsl:apply-templates>
- <!--
- <xsl:call-template name="typeReferenceLink">
- <xsl:with-param name="api" select="@api" />
- <xsl:with-param name="qualified" select="true()" />
- <xsl:with-param name="specialization" select="boolean(specialization)" />
- </xsl:call-template>
- <xsl:apply-templates select="specialization" />
- -->
- <br/>
- </xsl:for-each>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <xsl:template name="createTableEntries">
- <xsl:param name="count" />
- <xsl:if test="number($count) > 0">
- <td>&#x20;</td>
- <xsl:call-template name="createTableEntries">
- <xsl:with-param name="count" select="number($count)-1" />
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
- <xsl:template name="typeReferenceLink">
- <xsl:param name="api" />
- <xsl:param name="qualified" />
- <xsl:param name="specialization" />
-
- <referenceLink target="{$api}" qualified="{$qualified}">
- <xsl:choose>
- <xsl:when test="$specialization = 'true'">
- <xsl:attribute name="show-templates">false</xsl:attribute>
- </xsl:when>
- <xsl:otherwise>
- <xsl:attribute name="show-templates">true</xsl:attribute>
- </xsl:otherwise>
- </xsl:choose>
- </referenceLink>
-
- </xsl:template>
-
- <xsl:template match="template">
- <xsl:choose>
- <xsl:when test="@api=$key">
- <xsl:value-of select="@name" />
- </xsl:when>
- <xsl:otherwise>
- <include item="typeLinkToTypeParameter">
- <parameter>
- <xsl:value-of select="@name"/>
- </parameter>
- <parameter>
- <referenceLink target="{@api}" qualified="true" />
- </parameter>
- </include>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template match="member">
- <xsl:apply-templates select="type" mode="link" />
- <xsl:text>.</xsl:text>
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- Naming -->
-
- <xsl:template name="shortName">
- <xsl:choose>
- <xsl:when test="$subgroup='constructor'">
- <xsl:value-of select="/document/reference/containers/type/apidata/@name" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- decorated names -->
-
- <xsl:template name="shortNameDecorated">
- <!--<xsl:param name="titleType" /> -->
- <xsl:choose>
- <!-- type overview pages get the type name -->
- <xsl:when test="$group='type' or ($group='list' and not($subgroup='overload'))">
- <xsl:for-each select="/document/reference[1]">
- <xsl:call-template name="typeNameDecorated" />
- </xsl:for-each>
- </xsl:when>
- <!-- constructors and member list pages also use the type name -->
- <xsl:when test="$subgroup='constructor' or ($subgroup='overload' and /document/reference/apidata/@subgroup='constructor')">
- <xsl:for-each select="/document/reference/containers/type[1]">
- <xsl:call-template name="typeNameDecorated" />
- </xsl:for-each>
- </xsl:when>
- <!--
- <xsl:when test="$group='member'">
- <xsl:variable name="type">
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="GetTypeName" />
- </xsl:for-each>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$titleType = 'tocTitle'">
- <xsl:value-of select="$type" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="concat($typeName, '.', $type)"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- -->
- <!-- member pages use the qualified member name -->
- <xsl:when test="$group='member' or ($subgroup='overload' and /document/reference/apidata/@group='member')">
- <xsl:for-each select="/document/reference/containers/type[1]">
- <xsl:call-template name="typeNameDecorated" />
- </xsl:for-each>
- <span class="cs">.</span>
- <span class="vb">.</span>
- <span class="cpp">::</span>
- <xsl:for-each select="/document/reference[1]">
- <xsl:value-of select="apidata/@name" />
- <xsl:apply-templates select="templates" mode="decorated" />
- </xsl:for-each>
- </xsl:when>
- <!-- namespace (and any other) topics just use the name -->
- <xsl:when test="/document/reference/apidata/@name = ''">
- <include item="defaultNamespace" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- plain names -->
-
- <xsl:template name="shortNamePlain">
- <xsl:param name="qualifyMembers" select="false()" />
- <xsl:choose>
- <!-- type overview pages get the type name -->
- <xsl:when test="$group='type' or (group='list' and not($subgroup = 'overload'))">
- <xsl:for-each select="/document/reference[1]">
- <xsl:call-template name="typeNamePlain" />
- </xsl:for-each>
- </xsl:when>
- <!-- constructors and member list pages also use the type name -->
- <xsl:when test="$subgroup='constructor' or ($subgroup='overload' and /document/reference/apidata/@subgroup='constructor')">
- <xsl:for-each select="/document/reference/containers/type[1]">
- <xsl:call-template name="typeNamePlain" />
- </xsl:for-each>
- </xsl:when>
- <!-- namespace, member (and any other) topics just use the name -->
- <xsl:when test="/document/reference/apidata/@name = ''">
- <include item="defaultNamespace" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:if test="$qualifyMembers and /document/reference/apidata/@group='member'">
- <xsl:for-each select="/document/reference/containers/type[1]">
- <xsl:call-template name="typeNamePlain" />
- </xsl:for-each>
- <xsl:text>.</xsl:text>
- </xsl:if>
- <xsl:value-of select="/document/reference/apidata/@name" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <xsl:template name="typeNamePlain">
- <xsl:param name="annotate" select="false()" />
- <xsl:if test="(containers/type)|type">
- <xsl:for-each select="(containers/type)|type">
- <xsl:call-template name="typeNamePlain">
- <xsl:with-param name="annotate" select="$annotate" />
- </xsl:call-template>
- </xsl:for-each>
- <xsl:text>.</xsl:text>
- </xsl:if>
- <xsl:value-of select="apidata/@name" />
- <xsl:if test="$annotate and templates/template">
- <xsl:value-of select="concat('`',count(templates/template))"/>
- </xsl:if>
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/hana/transforms/xamlSyntax.xsl b/tools/Sandcastle/Presentation/hana/transforms/xamlSyntax.xsl
deleted file mode 100644
index 4362a26..0000000
--- a/tools/Sandcastle/Presentation/hana/transforms/xamlSyntax.xsl
+++ /dev/null
@@ -1,491 +0,0 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
- xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
- xmlns:mshelp="http://msdn.microsoft.com/mshelp"
- xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:msxsl="urn:schemas-microsoft-com:xslt"
- >
-
- <xsl:import href="globalTemplates.xsl"/>
-
- <xsl:variable name="showNonXamlAssemblyBoilerplate" select="'false'" />
-
- <!-- XAML Syntax -->
-
- <xsl:template name="XamlSyntaxBlock">
- <!-- Branch based on pagetype -->
- <xsl:choose>
- <!-- Display boilerplate for pagetypes that cannot be used in XAML,
- unless there's an authored XAML text section, which is used in place of the boilerplate. -->
- <xsl:when test="$subgroup='method' or
- $subgroup='constructor' or
- $subgroup='interface' or
- $subgroup='delegate' or
- $subgroup='field'">
- <xsl:call-template name="nonXamlMembersXamlSyntax"/>
- </xsl:when>
-
- <!-- class and struct -->
- <xsl:when test="$subgroup='class' or
- $subgroup='structure'">
- <xsl:call-template name="classOrStructXamlSyntax"/>
- </xsl:when>
-
- <!-- enumeration -->
- <xsl:when test="$subgroup='enumeration'">
- <xsl:call-template name="enumerationXamlSyntax"/>
- </xsl:when>
-
- <!-- property -->
- <xsl:when test="$subgroup='property' or $subsubgroup='attachedProperty'">
- <xsl:call-template name="propertyXamlSyntax"/>
- </xsl:when>
-
- <!-- event -->
- <xsl:when test="$subgroup='event' or $subsubgroup='attachedEvent'">
- <xsl:call-template name="eventXamlSyntax"/>
- </xsl:when>
-
- </xsl:choose>
- </xsl:template>
-
- <!-- XAML syntax for CLASS and STRUCT topics. This is the logic:
- if authored OESyntax,
- display it
- else if autogen OESyntax (AND no authored XAML section),
- display it.
- if authored AttrUsage,
- display it
- if authored XAML section,
- display it
- if no (authored OESyntax OR authored AttrUsage OR authored XAML section),
- display autogen boilerplate
- display XAML Values section, if any
- -->
- <xsl:template name="classOrStructXamlSyntax">
- <!-- Object Element Usage
- //ddue:section[starts-with(@address,'xamlValues')]
- //ddue:section[starts-with(@address,'xamlTextUsage')]
- //ddue:section[starts-with(@address,'xamlAttributeUsage')]
- //ddue:section[starts-with(@address,'xamlPropertyElementUsage')]
- //ddue:section[starts-with(@address,'xamlImplicitCollectionUsage')]
- //ddue:section[starts-with(@address,'xamlObjectElementUsage')]
- //ddue:section[starts-with(@address,'dependencyPropertyInfo')]
- //ddue:section[starts-with(@address,'routedEventInfo')]
- -->
- <xsl:choose>
- <!-- Show the authored Object Element Usage, if any. -->
- <xsl:when test="//ddue:section[starts-with(@address,'xamlObjectElementUsage')]">
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlObjectElementUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- </xsl:when>
- <!-- Else if no authored xamlTextUsage section, show the autogenerated Object Element Usage, if any. -->
- <xsl:when test="not(//ddue:section[starts-with(@address,'xamlTextUsage')])">
- <xsl:call-template name="ShowAutogeneratedXamlSyntax">
- <xsl:with-param name="autogenContent">
- <xsl:copy-of select="div[@class='xamlObjectElementUsageHeading']"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- </xsl:choose>
- <!-- Implicit Collection Usage - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlImplicitCollectionUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Attribute Usage - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlAttributeUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- XAML Text section - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlTextUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Autogen - show autogen boilerplate, if no authored xaml sections to override it. -->
- <xsl:if test="not(//ddue:section[starts-with(@address,'xamlObjectElementUsage')] or //ddue:section[starts-with(@address,'xamlImplicitCollectionUsage')] or //ddue:section[starts-with(@address,'xamlAttributeUsage')] or //ddue:section[starts-with(@address,'xamlTextUsage')])">
- <xsl:call-template name="ShowXamlSyntaxBoilerplate">
- <xsl:with-param name="param0">
- <xsl:copy-of select="."/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
- </xsl:template>
-
- <!-- XAML syntax for ENUMERATION topics. This is the logic:
- if authored AttrUsage,
- display it
- if authored XAML section,
- display it
- if no (authored AttrUsage OR authored XAML section),
- display autogen AttrUsage or boilerplate.
- display XAML Values section, if any
- -->
- <xsl:template name="enumerationXamlSyntax">
- <!-- Attribute Usage - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlAttributeUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- XAML Text section - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlTextUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Autogen - show enum syntax boilerplate, if no authored xaml sections to override it. -->
- <xsl:choose>
- <xsl:when test="$showNonXamlAssemblyBoilerplate='false' and div[@class='nonXamlAssemblyBoilerplate']"/>
- <xsl:when test="not(//ddue:section[starts-with(@address,'xamlAttributeUsage')] or //ddue:section[starts-with(@address,'xamlTextUsage')])">
- <span codeLanguage="XAML">
- <table>
- <tr>
- <th>
- <include item="xamlAttributeUsageHeading" />
- </th>
- </tr>
- <tr>
- <td>
- <pre xml:space="preserve"><xsl:text/><include item="enumerationOverviewXamlSyntax"/></pre>
- </td>
- </tr>
- </table>
- </span>
- </xsl:when>
- </xsl:choose>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
- </xsl:template>
-
- <!-- XAML syntax for PROPERTY topics. This is the logic:
- if authored OESyntax,
- display it
- if authored PEUsage,
- display it
- else if autogen PEUsage (AND no authored XAML section),
- display it
- if authored AttrUsage,
- display it
- else if autogen AttrUsage (AND no authored XAML section),
- display it
- if authored XAML section,
- display it
- if no (authored OESyntax OR authored PEUsage OR authored AttrUsage OR authored XAML section),
- display autogen boilerplate
- -->
- <xsl:template name="propertyXamlSyntax">
- <!-- Object Element Usage - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlObjectElementUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Property Element Usage -->
- <xsl:choose>
- <!-- Show the authored Property Element Usage, if any. -->
- <xsl:when test="//ddue:section[starts-with(@address,'xamlPropertyElementUsage')]">
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlPropertyElementUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- </xsl:when>
- <!-- Else if no authored xamlTextUsage section, show the autogenerated Property Element Usage, if any. -->
- <xsl:when test="not(//ddue:section[starts-with(@address,'xamlTextUsage')])">
- <xsl:call-template name="ShowAutogeneratedXamlSyntax">
- <xsl:with-param name="autogenContent">
- <xsl:copy-of select="div[@class='xamlPropertyElementUsageHeading' or @class='xamlContentElementUsageHeading']"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- </xsl:choose>
- <!-- Attribute Usage -->
- <xsl:choose>
- <!-- Show the authored Attribute Usage, if any. -->
- <xsl:when test="//ddue:section[starts-with(@address,'xamlAttributeUsage')]">
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlAttributeUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- </xsl:when>
- <!-- Else if no authored xamlTextUsage section, show the autogenerated Attribute Usage, if any. -->
- <xsl:when test="not(//ddue:section[starts-with(@address,'xamlTextUsage')])">
- <xsl:call-template name="ShowAutogeneratedXamlSyntax">
- <xsl:with-param name="autogenContent">
- <xsl:copy-of select="div[@class='xamlAttributeUsageHeading']"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- </xsl:choose>
- <!-- XAML Text section - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlTextUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Autogen - show autogen boilerplate, if no authored xaml sections to override it. -->
- <xsl:if test="not(//ddue:section[starts-with(@address,'xamlObjectElementUsage')] or //ddue:section[starts-with(@address,'xamlPropertyElementUsage')] or //ddue:section[starts-with(@address,'xamlAttributeUsage')] or //ddue:section[starts-with(@address,'xamlTextUsage')])">
- <xsl:call-template name="ShowXamlSyntaxBoilerplate">
- <xsl:with-param name="param0">
- <xsl:copy-of select="div/*"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
- </xsl:template>
-
- <!-- XAML syntax for EVENT topics. This is the logic:
- if authored AttrUsage,
- display it
- if authored XAML section,
- display it
- if no (authored AttrUsage OR authored XAML section),
- display autogen AttrUsage or boilerplate.
- display XAML Values section, if any
- -->
- <xsl:template name="eventXamlSyntax">
- <!-- Attribute Usage - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlAttributeUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- XAML Text section - show authored section, if any. -->
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlTextUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- <!-- Autogen - show autogen syntax or boilerplate, if no authored xaml sections to override it. -->
- <xsl:if test="not(//ddue:section[starts-with(@address,'xamlAttributeUsage')] or //ddue:section[starts-with(@address,'xamlTextUsage')])">
- <!-- If XamlSyntax component generated an Attribute Usage block, this template will show it. -->
- <xsl:call-template name="ShowAutogeneratedXamlSyntax">
- <xsl:with-param name="autogenContent">
- <xsl:copy-of select="div[@class='xamlAttributeUsageHeading']"/>
- </xsl:with-param>
- </xsl:call-template>
- <!-- If XamlSyntax component generated a boilerplate block, this template will show it. -->
- <xsl:call-template name="ShowXamlSyntaxBoilerplate">
- <xsl:with-param name="param0">
- <xsl:copy-of select="div/*"/>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
- </xsl:template>
-
- <!-- XAML syntax for members that cannot be used in XAML: interface, delegate, method, field, constructor.
- If there's an authored XAML section, show it. Otherwise, use the standard boilerplate. -->
- <xsl:template name="nonXamlMembersXamlSyntax">
- <xsl:choose>
- <!-- XAML Text section - show authored section, if any. -->
- <xsl:when test="//ddue:section[starts-with(@address,'xamlTextUsage')]">
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlTextUsage')][1]">
- <xsl:call-template name="ShowAuthoredXamlSyntax"/>
- </xsl:for-each>
- </xsl:when>
- <!-- Autogen - show autogen boilerplate, if no authored xaml sections to override it. -->
- <xsl:otherwise>
- <xsl:call-template name="ShowXamlSyntaxBoilerplate"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
-
- <!-- Displays one of the standard XAML boilerplate strings. -->
- <xsl:template name="ShowXamlSyntaxBoilerplate">
- <xsl:param name="param0"/>
- <xsl:variable name="boilerplateId">
- <xsl:choose>
- <!-- don't show boilerplate for apis that are not in xaml assemblies -->
- <xsl:when test="$showNonXamlAssemblyBoilerplate='false' and div[@class='nonXamlAssemblyBoilerplate']"/>
- <xsl:otherwise>
- <xsl:value-of select="div/@class[not(.='xamlAttributeUsageHeading' or
- .='xamlObjectElementUsageHeading' or
- .='xamlContentElementUsageHeading' or
- .='xamlPropertyElementUsageHeading' or
- .='xamlXmlnsUri')]"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:if test="$boilerplateId!=''">
- <span codeLanguage="XAML">
- <table>
- <tr>
- <th>
- <include item="xamlSyntaxBoilerplateHeading" />
- </th>
- </tr>
- <tr>
- <td>
- <pre xml:space="preserve"><span class="message"><xsl:text/><include item="{$boilerplateId}">
- <xsl:choose>
- <xsl:when test="$param0!=''">
- <parameter>
- <xsl:copy-of select="msxsl:node-set($param0)"/>
- </parameter>
- </xsl:when>
- <!-- make sure we at least pass in an empty param because some boilerplates expect them -->
- <xsl:otherwise>
- <parameter/>
- </xsl:otherwise>
- </xsl:choose>
- </include></span></pre>
- </td>
- </tr>
- </table>
- </span>
- </xsl:if>
- </xsl:template>
-
- <!-- Displays an authored XAML syntax section -->
- <xsl:template name="ShowAuthoredXamlSyntax">
- <xsl:if test="ddue:content[normalize-space(.)!='']">
- <xsl:variable name="headingID">
- <xsl:choose>
- <xsl:when test="starts-with(@address,'xamlObjectElementUsage')">xamlObjectElementUsageHeading</xsl:when>
- <xsl:when test="starts-with(@address,'xamlImplicitCollectionUsage')">xamlImplicitCollectionUsageHeading</xsl:when>
- <xsl:when test="starts-with(@address,'xamlPropertyElementUsage')">
- <xsl:choose>
- <xsl:when test="//div[@class='xamlContentElementUsageHeading']">xamlContentElementUsageHeading</xsl:when>
- <xsl:otherwise>xamlPropertyElementUsageHeading</xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:when test="starts-with(@address,'xamlAttributeUsage')">xamlAttributeUsageHeading</xsl:when>
- <xsl:when test="starts-with(@address,'xamlTextUsage')">xamlSyntaxBoilerplateHeading</xsl:when>
- </xsl:choose>
- </xsl:variable>
- <span codeLanguage="XAML">
- <table>
- <tr>
- <th>
- <include item="{$headingID}" />
- </th>
- </tr>
- <xsl:choose>
- <xsl:when test="$headingID='xamlSyntaxBoilerplateHeading'">
- <tr>
- <td>
- <xsl:apply-templates select="ddue:content"/>
- </td>
- </tr>
- </xsl:when>
- <xsl:otherwise>
- <tr>
- <td>
- <pre xml:space="preserve"><xsl:choose>
- <xsl:when test="ddue:content/ddue:code"><xsl:apply-templates select="ddue:content/ddue:code[1]/node()" /></xsl:when>
- <xsl:when test="ddue:content/ddue:para"><xsl:apply-templates select="ddue:content/ddue:para"/></xsl:when>
- </xsl:choose></pre>
- </td>
- </tr>
- </xsl:otherwise>
- </xsl:choose>
- </table>
- </span>
- </xsl:if>
- </xsl:template>
-
- <!-- Displays the autogenerated XAML syntax for pagetypes other than enumerations -->
- <xsl:template name="ShowAutogeneratedXamlSyntax">
- <xsl:param name="autogenContent"/>
- <xsl:if test="count(msxsl:node-set($autogenContent))>0">
- <xsl:for-each select="msxsl:node-set($autogenContent)/div">
- <xsl:variable name="headingID">
- <xsl:value-of select="@class"/>
- </xsl:variable>
- <span codeLanguage="XAML">
- <table>
- <tr>
- <th>
- <include item="{$headingID}" />
- </th>
- </tr>
- <tr>
- <td>
- <pre xml:space="preserve"><xsl:text/><xsl:copy-of select="node()"/></pre>
- </td>
- </tr>
- </table>
- </span>
- </xsl:for-each>
- </xsl:if>
- </xsl:template>
-
- <!-- Display the XAML Values section. -->
- <xsl:template name="showXamlValuesSection">
- <xsl:for-each select="//ddue:section[starts-with(@address,'xamlValues')]">
- <span codeLanguage="XAML">
- <p/>
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="xamlValuesSectionHeading" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates select="ddue:content"/>
- </xsl:with-param>
- </xsl:call-template>
- </span>
- </xsl:for-each>
- </xsl:template>
-
- <!-- these xaml sections are captured in the xaml syntax processing, so this template prevents them from showing up twice -->
- <xsl:template match="//ddue:section[starts-with(@address,'xamlValues') or
- starts-with(@address,'xamlTextUsage') or
- starts-with(@address,'xamlAttributeUsage') or
- starts-with(@address,'xamlPropertyElementUsage') or
- starts-with(@address,'xamlImplicitCollectionUsage') or
- starts-with(@address,'xamlObjectElementUsage') or
- starts-with(@address,'dependencyPropertyInfo') or
- starts-with(@address,'routedEventInfo')]"/>
-
- <!-- the authored dependency Property Information section -->
- <xsl:template match="ddue:section[starts-with(@address,'dependencyPropertyInfo')]" mode="section">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'dependencyPropertyInfo'"/>
- <xsl:with-param name="title">
- <include item="dependencyPropertyInfoHeading" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates select="ddue:content" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <!-- the authored routed event Information section -->
- <xsl:template match="ddue:section[starts-with(@address,'routedEventInfo')]" mode="section">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'routedEventInfo'"/>
- <xsl:with-param name="title">
- <include item="routedEventInfoHeading" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates select="ddue:content" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:template>
-
- <!-- Show XAML xmlns for apis that support XAML -->
- <xsl:template name="xamlXmlnsInfo">
- <xsl:variable name="hasAuthoredXamlSyntax" select="boolean(//ddue:sections/ddue:section[
- starts-with(@address,'xamlTextUsage') or
- starts-with(@address,'xamlAttributeUsage') or
- starts-with(@address,'xamlPropertyElementUsage') or
- starts-with(@address,'xamlImplicitCollectionUsage') or
- starts-with(@address,'xamlObjectElementUsage')])" />
- <xsl:variable name="hasAutogeneratedXamlSyntax" select="boolean(/document/syntax/div[@codeLanguage='XAML']/div[
- @class='xamlAttributeUsageHeading' or
- @class='xamlObjectElementUsageHeading' or
- @class='xamlContentElementUsageHeading' or
- @class='xamlPropertyElementUsageHeading'])" />
- <!-- All topics that have authored or autogen'd xaml syntax get an "XMLNS for XAML" line in the Requirements section.
- Topics with boilerplate xaml syntax, e.g. "Not applicable", do NOT get this line. -->
- <xsl:if test="$hasAuthoredXamlSyntax or $hasAutogeneratedXamlSyntax">
- <br/>
- <include item="xamlXmlnsRequirementsLayout">
- <parameter>
- <xsl:choose>
- <xsl:when test="/document/syntax/div[@codeLanguage='XAML']/div[@class='xamlXmlnsUri']">
- <xsl:for-each select="/document/syntax/div[@codeLanguage='XAML']/div[@class='xamlXmlnsUri']">
- <xsl:if test="position()!=1"><xsl:text>, </xsl:text></xsl:if>
- <xsl:value-of select="."/>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <include item="unmappedXamlXmlns"/>
- </xsl:otherwise>
- </xsl:choose>
- </parameter>
- </include>
- </xsl:if>
- </xsl:template>
-
-</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/Content/conceptual_content.xml b/tools/Sandcastle/Presentation/vs2005/Content/conceptual_content.xml
index 9063b63..50aef54 100644
--- a/tools/Sandcastle/Presentation/vs2005/Content/conceptual_content.xml
+++ b/tools/Sandcastle/Presentation/vs2005/Content/conceptual_content.xml
@@ -53,5 +53,9 @@
<p>This section contains the following subsections.</p>
</item>
<item id="RelatedTopicsLinkText">Related Topics</item>
+ <!-- resolve the autoOutline token -->
+ <item id="autoOutline">
+ <autoOutline/>
+ </item>
</content>
diff --git a/tools/Sandcastle/Presentation/vs2005/Content/feedBack_content.xml b/tools/Sandcastle/Presentation/vs2005/Content/feedBack_content.xml
index 6d3a068..2412a85 100644
--- a/tools/Sandcastle/Presentation/vs2005/Content/feedBack_content.xml
+++ b/tools/Sandcastle/Presentation/vs2005/Content/feedBack_content.xml
@@ -4,6 +4,7 @@
<item id="fb_product"></item>
<item id="fb_deliverable"></item>
+ <item id="fb_subject">Customer%20Feedback</item>
<item id="fb_body"></item>
<item id="fb_headerFeedBack">Send Feedback</item>
@@ -17,6 +18,7 @@
<item id="feedback_fileVersion"></item>
<item id="feedback_topicVersion"></item>
<item id="feedback_body"></item>
+ <item id="feedback_subject"></item>
<item id="fb_Introduction">We value your feedback. To rate this topic and send feedback about this topic to the documentation team, click a rating, and then click <b>Send Feedback</b>. For assistance with support issues, refer to the technical support information included with the product.</item>
@@ -27,4 +29,4 @@
<item id="fb_Title">Documentation Feedback</item>
<item id="fb_altIcon">Display feedback instructions at the bottom of the page.</item>
-</content>
+</content> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/vs2005/Content/reference_content.xml b/tools/Sandcastle/Presentation/vs2005/Content/reference_content.xml
index 970abb0..dfd9de0 100644
--- a/tools/Sandcastle/Presentation/vs2005/Content/reference_content.xml
+++ b/tools/Sandcastle/Presentation/vs2005/Content/reference_content.xml
@@ -21,8 +21,15 @@
<item id="constructorTopicTitle">{0} Constructor {1}</item>
<item id="propertyTopicTitle">{0} Property {1}</item>
<item id="eventTopicTitle">{0} Event</item>
- <item id="operatorTopicTitle">{0} Operator</item>
+ <!-- title for operator members -->
+ <item id="operatorTopicTitle">{0} Operator {1}</item>
+
+ <!-- title for op_explicit and op_implicit members -->
+ <item id="typeConversionTopicTitle">{0} Conversion {1}</item>
+ <!-- title for overload op_explicit and op_implicit topics -->
+ <item id="conversionOperatorTopicTitle">{0} Conversion Operators</item>
+
<item id="attachedPropertyTopicTitle">{0} Attached Property</item>
<item id="attachedEventTopicTitle">{0} Attached Event</item>
@@ -35,9 +42,17 @@
<!-- list topic titles -->
<item id="FieldsTopicTitle">{0} Fields</item>
- <item id="MethodsTopicTitle">{0} Methods {1}</item>
- <item id="ConstructorsTopicTitle">{0} Constructors {1}</item>
- <item id="PropertiesTopicTitle">{0} Properties {1}</item>
+ <item id="MethodsTopicTitle">{0} Methods</item>
+
+ <!-- title for operator list topic that has [operators + no type conversions] -->
+ <item id="OperatorsTopicTitle">{0} Operators</item>
+ <!-- title for operator list topic that has [operators + type conversions] -->
+ <item id="OperatorsAndTypeConversionsTopicTitle">{0} Operators and Type Conversions</item>
+ <!-- title for operator list topic that has [no operators + type conversions] -->
+ <item id="TypeConversionsTopicTitle">{0} Type Conversions</item>
+
+ <item id="ConstructorsTopicTitle">{0} Constructors</item>
+ <item id="PropertiesTopicTitle">{0} Properties</item>
<item id="EventsTopicTitle">{0} Events</item>
<item id="AttachedPropertiesTopicTitle">{0} Attached Properties</item>
<item id="AttachedEventsTopicTitle">{0} Attached Events</item>
@@ -59,6 +74,14 @@
<item id="derivedTypesIndexEntry">{0}, derived types</item>
<item id="membersIndexEntry">{0}, all members</item>
<item id="methodsIndexEntry">{0}, methods</item>
+ <!-- index entry for operator list topic that has [operators + no type conversions] -->
+ <item id="operatorsIndexEntry">{0}, operators</item>
+ <!-- index entry for operator list topic that has [operators + type conversions] -->
+ <item id="operatorsAndTypeConversionsIndexEntry">{0}, operators and type conversions</item>
+ <!-- index entry for operator list topic that has [no operators + type conversions] -->
+ <item id="typeConversionsIndexEntry">{0}, type conversions</item>
+ <!-- index entries for op_explicit and op_implicit members -->
+ <item id="conversionOperatorIndexEntry">{0} conversion</item>
<item id="propertiesIndexEntry">{0}, properties</item>
<item id="fieldsIndexEntry">{0}, fields</item>
<item id="eventsIndexEntry">{0}, events</item>
@@ -111,7 +134,7 @@
<item id="implementsTitle">Implements</item>
<item id="examplesTitle">Examples</item>
<item id="threadSafetyTitle">Thread Safety</item>
- <item id="permissionsTitle">Permissions</item>
+ <item id="permissionsTitle">.NET Framework Security</item>
<item id="namespacesTitle">Namespaces</item>
<item id="typesTitle">Types</item>
<item id="allMembersTitle">Members</item>
@@ -142,6 +165,10 @@
<item id="exceptionConditionHeader">Condition</item>
<item id="permissionNameHeader">Permission</item>
<item id="permissionDescriptionHeader">Description</item>
+ <item id="requiresNameHeader">Requires</item>
+ <item id="ensuresNameHeader">Ensures</item>
+ <item id="ensuresOnThrowNameHeader">EnsuresOnThrow</item>
+ <item id="invariantsNameHeader">Invariants</item>
<!-- filter control text -->
<item id="allTypesFilterLabel">All Types</item>
@@ -180,9 +207,9 @@
<item id="ThreadSafety">Thread Safety</item>
<item id="ThreadSafetyBP">Any public <include item="staticKeyword"/> members of this type are thread safe. Any instance members are not guaranteed to be thread safe.</item>
- <item id="NotesForImplementers">Notes to Implementers: </item>
- <item id="NotesForCallers">Notes to Callers: </item>
- <item id="NotesForInheritors">Notes to Inheritors: </item>
+ <item id="NotesForImplementers">Notes to Implementers</item>
+ <item id="NotesForCallers">Notes to Callers</item>
+ <item id="NotesForInheritors">Notes to Inheritors</item>
<!-- Used for Platform Notes -->
<item id="PlatformNote">
@@ -245,7 +272,7 @@
<item id="nonobsoleteAlternative">The non-obsolete alternative is {0}.</item>
<item id="obsoleteRed"><font color="red"><b>Obsolete. </b></font></item>
<item id="ObsoleteBoilerPlate">
- <font color="red"><b>NOTE: This API is now obsolete.</b></font>
+ <font color="red"><b>Note: This API is now obsolete.</b></font>
</item>
<item id="definedBy">(Defined by {0}.)</item>
<item id="inheritedFrom">(Inherited from {0}.)</item>
@@ -429,9 +456,23 @@
<item id="internalOnly">This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.</item>
<item id="infraStructure">Infrastructure. </item>
+
+ <!-- Variance boilerplate text -->
+ <item id="inKeyword"><span class="languageSpecificText"><span class="cs"><span class="keyword">in</span> </span><span class="vb"><span class="keyword">In</span> </span><span class="cpp"><span class="keyword">in</span> </span><span class="nu"><span class="keyword">in</span> </span><span class="fs"></span></span></item>
+ <item id="outKeyword"><span class="languageSpecificText"><span class="cs"><span class="keyword">out</span> </span><span class="vb"><span class="keyword">Out</span> </span><span class="cpp"><span class="keyword">out</span> </span><span class="nu"><span class="keyword">out</span> </span><span class="fs"></span></span></item>
+
+ <item id="covariant">This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived. </item>
+ <item id="contravariant">This type parameter is contavariant. That is, you can use either the type you specified or any type that is less derived. </item>
+ <item id="variance">For more information about covariance and contravariance, see <conceptualLink target="2678dc63-c7f9-4590-9ddc-0a4df684d42e" />.</item>
+
<!-- Non Cls Compliant boilerplate text-->
<item id="NotClsCompliant">This API is not CLS-compliant.</item>
<item id="AltClsCompliant">The CLS-compliant alternative is {0}.</item>
+
+ <!-- Security Critical Boilerplate text-->
+ <item id="typeSecurityCriticalBoilerplate">This type has a SecurityCriticalAttribute attribute, which restricts it to internal use by the .NET Framework for Silverlight class library. Application code that uses any member of this type throws a MethodAccessException.</item>
+ <item id="memberSecurityCriticalBoilerplate">This member has a SecurityCriticalAttribute attribute, which restricts it to internal use by the .NET Framework for Silverlight class library. Application code that uses this member throws a MethodAccessException.</item>
+ <item id="securityCritical">[SECURITY CRITICAL] </item>
<!-- platform names that appear in the Platforms section on mref type and member pages
The id values must be in sync with the platform/@name values used in the manifold platformFilters.xml filter files.
@@ -446,10 +487,19 @@
<item id="PocketPC">Windows Mobile for Pocket PC</item>
<item id="SmartPhone">Windows Mobile for Smartphone</item>
<item id="WinSvr2003">Windows Server 2003</item>
+ <item id="WinSvr2008">Windows Server 2008</item>
+ <item id="WinSvr2008R2">Windows Server 2008 R2</item>
<item id="WinXpMediaCenter">Windows XP Media Center Edition</item>
<item id="WinXPSE">Windows XP Starter Edition</item>
<item id="WinVista">Windows Vista</item>
+ <item id="Win7">Windows 7</item>
<item id="Xbox360">Xbox 360</item>
+ <item id="Zune">Zune</item>
+
+ <!-- Platforms boilerplate for Silverlight mref builds -->
+ <item id="silverlightplatforms">
+ For information on the operating systems and browsers supported by <include item="silverlight"/>, see "Supported Operating Systems and Browsers" in <conceptualLink target="d1c41046-1eef-4a73-8049-5c9f0487f7fc"/>.
+ </item>
<!-- framework ids:
These shared content item strings are used for the headings in the Version Information section
@@ -458,12 +508,15 @@
<item id="netfw">.NET Framework</item>
<item id="netcfw">.NET Compact Framework</item>
<item id="xnafw">XNA Framework</item>
+ <item id="silverlight">Silverlight</item>
<!-- framework version ids
These shared content item strings are used in the Version Information section.
These ids must be in sync with the ids used in the config file for VersionBuilder.
The ids are also used in the platformFilters.xml filter files to indicate the framework version supported by each platform
-->
+ <item id="netfw40">4.0</item>
+ <item id="netfw35_1">3.5 SP1</item>
<item id="netfw35">3.5</item>
<item id="netfw30_1">3.0 SP1</item>
<item id="netfw30">3.0</item>
@@ -472,18 +525,23 @@
<item id="netfw11">1.1</item>
<item id="netfw10">1.0</item>
+ <item id="netcfw37">3.7</item>
<item id="netcfw35">3.5</item>
<item id="netcfw20">2.0</item>
<item id="netcfw10">1.0</item>
<item id="xnafw10">1.0</item>
+ <!-- silverlight version ids used in Version Information section. -->
+ <item id="silverlight20">2.0</item>
+ <item id="silverlight10">1.0</item>
+
<!-- Used in the Requirements section to display an xmlns URI for apis that can be used in XAML -->
<item id="xamlXmlnsRequirementsLayout"><b>XMLNS for XAML:</b> {0}</item>
<item id="unmappedXamlXmlns">Not mapped to an xmlns.</item>
<item id="secondaryFrameworkOverride"><br/><br/>In <include item="{0}"/>, this member is overridden by {1}.</item>
- <item id="secondaryFrameworkInherited"><br/><br/>In <include item="{0}"/>&#160;<include item="{1}"/>, this member is inherited from {2}<span class="languageSpecificText"><span class="cs">.</span><span class="vb">.</span><span class="cpp">::</span><span class="nu">.</span></span>{3}.</item>
+ <item id="secondaryFrameworkInherited"><br/><br/>In <include item="{0}"/>&#160;<include item="{1}"/>, this member is inherited from {2}<span class="languageSpecificText"><span class="cs">.</span><span class="vb">.</span><span class="cpp">::</span><span class="nu">.</span><span class="fs">.</span></span>{3}.</item>
<item id="secondaryFrameworkMember"><br/><br/>In <include item="{0}"/>&#160;<include item="{1}"/>, this member is {2}.</item>
<item id="useBaseSummary">This member overrides {0}.</item>
diff --git a/tools/Sandcastle/Presentation/vs2005/Content/shared_content.xml b/tools/Sandcastle/Presentation/vs2005/Content/shared_content.xml
index f4a3d99..75d17fd 100644
--- a/tools/Sandcastle/Presentation/vs2005/Content/shared_content.xml
+++ b/tools/Sandcastle/Presentation/vs2005/Content/shared_content.xml
@@ -19,19 +19,29 @@
<!-- header -->
<item id="header"><font color="DarkGray"></font><p/> </item>
+ <!-- freshness date -->
+ <item id="UpdateTitle"><font color="DarkGray">Updated: {0}</font></item>
+ <!-- if the TransformComponent of the BuildAssembler config file has the argument:
+ argument key="changeHistoryOptions" value="showDefaultFreshnessDate"
+ the "defaultFreshnessDate" item is used as the default freshness date for topics that don't have a Change History table. -->
+ <item id="defaultFreshnessDate"/>
+
+ <!-- change history table section-->
+ <item id="changeHistory">Change History</item>
+
<!-- topic title -->
<item id="nsrTitle">{0}</item>
<!-- alert titles -->
- <item id="tipTitle"><b>Tip:</b></item>
- <item id="cautionTitle"><b>Caution:</b></item>
- <item id="securityTitle"><b>Security Note:</b></item>
- <item id="noteTitle"><b>Note:</b></item>
- <item id="importantTitle"><b>Important Note:</b></item>
- <item id="visualBasicTitle"><b>Visual Basic Note:</b></item>
- <item id="visualC#Title"><b>C# Note:</b></item>
- <item id="visualC++Title"><b>C++ Note:</b></item>
- <item id="visualJ#Title"><b>J# Note:</b></item>
+ <item id="tipTitle"><b>Tip</b></item>
+ <item id="cautionTitle"><b>Caution</b></item>
+ <item id="securityTitle"><b>Security Note</b></item>
+ <item id="noteTitle"><b>Note</b></item>
+ <item id="importantTitle"><b>Important</b></item>
+ <item id="visualBasicTitle"><b>Visual Basic Note</b></item>
+ <item id="visualC#Title"><b>C# Note</b></item>
+ <item id="visualC++Title"><b>C++ Note</b></item>
+ <item id="visualJ#Title"><b>J# Note</b></item>
<!-- alert alt text -->
<item id="tipAltText">Tip</item>
@@ -50,9 +60,14 @@
<item id="ManagedCPlusPlusLabel">Visual C++</item>
<item id="JSharpLabel">J#</item>
<item id="JScriptLabel">JScript</item>
+ <item id="JavaScriptLabel">JavaScript</item>
+ <item id="XAMLLabel">XAML</item>
<!-- section titles -->
<item id="exceptionsTitle">Exceptions</item>
+ <item id="contractsTitle">Contracts</item>
+ <item id="setterTitle">Set</item>
+ <item id="getterTitle">Get</item>
<item id="SeeAlso">See&#160;Also</item>
<item id="SeeAlsoTasks">Tasks</item>
<item id="SeeAlsoReference">Reference</item>
@@ -100,6 +115,7 @@
<item id="JScript">JScript</item>
<item id="xmlLang">Xml</item>
<item id="JavaScript">JavaScript</item>
+ <item id="FSharp">F#</item>
<item id="html">Html</item>
<item id="visualbasicANDcsharp"><include item="VisualBasic"/> and <include item="CSharp"/></item>
<item id="other"></item>
@@ -196,7 +212,7 @@
</a>
</span>
</item>
-<item id="MailToLink">javascript:SubmitFeedback('<include item="fb_alias" />','<include item="fb_product" />','<include item="fb_deliverable" />','{0}','{1}','<include item="fb_body" />');</item>
+<item id="MailToLink">javascript:SubmitFeedback('<include item="fb_alias" />','<include item="fb_product" />','<include item="fb_deliverable" />','{0}','{1}','<include item="fb_body" />','<include item="fb_subject" />');</item>
<!-- 5 star rating feedback control in sandcastle scenario-->
<!--
@@ -235,7 +251,7 @@
</span>
</item>
-<item id="MailToLink">javascript:SubmitFeedback('<include item="feedback_alias" />','<include item="feedback_product" />','<include item="feedback_deliverable" />','<include item="feedback_fileVersion" />','<include item="feedback_topicVersion" />','<include item="feedback_body" />');</item>
+<item id="MailToLink">javascript:SubmitFeedback('<include item="feedback_alias" />','<include item="feedback_product" />','<include item="feedback_deliverable" />','<include item="feedback_fileVersion" />','<include item="feedback_topicVersion" />','<include item="feedback_body" />','<include item="feedback_subject" />');</item>
-->
<item id="copyrightStatement"><include item="copyrightText"/></item>
diff --git a/tools/Sandcastle/Presentation/vs2005/Scripts/CommonUtilities.js b/tools/Sandcastle/Presentation/vs2005/Scripts/CommonUtilities.js
index e2d5767..42a9360 100644
--- a/tools/Sandcastle/Presentation/vs2005/Scripts/CommonUtilities.js
+++ b/tools/Sandcastle/Presentation/vs2005/Scripts/CommonUtilities.js
@@ -103,6 +103,8 @@ function GetDevlangCheckboxId(devlang)
return devlangsMenu.GetCheckboxId("JSharp");
case "JavaScript":
return devlangsMenu.GetCheckboxId("JavaScript");
+ case "FSharp":
+ return devlangsMenu.GetCheckboxId("FSharp");
default:
return "";
}
@@ -116,26 +118,36 @@ function styleSheetHandler(oneDevlang)
var sd = getStyleDictionary();
if (devlang == 'cs') {
- sd['span.cs'].display = 'inline';
- sd['span.vb'].display = 'none';
- sd['span.cpp'].display = 'none';
- sd['span.nu'].display = 'none';
+ sd['span.cs'].display = 'inline';
+ sd['span.vb'].display = 'none';
+ sd['span.cpp'].display = 'none';
+ sd['span.nu'].display = 'none';
+ sd['span.fs'].display = 'none';
} else if (devlang == 'vb') {
- sd['span.cs'].display = 'none';
- sd['span.vb'].display = 'inline';
- sd['span.cpp'].display = 'none';
- sd['span.nu'].display = 'none';
- } else if (devlang == 'cpp') {
- sd['span.cs'].display = 'none';
- sd['span.vb'].display = 'none';
- sd['span.cpp'].display = 'inline';
- sd['span.nu'].display = 'none';
- } else if (devlang == 'nu') {
- sd['span.cs'].display = 'none';
- sd['span.vb'].display = 'none';
- sd['span.cpp'].display = 'none';
- sd['span.nu'].display = 'inline';
- }
+ sd['span.cs'].display = 'none';
+ sd['span.vb'].display = 'inline';
+ sd['span.cpp'].display = 'none';
+ sd['span.nu'].display = 'none';
+ sd['span.fs'].display = 'none';
+ } else if (devlang == 'cpp') {
+ sd['span.cs'].display = 'none';
+ sd['span.vb'].display = 'none';
+ sd['span.cpp'].display = 'inline';
+ sd['span.nu'].display = 'none';
+ sd['span.fs'].display = 'none';
+ } else if (devlang == 'nu') {
+ sd['span.cs'].display = 'none';
+ sd['span.vb'].display = 'none';
+ sd['span.cpp'].display = 'none';
+ sd['span.nu'].display = 'inline';
+ sd['span.fs'].display = 'none';
+ } else if (devlang == 'fs') {
+ sd['span.cs'].display = 'none';
+ sd['span.vb'].display = 'none';
+ sd['span.cpp'].display = 'none';
+ sd['span.nu'].display = 'none';
+ sd['span.fs'].display = 'inline';
+ }
}
function getStyleDictionary() {
diff --git a/tools/Sandcastle/Presentation/vs2005/Scripts/script_feedBack.js b/tools/Sandcastle/Presentation/vs2005/Scripts/script_feedBack.js
index 4f79de1..55ee44a 100644
--- a/tools/Sandcastle/Presentation/vs2005/Scripts/script_feedBack.js
+++ b/tools/Sandcastle/Presentation/vs2005/Scripts/script_feedBack.js
@@ -82,9 +82,9 @@ function GetRating()
return sRating;
}
-function SubmitFeedback(alias, product, deliverable, productVersion, documentationVersion, defaultBody)
+function SubmitFeedback(alias, product, deliverable, productVersion, documentationVersion, defaultBody, defaultSubject)
{
- var subject = title
+ var subject = defaultSubject
+ " ("
+ "/1:"
+ product
diff --git a/tools/Sandcastle/Presentation/vs2005/Scripts/script_manifold.js b/tools/Sandcastle/Presentation/vs2005/Scripts/script_manifold.js
index 26bb631..ebc63a7 100644
--- a/tools/Sandcastle/Presentation/vs2005/Scripts/script_manifold.js
+++ b/tools/Sandcastle/Presentation/vs2005/Scripts/script_manifold.js
@@ -99,6 +99,13 @@ function HideSelect()
i = n;
}
break;
+ case "fsharp":
+ for (m=0; m<spanEles.length; m++)
+ {
+ if (spanEles[m].getAttribute("codeLanguage") == "FSharp" && spanEles[m].style.display != "none" && n < i)
+ i = n;
+ }
+ break;
}
}
if (i != 10)
diff --git a/tools/Sandcastle/Presentation/vs2005/Styles/Presentation.css b/tools/Sandcastle/Presentation/vs2005/Styles/Presentation.css
index 8c7e864..5fe081f 100644
--- a/tools/Sandcastle/Presentation/vs2005/Styles/Presentation.css
+++ b/tools/Sandcastle/Presentation/vs2005/Styles/Presentation.css
@@ -148,7 +148,7 @@ span.selflink {
}
span.nolink {
-
+ font-weight: bold;
}
/***********************************************************
@@ -233,7 +233,7 @@ div#header table tr#headerTableRow3 td
/* Applies to the lower table in the non-scrolling header region. Text in this table
includes Collapse All/Expand All, Language Filter, and Members Options. */
-div#header table#topTable
+div#header table#bottomTable
{
border-top-color: #FFFFFF;
border-top-style: solid;
@@ -891,6 +891,11 @@ span.nu {
display: inline;
}
+span.fs
+{
+ display: none;
+}
+
span.code {
font-family: Monospace, Courier New, Courier;
font-size: 105%;
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/conceptual.config b/tools/Sandcastle/Presentation/vs2005/configuration/conceptual.config
index 5458268..7025e18 100644
--- a/tools/Sandcastle/Presentation/vs2005/configuration/conceptual.config
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/conceptual.config
@@ -50,45 +50,106 @@
<copy name="projectSettings" key="string('PBM_FileVersion')" source="." target="/document/metadata" />
</component>
- <!-- Resolve code snippets -->
- <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <examples file="%DXROOT%\Data\CodeSnippet.xml" />
- <colors language="VisualBasic">
- <color pattern="^\s*'[^\r\n]*" class="comment" />
- <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
- <color pattern="\b((AddHandler)|(AddressOf)|(As)|(Boolean)|(ByRef)|(ByVal)|(Case)|(Catch)|(Char)|(Class)|(Const)|(Continue)|(Delegate)|(Dim)|(Double)|(Each)|(Else)|(ElseIf)|(End)|(Enum)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(From)|(Function)|(Get)|(Handles)|(If)|(Implements)|(Imports)|(In)|(Inherits)|(Integer)|(Interface)|(Is)|(Let)|(Loop)|(Me)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(Namespace)|(New)|(Next)|(Nothing)|(NotInheritable)|(NotOverrideable)|(Of)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(RemoveHandler)|(Return)|(Select)|(Set)|(Shadows)|(Shared)|(Static)|(Step)|(String)|(Structure)|(Sub)|(Then)|(Throw)|(To)|(True)|(Try)|(Until)|(Using)|(When)|(Where)|(While)|(With)|(WriteOnly))\b" class="keyword" />
- </colors>
- <colors language="CSharp">
- <color pattern="/\*(.|\n)+?\*/" class="comment" />
- <color pattern="//[^\r\n]*" class="comment" />
- <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
- <color pattern="\b((abstract)|(as)|(ascending)|(base)|(bool)|(break)|(by)|(case)|(catch)|(char)|(class)|(const)|(continue)|(default)|(delegate)|(descending)|(do)|(double)|(else)|(enum)|(equals)|(event)|(extern)|(false)|(finally)|(float)|(for)|(foreach)|(from)|(get)|(group)|(if)|(in)|(int)|(interface)|(internal)|(into)|(is)|(join)|(let)|(namespace)|(new)|(null)|(on)|(orderby)|(out)|(override)|(params)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sealed)|(select)|(set)|(static)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(using)|(virtual)|(volatile)|(void)|(where)|(while))\b" class="keyword" />
- </colors>
- <colors language="ManagedCPlusPlus">
- <color pattern="/\*(.|\n)+?\*/" class="comment" />
- <color pattern="//[^\r\n]*" class="comment" />
- <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
- <color pattern="\b((abstract)|(array)|(bool)|(break)|(case)|(catch)|(char)|(class)|(const)|(continue)|(delegate)|(delete)|(do)|(double)|(else)|(enum)|(event)|(extern)|(false)|(finally)|(float)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(int)|(interface)|(literal)|(namespace)|(new)|(noinline)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(sealed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(throw)|(true)|(try)|(typedef)|(union)|(using)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
- </colors>
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.SnippetComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples>
+ <example directory="d:\SnippetComponentTest\parsnip" />
+ </examples>
+ <!-- Each excludedUnits/unitFolder node specifies the name of a folder to exclude at the unit-level of the sample tree.
+ The unit folders are typically named "CS", "VB", etc.
+ Many example folders have "CPP_OLD" unit folders containing snippets that we do NOT want to include in the build. -->
+ <excludedUnits>
+ <unitFolder name="CPP_OLD" />
+ </excludedUnits>
+ <!-- You can specify an optional Parsnip approval log, in which case snippets are included only if they are in approved example units in the log. -->
+ <!-- TFS 480671 says DO NOT USE Parsnip approval logs for DevDiv content; ALL snippets should be included, regardless of Parsnip results. -->
+ <!--
+ <approvalLogs>
+ <approvalLog file="\\docbuildtask\snippet_building\Orcas\parsnip\approved-all.xml" />
+ </approvalLogs>
+ -->
+
+ <!-- language nodes specify:
+ @unit: name of the unit folders in the sample tree that contain examples in this language
+ @languageId: id for this language used in Manifold transforms, etc.
+ optional color nodes to specify rules for coloring snippets in this language
+ The order of language nodes determines the order in which the snippets are displayed
+ -->
+ <languages>
+ <language unit="VB" languageId="VisualBasic" extension=".vb">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(Alias)|(And)|(AndAlso)|(As)|(Boolean)|(ByRef)|(Byte)|(ByVal)|(Call)|(Case)|(Catch)|(CBool)|(CByte)|(CChar)|(CDate)|(CDec)|(CDbl)|(Char)|(CInt)|(Class)|(CLng)|(CObj)|(Const)|(Continue)|(CSByte)|(CShort)|(CSng)|(CStr)|(CType)|(CUInt)|(CULng)|(CUShort)|(Date)|(Decimal)|(Declare)|(Default)|(Delegate)|(Dim)|(DirectCast)|(Do)|(Double)|(Each)|(Else)|(ElseIf)|(End)|(EndIf)|(Enum)|(Erase)|(Error)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(From)|(Function)|(Get)|(GetType)|(GetXMLNamespace)|(Global)|(GoSub)|(GoTo)|(Handles)|(If)|(Implements)|(Imports)|(In)|(Inherits)|(Integer)|(Interface)|(Is)|(IsNot)|(Let)|(Lib)|(Like)|(Long)|(Loop)|(Me)|(Mod)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(MyClass)|(Namespace)|(Narrowing)|(New)|(Next)|(Not)|(Nothing)|(NotInheritable)|(NotOverridable)|(Object)|(Of)|(On)|(Operator)|(Option)|(Optional)|(Or)|(OrElse)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(ReDim)|(REM)|(RemoveHandler)|(Resume)|(Return)|(SByte)|(Select)|(Set)|(Shadows)|(Shared)|(Short)|(Single)|(Static)|(Step)|(Stop)|(String)|(Structure)|(Sub)|(SyncLock)|(Then)|(Throw)|(To)|(True)|(Try)|(TryCast)|(TypeOf)|(Variant)|(Wend)|(UInteger)|(ULong)|(UShort)|(Until)|(Using)|(When)|(Where)|(While)|(Widening)|(With)|(WithEvents)|(WriteOnly)|(Xor)|(#Const)|(#Else)|(#ElseIf)|(#End)|(#If))\b" class="keyword" />
+ </language>
+
+ <language unit="CS" languageId="CSharp" extension=".cs">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(as)|(ascending)|(base)|(bool)|(break)|(by)|(byte)|(case)|(catch)|(char)|(checked)|(class)|(const)|(continue)|(decimal)|(default)|(delegate)|(descending)|(do)|(double)|(else)|(enum)|(equals)|(event)|(explicit)|(extern)|(false)|(finally)|(fixed)|(float)|(for)|(foreach)|(from)|(get)|(goto)|(group)|(if)|(implicit)|(in)|(int)|(interface)|(internal)|(into)|(is)|(join)|(let)|(lock)|(long)|(namespace)|(new)|(null)|(object)|(operator)|(on)|(orderby)|(out)|(override)|(params)|(partial)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sbyte)|(sealed)|(select)|(set)|(short)|(sizeof)|(stackalloc)|(static)|(string)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(uint)|(ulong)|(unchecked)|(unsafe)|(ushort)|(using)|(value)|(var)|(yield)|(virtual)|(volatile)|(void)|(where)|(while))\b" class="keyword" />
+ </language>
+
+ <language unit="CPP" languageId="ManagedCPlusPlus" extension=".cpp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(array)|(bool)|(break)|(case)|(catch)|(char)|(class)|(const)|(continue)|(default)|(delegate)|(delete)|(deprecated)|(dllexport)|(dllimport)|(do)|(double)|(else)|(enum)|(event)|(explicit)|(extern)|(false)|(finally)|(float)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(int)|(interface)|(literal)|(long)|(mutable)|(naked)|(namespace)|(new)|(noinline)|(noreturn)|(nothrow)|(novtable)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(safecast)|(sealed)|(selectany)|(short)|(signed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(thread)|(throw)|(true)|(try)|(typedef)|(typeid)|(typename)|(union)|(unsigned)|(using)|(uuid)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </language>
+
+ <language unit="FS" languageId="FSharp" extension=".fs">
+ <color pattern="\(\*(.|\n)+?\*\)" class="comment" />"
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(and)|(as)|(asr)|(assert)|(atomic)|(base)|(begin)|(break)|(checked)|(class)|(component)|(const)|(constraint)|(constructor)|(continue)|(default)|(delegate)|(do)|(done)|(downcast)|(downto)|(eager)|(elif)|(else)|(end)|(event)|(exception)|(extern)|(external)|(false)|(finally)|(fixed)|(for)|(fun)|(function)|(functor)|(global)|(if)|(in)|(include)|(inherit)|(inline)|(interface)|(internal)|(land)|(lazy)|(let)|(lor)|(lsl)|(lsr)|(lxor)|(match)|(member)|(method)|(mixin)|(mod)|(module)|(mutable)|(namespace)|(new)|(null)|(object)|(of)|(open)|(or)|(override)|(parallel)|(private)|(process)|(protected)|(public)|(pure)|(rec)|(return)|(sealed)|(sig)|(static)|(struct)|(tailcall)|(then)|(to)|(trait)|(true)|(try)|(type)|(upcast)|(use)|(val)|(virtual)|(void)|(volatile)|(when)|(while)|(with)|(yield))\b" class="keyword" />
+ </language>
+
+ <language unit="JS" languageId="JScript" />
+ <language unit="JSL" languageId="JSharp" />
+ <language unit="Common" languageId="None" />
+ <language unit="XAML" languageId="XAML" />
+ </languages>
+
</component>
+ <!-- Copy in topicTypes -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <variable expression="/document/topic/*/ddue:relatedTopics/*/@xlink:href" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <index name="topicType" value="/metadata/topic" key="@id">
+ <data base="%DXROOT%\Data\ContentMetadata" recurse="true" files="*.contentmetadata.xml" />
+ </index>
+ <copy name="topicType" source="topicType" target="/document/topic/*/ddue:relatedTopics/*[@xlink:href='{0}' and not(@topicType_id)]" attribute="true" ignoreCase="true" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
<!-- transform -->
<component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<transform file="%DXROOT%\Presentation\Vs2005\transforms\main_conceptual.xsl">
- <argument key="metadata" value="true" />
- <argument key="languages">
- <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
<language label="CSharp" name="CSharp" style="cs" />
<language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
- <language label="JSharp" name="JSharp" style="cs" />
<language label="JScript" name="JScript" style="cs" />
+ <language label="FSharp" name="FSharp" style="fs" />
</argument>
+ <!-- You can use the optional changeHistoryOptions argument to control display of freshness date and Change History sections.
+ If value='showDefaultFreshnessDate', all topics have a freshness date; default date is from 'defaultFreshnessDate' shared content item.
+ if value='omit', freshness date and Change History sections are omitted from all topics.
+ <argument key="changeHistoryOptions" value="omit" />
+ -->
</transform>
</component>
<!-- resolve art links -->
<component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets input="%DXROOT%\Data\ArtStore" output=".\Output\media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ <targets input="%DXROOT%\Data\ArtStore" baseOutput=".\Output" outputPath="media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
</component>
<!-- resolve shared content -->
@@ -106,16 +167,16 @@
<!-- resolve reference links -->
<component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%DXROOT%\Data\Reflection\" recurse="true" files="*.xml" type="index" />
+ <targets base="%FxReflectionData%\" recurse="true" files="*.xml" type="index" />
</component>
<!-- save the result -->
<component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <save base=".\Output\html" path="concat($key,'.htm')" indent="true" omit-xml-declaration="true" />
+ <save base=".\Output\html" path="concat($key,'.htm')" link="../html" indent="true" omit-xml-declaration="true" />
</component>
<!-- record file creation events -->
- <component type="Microsoft.Ddue.Tools.HxfGeneratorComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll" input="%DXROOT%\Presentation\vs2005\seed.HxF" output=".\Output\test.HxF" />
+ <component type="Microsoft.Ddue.Tools.HxfGeneratorComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll" input="%DXROOT%\Presentation\vs2005\seed.HxF" output="test.HxF" />
</components>
</builder>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/reference-core-componentized.config b/tools/Sandcastle/Presentation/vs2005/configuration/reference-core-componentized.config
new file mode 100644
index 0000000..8081189
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/reference-core-componentized.config
@@ -0,0 +1,374 @@
+<configuration>
+ <dduetools>
+ <builder>
+ <context>
+ <namespace prefix="ddue" uri="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ </context>
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\vs2005\transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data files=".\reflection.xml" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" missing-entry="error" missing-source="error" missing-target="error" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="topicdata|apidata|typedata|family|templates|attributes" target="/document/reference/containers//type[@api=$key]" missing-entry="error" missing-source="error" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in type version data on memberlist topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/topicdata/@typeTopicId)" source="versions" target="/document/reference/topicdata" />
+ </component>
+
+ <!-- Copy in members version data for overload list topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference[topicdata[@subgroup='overload']]/elements//element/@api)" source="versions" target="/document/reference[topicdata[@subgroup='overload']]/elements//element[@api=$key]" />
+ </component>
+
+ <!-- Copy in explicitInterfaceImplemented reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/implements/member/@api | /document/reference/implements//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/implements//*[@api=$key and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/implements//*[@api=$key and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/parameters/parameter//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="/document/reference/topicdata/@group='api'" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator name="VisualBasic" type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="VisualBasicUsage" type="Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="CSharp" type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="ManagedCPlusPlus" type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="JSharp" type="Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="JScript" type="Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll">
+ <!-- filter files specify xaml configuration info, e.g. to control the assemblies whose apis get xaml syntax -->
+ <filter files="%DXROOT%\Presentation\shared\configuration\xamlSyntax.config"/>
+ </generator>
+ <generator type="Microsoft.Ddue.Tools.AspNetSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in metadata attributes -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="metadata" value="/metadata/topic" key="@id">
+ <data files=".\SupportFiles\*Metadata.xml" />
+ </index>
+ <index name="version" value="/metadata/topic" key="@id">
+ <data files="Version.xml" />
+ </index>
+ <copy name="metadata" source="*" target="/document/metadata" missing-target="error" />
+ <copy name="metadata" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ <copy name="version" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ </component>
+
+ <!-- Copy in metadata project settings -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="projectSettings" value="/*/item" key="@id">
+ <data files=".\ExtractedFiles\*projectsettings.xml" />
+ </index>
+ <copy name="projectSettings" key="string('PBM_FileVersion')" source="." target="/document/metadata" />
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base=".\DdueXml" recurse="true" files="*.xml" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" missing-target="error" />
+ </component>
+
+ <!-- Copy in comments of overidden member -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/comments/ddue:dduexml/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/overrides/member/@api)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:parameters|ddue:dduexml/ddue:returnValue" target="/document/comments/ddue:dduexml" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments of parent topics for inherited overload topics -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata/@parentTopicId)" source="*" target="/document/comments" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in HowDoI tasks -->
+ <component type="Microsoft.Ddue.Tools.TaskGrabberComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5"/>
+ <keywords topic="/metadata/topic[keyword[@index='B']]" keyword="keyword[@index='B']" files=".\SupportFiles\HowDoIKeywords\*.xml"/>
+ <source value="/topic/ddue:developerHowToDocument" key="../@id">
+ <data files=".\SupportFiles\HowDoIData\*.xml"/>
+ </source>
+ <copy source="ddue:title|ddue:introduction|ddue:codeExample" target="/document/comments/ddue:dduexml/ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/ddue:codeReference[starts-with(.,'HOWDOI#')]"/>
+ </component>
+
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples file="%DXROOT%\Data\CodeSnippet.xml" />
+ <colors language="VisualBasic">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(Alias)|(And)|(AndAlso)|(As)|(Boolean)|(ByRef)|(Byte)|(ByVal)|(Call)|(Case)|(Catch)|(CBool)|(CByte)|(CChar)|(CDate)|(CDec)|(CDbl)|(Char)|(CInt)|(Class)|(CLng)|(CObj)|(Const)|(Continue)|(CSByte)|(CShort)|(CSng)|(CStr)|(CType)|(CUInt)|(CULng)|(CUShort)|(Date)|(Decimal)|(Declare)|(Default)|(Delegate)|(Dim)|(DirectCast)|(Do)|(Double)|(Each)|(Else)|(ElseIf)|(End)|(EndIf)|(Enum)|(Erase)|(Error)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(From)|(Function)|(Get)|(GetType)|(GetXMLNamespace)|(Global)|(GoSub)|(GoTo)|(Handles)|(If)|(Implements)|(Imports)|(In)|(Inherits)|(Integer)|(Interface)|(Is)|(IsNot)|(Let)|(Lib)|(Like)|(Long)|(Loop)|(Me)|(Mod)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(MyClass)|(Namespace)|(Narrowing)|(New)|(Next)|(Not)|(Nothing)|(NotInheritable)|(NotOverridable)|(Object)|(Of)|(On)|(Operator)|(Option)|(Optional)|(Or)|(OrElse)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(ReDim)|(REM)|(RemoveHandler)|(Resume)|(Return)|(SByte)|(Select)|(Set)|(Shadows)|(Shared)|(Short)|(Single)|(Static)|(Step)|(Stop)|(String)|(Structure)|(Sub)|(SyncLock)|(Then)|(Throw)|(To)|(True)|(Try)|(TryCast)|(TypeOf)|(Variant)|(Wend)|(UInteger)|(ULong)|(UShort)|(Until)|(Using)|(When)|(Where)|(While)|(Widening)|(With)|(WithEvents)|(WriteOnly)|(Xor)|(#Const)|(#Else)|(#ElseIf)|(#End)|(#If))\b" class="keyword" />
+ </colors>
+ <colors language="CSharp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(as)|(ascending)|(base)|(bool)|(break)|(by)|(byte)|(case)|(catch)|(char)|(checked)|(class)|(const)|(continue)|(decimal)|(default)|(delegate)|(descending)|(do)|(double)|(else)|(enum)|(equals)|(event)|(explicit)|(extern)|(false)|(finally)|(fixed)|(float)|(for)|(foreach)|(from)|(get)|(goto)|(group)|(if)|(implicit)|(in)|(int)|(interface)|(internal)|(into)|(is)|(join)|(let)|(lock)|(long)|(namespace)|(new)|(null)|(object)|(operator)|(on)|(orderby)|(out)|(override)|(params)|(partial)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sbyte)|(sealed)|(select)|(set)|(short)|(sizeof)|(stackalloc)|(static)|(string)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(uint)|(ulong)|(unchecked)|(unsafe)|(ushort)|(using)|(value)|(var)|(vield)|(virtual)|(volatile)|(void)|(where)|(while))\b" class="keyword" />
+ </colors>
+ <colors language="ManagedCPlusPlus">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(array)|(bool)|(break)|(case)|(catch)|(char)|(class)|(const)|(continue)|(default)|(delegate)|(delete)|(deprecated)|(dllexport)|(dllimport)|(do)|(double)|(else)|(enum)|(event)|(explicit)|(extern)|(false)|(finally)|(float)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(int)|(interface)|(literal)|(long)|(mutable)|(naked)|(namespace)|(new)|(noinline)|(noreturn)|(nothrow)|(novtable)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(safecast)|(sealed)|(selectany)|(short)|(signed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(thread)|(throw)|(true)|(try)|(typedef)|(typeid)|(typename)|(union)|(unsigned)|(using)|(uuid)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </colors>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements//element[@api=$key]/apidata)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" missing-entry="error" missing-source="error" missing-target="error" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" missing-target="error" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/overrides/member/@api)" source="ddue:dduexml/ddue:summary" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ </components>
+ </component>
+
+ <!-- Add platforms data -->
+ <component type="Microsoft.Ddue.Tools.PlatformsComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <!-- The order of filter files in this config determines the order of platforms in the output. -->
+ <filter files=".\SupportFiles\Platforms\WinVista.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXP.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXpMediaCenter.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXPPro64.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXPSE.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinSvr2003.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinSvr2000.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinME.xml"/>
+ <filter files=".\SupportFiles\Platforms\Win98.xml"/>
+ <filter files=".\SupportFiles\Platforms\WindowsCE.xml"/>
+ <filter files=".\SupportFiles\Platforms\SmartPhone.xml"/>
+ <filter files=".\SupportFiles\Platforms\PocketPC.xml"/>
+ <filter files=".\SupportFiles\Platforms\Xbox360.xml"/>
+ </component>
+
+ <!-- Copy in comments for a member list topic's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata[@group='list' and @subgroup!='overload'])" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata[@group='list' and @subgroup!='overload']/@typeTopicId)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments for a member's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean((/document/reference/topicdata[@group='list' and @subgroup='overload']) | (/document/reference/apidata[@group='member']))" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/containers/type/@api)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- resolve tokens -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <content file="%DXROOT%\Data\tokens.xml" />
+ <replace elements="/document//ddue:token" item="string(.)" />
+ </component>
+
+ <!-- Copy in topicTypes -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <variable expression="/document/comments/ddue:relatedTopics/*/@xlink:href" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <index name="topicType" value="/metadata/topic" key="@id">
+ <data base="%DXROOT%\Data\ContentMetadata" recurse="true" files="*.contentmetadata.xml" />
+ </index>
+ <copy name="topicType" source="topicType" target="/document/comments/ddue:relatedTopics/*[@xlink:href='{0}' and not(@topicType_id)]" attribute="true" ignoreCase="true" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\vs2005\transforms\main_reference.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <language label="JSharp" name="JSharp" style="cs" />
+ <language label="JScript" name="JScript" style="cs" />
+ </argument>
+ <argument key="omitAptcaBoilerplate" value="false" />
+ <argument key="RTMReleaseDate" value="June 2007" />
+ </transform>
+ </component>
+
+ <!-- resolve art links -->
+ <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets input="%DXROOT%\Data\ArtStore" baseOutput=".\Output" outputPath="concat(/html/head/meta[@name='container']/@content,'\media')" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\vs2005\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\Vs2005\content\feedBack_content.xml" />
+ <content file="%DXROOT%\Presentation\vs2005\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
+ </component>
+
+ <!-- resolve conceptual links -->
+ <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\XmlComp" type="index"/>
+ </component>
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets files=".\reflection.xml" type="LocalOrIndex" />
+ </component>
+
+<!--
+ <component type="Microsoft.Ddue.Tools.DisplayComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <xpath>/</xpath>
+ </component>
+-->
+
+ <!-- Write out intellisense -->
+ <component type="Microsoft.Ddue.Tools.IntellisenseComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <output directory=".\Intellisense" />
+ <expressions root="/html/body/div[@id='mainSection']/div[@id='mainBody']"
+ assembly="string(span[@sdata='assembly'])"
+ summary="span[@sdata='authoredSummary']"
+ parameters="div[@id='syntaxSection']/div[@id='parameters']/dl"
+ parameterContent="dd/span[@sdata='authoredParameterSummary']"
+ templates="div[@id='syntaxSection']/div[@id='genericParameters']/dl"
+ templateContent="dd"
+ returns="div[@id='syntaxSection']/div[@id='returns']/span[@sdata='authoredValueSummary']"
+ exception="div[@id='ddueExceptionsSection']/div[@class='tableSection']/table/tr/td[2]"
+ exceptionCref="../td[1]/span[@sdata='cer']"
+ enumeration="div[@id='enumerationSection']/div[@id='membersSection']/table[@class='members']/tr/td[3]"
+ enumerationApi="../td[2]"
+ memberSummary="span[@sdata='memberAuthoredSummary']" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base=".\Output" path="concat(/html/head/meta[@name='container']/@content,'\html\',/html/head/meta[@name='file']/@content,'.htm')" indent="true" omit-xml-declaration="true" />
+ </component>
+
+ <!-- record file creation events -->
+ <component type="Microsoft.Ddue.Tools.HxfGeneratorComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll" input="%DXROOT%\Presentation\vs2005\seed.HxF" output="test.HXF" />
+
+ </components>
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/reference-core.config b/tools/Sandcastle/Presentation/vs2005/configuration/reference-core.config
new file mode 100644
index 0000000..56a14dd
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/reference-core.config
@@ -0,0 +1,373 @@
+<configuration>
+ <dduetools>
+ <builder>
+ <context>
+ <namespace prefix="ddue" uri="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ </context>
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\vs2005\transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data files=".\reflection.xml" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" missing-entry="error" missng-source="error" missing-target="error" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="topicdata|apidata|typedata|family|templates|attributes" target="/document/reference/containers//type[@api=$key]" missing-entry="error" missing-source="error" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in type version data on memberlist topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/topicdata/@typeTopicId)" source="versions" target="/document/reference/topicdata" />
+ </component>
+
+ <!-- Copy in members version data for overload list topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference[topicdata[@subgroup='overload']]/elements//element/@api)" source="versions" target="/document/reference[topicdata[@subgroup='overload']]/elements//element[@api=$key]" />
+ </component>
+
+ <!-- Copy in explicitInterfaceImplemented reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/implements/member/@api | /document/reference/implements//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/implements//*[@api=$key and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/implements//*[@api=$key and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/parameters/parameter//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="/document/reference/topicdata/@group='api'" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator name="VisualBasic" type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="VisualBasicUsage" type="Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="CSharp" type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="ManagedCPlusPlus" type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="JSharp" type="Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator name="JScript" type="Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll">
+ <!-- filter files specify xaml configuration info, e.g. to control the assemblies whose apis get xaml syntax -->
+ <filter files="%DXROOT%\Presentation\shared\configuration\xamlSyntax.config"/>
+ </generator>
+ <generator type="Microsoft.Ddue.Tools.AspNetSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in metadata attributes -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="metadata" value="/metadata/topic" key="@id">
+ <data files=".\SupportFiles\*Metadata.xml" />
+ </index>
+ <index name="version" value="/metadata/topic" key="@id">
+ <data files="Version.xml" />
+ </index>
+ <copy name="metadata" source="*" target="/document/metadata" missing-target="error" />
+ <copy name="metadata" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ <copy name="version" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ </component>
+
+ <!-- Copy in metadata project settings -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="projectSettings" value="/*/item" key="@id">
+ <data files=".\ExtractedFiles\*projectsettings.xml" />
+ </index>
+ <copy name="projectSettings" key="string('PBM_FileVersion')" source="." target="/document/metadata" />
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base=".\DdueXml" recurse="true" files="*.xml" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" missing-target="error" />
+ </component>
+
+ <!-- Copy in comments of overidden member -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/comments/ddue:dduexml/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/overrides/member/@api)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:parameters|ddue:dduexml/ddue:returnValue" target="/document/comments/ddue:dduexml" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments of parent topics for inherited overload topics -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata/@parentTopicId)" source="*" target="/document/comments" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in HowDoI tasks -->
+ <component type="Microsoft.Ddue.Tools.TaskGrabberComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5"/>
+ <keywords topic="/metadata/topic[keyword[@index='B']]" keyword="keyword[@index='B']" files=".\SupportFiles\HowDoIKeywords\*.xml"/>
+ <source value="/topic/ddue:developerHowToDocument" key="../@id">
+ <data files=".\SupportFiles\HowDoIData\*.xml"/>
+ </source>
+ <copy source="ddue:title|ddue:introduction|ddue:codeExample" target="/document/comments/ddue:dduexml/ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/ddue:codeReference[starts-with(.,'HOWDOI#')]"/>
+ </component>
+
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples file="%DXROOT%\Data\CodeSnippet.xml" />
+ <colors language="VisualBasic">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(Alias)|(And)|(AndAlso)|(As)|(Boolean)|(ByRef)|(Byte)|(ByVal)|(Call)|(Case)|(Catch)|(CBool)|(CByte)|(CChar)|(CDate)|(CDec)|(CDbl)|(Char)|(CInt)|(Class)|(CLng)|(CObj)|(Const)|(Continue)|(CSByte)|(CShort)|(CSng)|(CStr)|(CType)|(CUInt)|(CULng)|(CUShort)|(Date)|(Decimal)|(Declare)|(Default)|(Delegate)|(Dim)|(DirectCast)|(Do)|(Double)|(Each)|(Else)|(ElseIf)|(End)|(EndIf)|(Enum)|(Erase)|(Error)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(From)|(Function)|(Get)|(GetType)|(GetXMLNamespace)|(Global)|(GoSub)|(GoTo)|(Handles)|(If)|(Implements)|(Imports)|(In)|(Inherits)|(Integer)|(Interface)|(Is)|(IsNot)|(Let)|(Lib)|(Like)|(Long)|(Loop)|(Me)|(Mod)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(MyClass)|(Namespace)|(Narrowing)|(New)|(Next)|(Not)|(Nothing)|(NotInheritable)|(NotOverridable)|(Object)|(Of)|(On)|(Operator)|(Option)|(Optional)|(Or)|(OrElse)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(ReDim)|(REM)|(RemoveHandler)|(Resume)|(Return)|(SByte)|(Select)|(Set)|(Shadows)|(Shared)|(Short)|(Single)|(Static)|(Step)|(Stop)|(String)|(Structure)|(Sub)|(SyncLock)|(Then)|(Throw)|(To)|(True)|(Try)|(TryCast)|(TypeOf)|(Variant)|(Wend)|(UInteger)|(ULong)|(UShort)|(Until)|(Using)|(When)|(Where)|(While)|(Widening)|(With)|(WithEvents)|(WriteOnly)|(Xor)|(#Const)|(#Else)|(#ElseIf)|(#End)|(#If))\b" class="keyword" />
+ </colors>
+ <colors language="CSharp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(as)|(ascending)|(base)|(bool)|(break)|(by)|(byte)|(case)|(catch)|(char)|(checked)|(class)|(const)|(continue)|(decimal)|(default)|(delegate)|(descending)|(do)|(double)|(else)|(enum)|(equals)|(event)|(explicit)|(extern)|(false)|(finally)|(fixed)|(float)|(for)|(foreach)|(from)|(get)|(goto)|(group)|(if)|(implicit)|(in)|(int)|(interface)|(internal)|(into)|(is)|(join)|(let)|(lock)|(long)|(namespace)|(new)|(null)|(object)|(operator)|(on)|(orderby)|(out)|(override)|(params)|(partial)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sbyte)|(sealed)|(select)|(set)|(short)|(sizeof)|(stackalloc)|(static)|(string)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(uint)|(ulong)|(unchecked)|(unsafe)|(ushort)|(using)|(value)|(var)|(vield)|(virtual)|(volatile)|(void)|(where)|(while))\b" class="keyword" />
+ </colors>
+ <colors language="ManagedCPlusPlus">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(array)|(bool)|(break)|(case)|(catch)|(char)|(class)|(const)|(continue)|(default)|(delegate)|(delete)|(deprecated)|(dllexport)|(dllimport)|(do)|(double)|(else)|(enum)|(event)|(explicit)|(extern)|(false)|(finally)|(float)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(int)|(interface)|(literal)|(long)|(mutable)|(naked)|(namespace)|(new)|(noinline)|(noreturn)|(nothrow)|(novtable)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(safecast)|(sealed)|(selectany)|(short)|(signed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(thread)|(throw)|(true)|(try)|(typedef)|(typeid)|(typename)|(union)|(unsigned)|(using)|(uuid)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </colors>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements//element[@api=$key]/apidata)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" missing-entry="error" missing-source="error" missing-target="error" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" missing-target="error" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/overrides/member/@api)" source="ddue:dduexml/ddue:summary" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ </components>
+ </component>
+
+ <!-- Add platforms data -->
+ <component type="Microsoft.Ddue.Tools.PlatformsComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <!-- The order of filter files in this config determines the order of platforms in the output. -->
+ <filter files=".\SupportFiles\Platforms\WinVista.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXP.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXpMediaCenter.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXPPro64.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinXPSE.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinSvr2003.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinSvr2000.xml"/>
+ <filter files=".\SupportFiles\Platforms\WinME.xml"/>
+ <filter files=".\SupportFiles\Platforms\Win98.xml"/>
+ <filter files=".\SupportFiles\Platforms\WindowsCE.xml"/>
+ <filter files=".\SupportFiles\Platforms\SmartPhone.xml"/>
+ <filter files=".\SupportFiles\Platforms\PocketPC.xml"/>
+ <filter files=".\SupportFiles\Platforms\Xbox360.xml"/>
+ </component>
+
+ <!-- Copy in comments for a member list topic's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata[@group='list' and @subgroup!='overload'])" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata[@group='list' and @subgroup!='overload']/@typeTopicId)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments for a member's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean((/document/reference/topicdata[@group='list' and @subgroup='overload']) | (/document/reference/apidata[@group='member']))" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/containers/type/@api)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- resolve tokens -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <content file="%DXROOT%\Data\tokens.xml" />
+ <replace elements="/document//ddue:token" item="string(.)" />
+ </component>
+
+ <!-- Copy in topicTypes -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <variable expression="/document/comments/ddue:relatedTopics/*/@xlink:href" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <index name="topicType" value="/metadata/topic" key="@id">
+ <data base="%DXROOT%\Data\ContentMetadata" recurse="true" files="*.contentmetadata.xml" />
+ </index>
+ <copy name="topicType" source="topicType" target="/document/comments/ddue:relatedTopics/*[@xlink:href='{0}' and not(@topicType_id)]" attribute="true" ignoreCase="true" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\vs2005\transforms\main_reference.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <language label="JSharp" name="JSharp" style="cs" />
+ <language label="JScript" name="JScript" style="cs" />
+ </argument>
+ <argument key="omitAptcaBoilerplate" value="false" />
+ <argument key="RTMReleaseDate" value="June 2007" />
+ </transform>
+ </component>
+
+ <!-- resolve art links -->
+ <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets input="%DXROOT%\Data\ArtStore" baseOutput=".\Output" outputPath="media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\vs2005\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\Vs2005\content\feedBack_content.xml" />
+ <content file="%DXROOT%\Presentation\vs2005\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
+ </component>
+
+ <!-- resolve conceptual links -->
+ <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\XmlComp" type="index"/>
+ </component>
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets files=".\reflection.xml" type="local" />
+ </component>
+<!--
+ <component type="Microsoft.Ddue.Tools.DisplayComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <xpath>/</xpath>
+ </component>
+ -->
+
+ <!-- Write out intellisense -->
+ <component type="Microsoft.Ddue.Tools.IntellisenseComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <output directory=".\Intellisense" />
+ <expressions root="/html/body/div[@id='mainSection']/div[@id='mainBody']"
+ assembly="string(span[@sdata='assembly'])"
+ summary="span[@sdata='authoredSummary']"
+ parameters="div[@id='syntaxSection']/div[@id='parameters']/dl"
+ parameterContent="dd/span[@sdata='authoredParameterSummary']"
+ templates="div[@id='syntaxSection']/div[@id='genericParameters']/dl"
+ templateContent="dd"
+ returns="div[@id='syntaxSection']/div[@id='returns']/span[@sdata='authoredValueSummary']"
+ exception="div[@id='ddueExceptionsSection']/div[@class='tableSection']/table/tr/td[2]"
+ exceptionCref="../td[1]/span[@sdata='cer']"
+ enumeration="div[@id='enumerationSection']/div[@id='membersSection']/table[@class='members']/tr/td[3]"
+ enumerationApi="../td[2]"
+ memberSummary="span[@sdata='memberAuthoredSummary']" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base=".\Output\html" path="concat(/html/head/meta[@name='file']/@content,'.htm')" link="../html" indent="true" omit-xml-declaration="true" />
+ </component>
+
+ <!-- record file creation events -->
+ <component type="Microsoft.Ddue.Tools.HxfGeneratorComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll" input="%DXROOT%\Presentation\vs2005\seed.HxF" output="test.HxF" />
+
+ </components>
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/reference.config b/tools/Sandcastle/Presentation/vs2005/configuration/reference.config
new file mode 100644
index 0000000..775ec5b
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/reference.config
@@ -0,0 +1,344 @@
+<configuration>
+ <dduetools>
+ <builder>
+
+ <context>
+ <namespace prefix="ddue" uri="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ </context>
+
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\vs2005\transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" />
+ <data files=".\reflection.xml" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="topicdata|apidata|typedata|family|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in type version data on memberlist topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/topicdata/@typeTopicId)" source="versions" target="/document/reference/topicdata" />
+ </component>
+
+ <!-- Copy in members version data for overload list topics -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference[topicdata[@subgroup='overload']]/elements//element/@api)" source="versions" target="/document/reference[topicdata[@subgroup='overload']]/elements//element[@api=$key]" />
+ </component>
+
+ <!-- Copy in explicitInterfaceImplemented reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/implements/member/@api | /document/reference/implements//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/implements//*[@api=$key and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/implements//*[@api=$key and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/parameters/parameter//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="/document/reference/topicdata/@group='api'" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll">
+ <!-- filter files specify xaml configuration info, e.g. to control the assemblies whose apis get xaml syntax -->
+ <filter files="%DXROOT%\Presentation\shared\configuration\xamlSyntax.config"/>
+ </generator>
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in metadata attributes -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="metadata" value="/metadata/topic" key="@id">
+ <data files=".\SupportFiles\*Metadata.xml" />
+ </index>
+ <index name="version" value="/metadata/topic" key="@id">
+ <data files="Version.xml" />
+ </index>
+ <copy name="metadata" source="*" target="/document/metadata" />
+ <copy name="metadata" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ <copy name="version" key="string('*')" source="*" target="/document/metadata" missing-target="error" />
+ </component>
+
+ <!-- Copy in metadata project settings -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="projectSettings" value="/*/item" key="@id">
+ <data files=".\ExtractedFiles\*projectsettings.xml" />
+ </index>
+ <copy name="projectSettings" key="string('PBM_FileVersion')" source="." target="/document/metadata" />
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base="%DXROOT%\Data\DdueXml" recurse="true" files="*.xml" />
+ <data base=".\DdueXml" recurse="true" files="*.xml" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" />
+ </component>
+
+ <!-- Copy in comments of overidden member -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/comments/ddue:dduexml/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/overrides/member/@api)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:parameters|ddue:dduexml/ddue:returnValue" target="/document/comments/ddue:dduexml" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments of parent topics for inherited overload topics -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata/@parentTopicId)" source="*" target="/document/comments" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Resolve code snippets -->
+ <component type="Microsoft.Ddue.Tools.ExampleComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <examples file="%DXROOT%\Data\CodeSnippet.xml" />
+ <colors language="VisualBasic">
+ <color pattern="^\s*'[^\r\n]*" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="\b((AddHandler)|(AddressOf)|(Alias)|(And)|(AndAlso)|(As)|(Boolean)|(ByRef)|(Byte)|(ByVal)|(Call)|(Case)|(Catch)|(CBool)|(CByte)|(CChar)|(CDate)|(CDec)|(CDbl)|(Char)|(CInt)|(Class)|(CLng)|(CObj)|(Const)|(Continue)|(CSByte)|(CShort)|(CSng)|(CStr)|(CType)|(CUInt)|(CULng)|(CUShort)|(Date)|(Decimal)|(Declare)|(Default)|(Delegate)|(Dim)|(DirectCast)|(Do)|(Double)|(Each)|(Else)|(ElseIf)|(End)|(EndIf)|(Enum)|(Erase)|(Error)|(Event)|(Exit)|(False)|(Finally)|(For)|(Friend)|(From)|(Function)|(Get)|(GetType)|(GetXMLNamespace)|(Global)|(GoSub)|(GoTo)|(Handles)|(If)|(Implements)|(Imports)|(In)|(Inherits)|(Integer)|(Interface)|(Is)|(IsNot)|(Let)|(Lib)|(Like)|(Long)|(Loop)|(Me)|(Mod)|(Module)|(MustInherit)|(MustOverride)|(MyBase)|(MyClass)|(Namespace)|(Narrowing)|(New)|(Next)|(Not)|(Nothing)|(NotInheritable)|(NotOverridable)|(Object)|(Of)|(On)|(Operator)|(Option)|(Optional)|(Or)|(OrElse)|(Overloads)|(Overridable)|(Overrides)|(ParamArray)|(Partial)|(Private)|(Property)|(Protected)|(Public)|(RaiseEvent)|(ReadOnly)|(ReDim)|(REM)|(RemoveHandler)|(Resume)|(Return)|(SByte)|(Select)|(Set)|(Shadows)|(Shared)|(Short)|(Single)|(Static)|(Step)|(Stop)|(String)|(Structure)|(Sub)|(SyncLock)|(Then)|(Throw)|(To)|(True)|(Try)|(TryCast)|(TypeOf)|(Variant)|(Wend)|(UInteger)|(ULong)|(UShort)|(Until)|(Using)|(When)|(Where)|(While)|(Widening)|(With)|(WithEvents)|(WriteOnly)|(Xor)|(#Const)|(#Else)|(#ElseIf)|(#End)|(#If))\b" class="keyword" />
+
+ </colors>
+ <colors language="CSharp">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(as)|(ascending)|(base)|(bool)|(break)|(by)|(byte)|(case)|(catch)|(char)|(checked)|(class)|(const)|(continue)|(decimal)|(default)|(delegate)|(descending)|(do)|(double)|(else)|(enum)|(equals)|(event)|(explicit)|(extern)|(false)|(finally)|(fixed)|(float)|(for)|(foreach)|(from)|(get)|(goto)|(group)|(if)|(implicit)|(in)|(int)|(interface)|(internal)|(into)|(is)|(join)|(let)|(lock)|(long)|(namespace)|(new)|(null)|(object)|(operator)|(on)|(orderby)|(out)|(override)|(params)|(partial)|(private)|(protected)|(public)|(readonly)|(ref)|(return)|(sbyte)|(sealed)|(select)|(set)|(short)|(sizeof)|(stackalloc)|(static)|(string)|(struct)|(switch)|(this)|(throw)|(true)|(try)|(typeof)|(uint)|(ulong)|(unchecked)|(unsafe)|(ushort)|(using)|(value)|(var)|(vield)|(virtual)|(volatile)|(void)|(where)|(while))\b" class="keyword" />
+ </colors>
+ <colors language="ManagedCPlusPlus">
+ <color pattern="/\*(.|\n)+?\*/" class="comment" />
+ <color pattern="\&#34;[^&#34;\r\n]*\&#34;" class="literal" />
+ <color pattern="//[^\r\n]*" class="comment" />
+ <color pattern="\b((abstract)|(array)|(bool)|(break)|(case)|(catch)|(char)|(class)|(const)|(continue)|(default)|(delegate)|(delete)|(deprecated)|(dllexport)|(dllimport)|(do)|(double)|(else)|(enum)|(event)|(explicit)|(extern)|(false)|(finally)|(float)|(for)|(friend)|(gcnew)|(generic)|(goto)|(if)|(initonly)|(inline)|(int)|(interface)|(literal)|(long)|(mutable)|(naked)|(namespace)|(new)|(noinline)|(noreturn)|(nothrow)|(novtable)|(nullptr)|(operator)|(private)|(property)|(protected)|(public)|(ref)|(register)|(return)|(safecast)|(sealed)|(selectany)|(short)|(signed)|(sizeof)|(static)|(struct)|(switch)|(template)|(this)|(thread)|(throw)|(true)|(try)|(typedef)|(typeid)|(typename)|(union)|(unsigned)|(using)|(uuid)|(value)|(virtual)|(void)|(volatile)|(while))\b" class="keyword" />
+ </colors>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements//element[@api=$key]/apidata)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/topicdata/@parentTopicId)" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/elements//element[@api=$key]/ddue:useBase)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/elements//element[@api=$key]/overrides/member/@api)" source="ddue:dduexml/ddue:summary" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in comments for a member list topic's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean(/document/reference/topicdata[@group='list' and @subgroup!='overload'])" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/topicdata[@group='list' and @subgroup!='overload']/@typeTopicId)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments for a member's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="boolean((/document/reference/topicdata[@group='list' and @subgroup='overload']) | (/document/reference/apidata[@group='member']))" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <copy name="comments" key="string(/document/reference/containers/type/@api)"
+ source="ddue:dduexml/ddue:summary|ddue:dduexml/ddue:useBase|ddue:dduexml/ddue:obsoleteCodeEntity|ddue:dduexml/ddue:clsCompliantAlternative|ddue:dduexml/ddue:platformNotes|ddue:dduexml/ddue:internalOnly"
+ target="/document/reference/containers" />
+ </component>
+ </then>
+ </component>
+
+ <!-- resolve tokens -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <content file="%DXROOT%\Data\tokens.xml" />
+ <replace elements="/document//ddue:token" item="string(.)" />
+ </component>
+
+ <!-- Copy in topicTypes -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <variable expression="/document/comments/ddue:relatedTopics/*/@xlink:href" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <context prefix="ddue" name="http://ddue.schemas.microsoft.com/authoring/2003/5" />
+ <context prefix="xlink" name="http://www.w3.org/1999/xlink" />
+ <index name="topicType" value="/metadata/topic" key="@id">
+ <data base="%DXROOT%\Data\ContentMetadata" recurse="true" files="*.contentmetadata.xml" />
+ </index>
+ <copy name="topicType" source="topicType" target="/document/comments/ddue:relatedTopics/*[@xlink:href='{0}' and not(@topicType_id)]" attribute="true" ignoreCase="true" missing-target="error" />
+ </component>
+ </components>
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\vs2005\transforms\main_reference.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <language label="JSharp" name="JSharp" style="cs" />
+ <language label="JScript" name="JScript" style="cs" />
+ </argument>
+ <argument key="omitAptcaBoilerplate" value="false" />
+ <argument key="RTMReleaseDate" value="June 2007" />
+ </transform>
+ </component>
+
+ <!-- resolve art links -->
+ <component type="Microsoft.Ddue.Tools.ResolveArtLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets input="%DXROOT%\Data\ArtStore" baseOutput=".\Output" outputPath="media" link="../media" map="%DXROOT%\Data\ArtSharedContent.loc.xml" />
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\vs2005\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\Vs2005\content\feedBack_content.xml" />
+ <content file="%DXROOT%\Presentation\vs2005\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
+ </component>
+
+ <!-- resolve conceptual links -->
+ <component type="Microsoft.Ddue.Tools.ResolveConceptualLinksComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%DXROOT%\Data\XmlComp" type="index"/>
+ </component>
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <!-- <targets base="%DXROOT%\Data\Reflection" recurse="true" files="*.xml" type="index" /> -->
+ <targets files=".\reflection.xml" type="local" />
+ </component>
+
+ <!-- Write out intellisense -->
+ <component type="Microsoft.Ddue.Tools.IntellisenseComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <output directory=".\Intellisense" />
+ <expressions root="/html/body/div[@id='mainSection']/div[@id='mainBody']"
+ assembly="string(span[@sdata='assembly'])"
+ summary="span[@sdata='authoredSummary']"
+ parameters="div[@id='syntaxSection']/div[@id='parameters']/dl"
+ parameterContent="dd/span[@sdata='authoredParameterSummary']"
+ templates="div[@id='syntaxSection']/div[@id='genericParameters']/dl"
+ templateContent="dd"
+ returns="div[@id='syntaxSection']/div[@id='returns']/span[@sdata='authoredValueSummary']"
+ exception="div[@id='ddueExceptionsSection']/div[@class='tableSection']/table/tr/td[2]"
+ exceptionCref="../td[1]/span[@sdata='cer']"
+ enumeration="div[@id='enumerationSection']/div[@id='membersSection']/table[@class='members']/tr/td[3]"
+ enumerationApi="../td[2]"
+ memberSummary="span[@sdata='memberAuthoredSummary']" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base=".\Output\html" path="concat(/html/head/meta[@name='file']/@content,'.htm')" link="../html" indent="true" omit-xml-declaration="true" />
+ </component>
+
+ <!-- record file creation events -->
+ <component type="Microsoft.Ddue.Tools.HxfGeneratorComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll" input="%DXROOT%\Presentation\vs2005\seed.HxF" output="test.HxF" />
+
+ </components>
+ </builder>
+ </dduetools>
+</configuration>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-scbuild.config b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-scbuild.config
index 237a27e..0c5a7ff 100644
--- a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-scbuild.config
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-scbuild.config
@@ -41,13 +41,55 @@
</components>
</component>
- <!-- Copy in parameter data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <!-- Copy in extension method template/type data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element[@source='extension']/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<variable expression="/document/reference/parameters/parameter//type/@api" />
<components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
- </component>
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in templates type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/templates//type[@api=$key]" />
+ <copy name="reflection" source="templates" target="/document/reference/templates//type[@api=$key and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
</components>
</component>
@@ -73,6 +115,12 @@
<data base="%DxTempDir%\Comments\" recurse="false" files="*.xml" />
</index>
<copy name="comments" source="*" target="/document/comments" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
</component>
<!-- Copy in reflection data and comments for members -->
@@ -88,7 +136,13 @@
</then>
</component>
<component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" source="summary|overloads" target="/document/reference/elements//element[@api=$key]" />
+ <copy name="comments" source="summary|overloads|inheritdoc" target="/document/reference/elements//element[@api=$key]" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
</component>
</components>
</component>
@@ -108,7 +162,7 @@
<language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
<!--<language label="JSharp" name="JSharp" style="cs" />
<language label="JScript" name="JScript" style="cs" />-->
- <language label="JavaScript" name="JavaScript" style="vb" />
+ <language label="JavaScript" name="JavaScript" style="cs" />
</argument>
</transform>
</component>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-webref.config b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-webref.config
index e4b7612..956c5a6 100644
--- a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-webref.config
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle-webref.config
@@ -41,13 +41,55 @@
</components>
</component>
- <!-- Copy in parameter data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <!-- Copy in extension method template/type data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element[@source='extension']/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<variable expression="/document/reference/parameters/parameter//type/@api" />
<components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
<copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
- </component>
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in templates type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/templates//type[@api=$key]" />
+ <copy name="reflection" source="templates" target="/document/reference/templates//type[@api=$key and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
</components>
</component>
@@ -73,6 +115,12 @@
<data base="%DxTempDir%\Comments\" recurse="false" files="*.xml" />
</index>
<copy name="comments" source="*" target="/document/comments" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
</component>
<!-- Copy in reflection data and comments for members -->
@@ -88,7 +136,13 @@
</then>
</component>
<component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" source="summary|overloads" target="/document/reference/elements//element[@api=$key]" />
+ <copy name="comments" source="summary|overloads|inheritdoc" target="/document/reference/elements//element[@api=$key]" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
</component>
</components>
</component>
@@ -108,7 +162,7 @@
<language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
<!--<language label="JSharp" name="JSharp" style="cs" />
<language label="JScript" name="JScript" style="cs" />-->
- <language label="JavaScript" name="JavaScript" style="vb" />
+ <language label="JavaScript" name="JavaScript" style="cs" />
</argument>
</transform>
</component>
diff --git a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle.config b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle.config
index 8522fd9..7d45cf8 100644
--- a/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle.config
+++ b/tools/Sandcastle/Presentation/vs2005/configuration/sandcastle.config
@@ -1,141 +1,195 @@
<configuration>
- <dduetools>
- <builder>
- <components>
-
- <!-- Create skeleton document -->
- <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <data file="%DXROOT%\Presentation\vs2005\Transforms\skeleton.xml" />
- <copy source="/*" target="/" />
- </component>
-
- <!-- Copy in reflection data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
- <data base="%FxReflectionData%" recurse="true" files="*.xml" />
- <data files="%ReflectionXmlFile%" />
- </index>
- <copy name="reflection" source="*" target="/document/reference" />
- </component>
-
- <!-- Copy in container data -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
- </component>
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/containers//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in explicitInterfaceImplemented reflection data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/implements/member/@api | /document/reference/implements//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata" target="/document/reference/implements//*[@api=$key and not(apidata)]" />
- <copy name="reflection" source="templates" target="/document/reference/implements//*[@api=$key and not(apidata) and not(specialization)]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in parameter data -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/parameters/parameter//type/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
- </component>
- </components>
- </component>
-
- <!-- Generate syntax -->
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(starts-with($key,'Overload:') or starts-with($key,'R:'))" />
- <then>
- <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <syntax input="/document/reference" output="/document/syntax" />
- <generators>
- <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- <generator type="Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
- </generators>
- </component>
- </then>
- </component>
-
- <!-- Copy in comments -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <index name="comments" value="/doc/members/member" key="@name" cache="100">
- <data base="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" recurse="false" files="*.xml" />
- <data files="%DocumentationFile%" />
- </index>
- <copy name="comments" source="*" target="/document/comments" />
- </component>
-
- <!-- Copy in reflection data and comments for members -->
- <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <variable expression="/document/reference/elements//element/@api" />
- <components>
- <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <if condition="not(/document/reference/elements/element[@api=$key]/apidata)" />
- <then>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </then>
- </component>
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" source="summary|overloads" target="/document/reference/elements//element[@api=$key]" />
- </component>
- </components>
- </component>
-
- <!-- Copy in comments for the member's declaring type. -->
- <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <copy name="comments" key="string(/document/reference/containers/type/@api)" source="summary" target="/document/reference/containers" />
- </component>
-
- <!-- transform -->
- <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <transform file="%DXROOT%\Presentation\vs2005\Transforms\main_sandcastle.xsl">
- <argument key="metadata" value="true" />
- <argument key="languages">
- <language label="VisualBasic" name="VisualBasic" style="vb" />
- <language label="CSharp" name="CSharp" style="cs" />
- <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
- <!--<language label="JSharp" name="JSharp" style="cs" />
+ <dduetools>
+ <builder>
+ <components>
+
+ <!-- Create skeleton document -->
+ <component type="Microsoft.Ddue.Tools.CopyFromFileComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <data file="%DXROOT%\Presentation\vs2005\Transforms\skeleton.xml" />
+ <copy source="/*" target="/" />
+ </component>
+
+ <!-- Copy in reflection data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
+ <data base="%FxReflectionData%" recurse="true" files="*.xml" />
+ <data files="%ReflectionXmlFile%" />
+ </index>
+ <copy name="reflection" source="*" target="/document/reference" />
+ </component>
+
+ <!-- Copy in container data -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" key="string(/document/reference/containers/namespace/@api)" source="*[not(local-name()='elements')]" target="/document/reference/containers/namespace" />
+ </component>
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/containers//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|templates|attributes" target="/document/reference/containers//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in explicitInterfaceImplemented reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/implements/member/@api | /document/reference/implements//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/implements//*[@api=$key and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/implements//*[@api=$key and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in extension method template/type data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element[@source='extension']/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata)]" />
+ <copy name="reflection" source="templates" target="/document/reference/elements//element[@source='extension']/templates//type[boolean(@api=$key) and not(apidata) and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in parameter data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/parameters/parameter//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/parameters/parameter//type[boolean(@api=$key) and not(apidata)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in templates type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/templates//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata" target="/document/reference/templates//type[@api=$key]" />
+ <copy name="reflection" source="templates" target="/document/reference/templates//type[@api=$key and not(specialization)]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in return type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/returns//type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/returns//type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in event handler type reflection data -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/eventhandler/type/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="apidata|typedata|family|templates|containers|attributes" target="/document/reference/eventhandler/type[@api=$key]" />
+ </component>
+ </components>
+ </component>
+
+ <!-- Generate syntax -->
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(starts-with($key,'Overload:') or starts-with($key,'R:'))" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.SyntaxComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <syntax input="/document/reference" output="/document/syntax" />
+ <generators>
+ <generator type="Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ <generator type="Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator" assembly="%DXROOT%\ProductionTools\SyntaxComponents.dll" />
+ </generators>
+ </component>
+ </then>
+ </component>
+
+ <!-- Copy in comments -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
+ <data base="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" recurse="false" files="*.xml" />
+ <data files="%DocumentationFile%" />
+ </index>
+ <copy name="comments" source="*" target="/document/comments" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in reflection data and comments for members -->
+ <component type="Microsoft.Ddue.Tools.ForEachComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <variable expression="/document/reference/elements//element/@api" />
+ <components>
+ <component type="Microsoft.Ddue.Tools.IfThenComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <if condition="not(/document/reference/elements/element[@api=$key]/apidata)" />
+ <then>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="reflection" source="*[not(self::elements)]" target="/document/reference/elements//element[@api=$key]" />
+ </component>
+ </then>
+ </component>
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="comments" source="summary|overloads|inheritdoc" target="/document/reference/elements//element[@api=$key]" />
+ <components>
+ <!-- copy comments for inheritdoc -->
+ <component type="Microsoft.Ddue.Tools.InheritDocumentationComponent" assembly="%DXROOT%\ProductionTools\CopyComponents.dll">
+ <copy name="comments" use="reflection"/>
+ </component>
+ </components>
+ </component>
+ </components>
+ </component>
+
+ <!-- Copy in comments for the member's declaring type. -->
+ <component type="Microsoft.Ddue.Tools.CopyFromIndexComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <copy name="comments" key="string(/document/reference/containers/type/@api)" source="summary" target="/document/reference/containers" />
+ </component>
+
+ <!-- transform -->
+ <component type="Microsoft.Ddue.Tools.TransformComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <transform file="%DXROOT%\Presentation\vs2005\Transforms\main_sandcastle.xsl">
+ <argument key="metadata" value="true" />
+ <argument key="languages">
+ <language label="VisualBasic" name="VisualBasic" style="vb" />
+ <language label="CSharp" name="CSharp" style="cs" />
+ <language label="ManagedCPlusPlus" name="ManagedCPlusPlus" style="cpp" />
+ <!--<language label="JSharp" name="JSharp" style="cs" />
<language label="JScript" name="JScript" style="cs" />-->
- <language label="JavaScript" name="JavaScript" style="vb" />
- </argument>
- </transform>
- </component>
-
- <!-- resolve shared content -->
- <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <content file="%DXROOT%\Presentation\vs2005\content\shared_content.xml" />
- <content file="%DXROOT%\Presentation\vs2005\content\reference_content.xml" />
- <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
- <content file="%DXROOT%\Presentation\vs2005\content\feedback_content.xml" />
- </component>
-
-
- <!-- resolve reference links -->
- <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <targets base="%FxReflectionData%" recurse="true" files="*.xml" type="msdn" />
- <targets files="%ReflectionXmlFile%" type="local" />
- </component>
-
- <!-- save the result -->
- <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
- <save base ="%OutputHtml%" path="concat(/html/head/meta[@name='file']/@content,'.htm')" indent="true" omit-xml-declaration="true" />
- </component>
-
- </components>
- </builder>
- </dduetools>
+ <language label="JavaScript" name="JavaScript" style="cs" />
+ </argument>
+ </transform>
+ </component>
+
+ <!-- resolve shared content -->
+ <component type="Microsoft.Ddue.Tools.SharedContentComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <content file="%DXROOT%\Presentation\vs2005\content\shared_content.xml" />
+ <content file="%DXROOT%\Presentation\vs2005\content\reference_content.xml" />
+ <content file="%DXROOT%\Presentation\shared\content\syntax_content.xml" />
+ <content file="%DXROOT%\Presentation\vs2005\content\feedback_content.xml" />
+ </component>
+
+
+ <!-- resolve reference links -->
+ <component type="Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <targets base="%FxReflectionData%" recurse="true" files="*.xml" type="msdn" />
+ <targets files="%ReflectionXmlFile%" type="local" />
+ </component>
+
+ <!-- save the result -->
+ <component type="Microsoft.Ddue.Tools.SaveComponent" assembly="%DXROOT%\ProductionTools\BuildComponents.dll">
+ <save base ="%OutputHtml%" path="concat(/html/head/meta[@name='file']/@content,'.htm')" indent="true" omit-xml-declaration="true" />
+ </component>
+
+ </components>
+ </builder>
+ </dduetools>
</configuration>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp20.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp20.xsl
new file mode 100644
index 0000000..0cb6330
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp20.xsl
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
+ xmlns:mshelp="http://msdn.microsoft.com/mshelp"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ exclude-result-prefixes="msxsl"
+>
+
+ <xsl:template name="insertMetadata">
+ <xsl:if test="$metadata='true'">
+ <xml>
+ <!-- mshelp metadata -->
+
+ <!-- insert toctitle -->
+ <xsl:if test="normalize-space(/document/metadata/tableOfContentsTitle) and (/document/metadata/tableOfContentsTitle != /document/metadata/title)">
+ <MSHelp:TOCTitle Title="{/document/metadata/tableOfContentsTitle}" />
+ </xsl:if>
+
+ <!-- link index -->
+ <MSHelp:Keyword Index="A" Term="{$key}" />
+
+ <!-- authored K -->
+ <xsl:variable name="docset" select="translate(/document/metadata/attribute[@name='DocSet'][1]/text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz ')"/>
+ <xsl:for-each select="/document/metadata/keyword[@index='K']">
+ <xsl:variable name="nestedKeywordText">
+ <xsl:call-template name="nestedKeywordText"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="not(contains(text(),'[')) and ($docset='avalon' or $docset='wpf' or $docset='wcf' or $docset='windowsforms')">
+ <MSHelp:Keyword Index="K">
+ <includeAttribute name="Term" item="kIndexTermWithTechQualifier">
+ <parameter>
+ <xsl:value-of select="text()"/>
+ </parameter>
+ <parameter>
+ <xsl:value-of select="$docset"/>
+ </parameter>
+ <parameter>
+ <xsl:value-of select="$nestedKeywordText"/>
+ </parameter>
+ </includeAttribute>
+ </MSHelp:Keyword>
+ </xsl:when>
+ <xsl:otherwise>
+ <MSHelp:Keyword Index="K" Term="{concat(text(),$nestedKeywordText)}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <!-- authored S -->
+ <xsl:for-each select="/document/metadata/keyword[@index='S']">
+ <MSHelp:Keyword Index="S">
+ <xsl:attribute name="Term">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='S']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </MSHelp:Keyword>
+ <!-- S index keywords need to be converted to F index keywords -->
+ <MSHelp:Keyword Index="F">
+ <xsl:attribute name="Term">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='S']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </MSHelp:Keyword>
+ </xsl:for-each>
+
+ <!-- authored F -->
+ <xsl:for-each select="/document/metadata/keyword[@index='F']">
+ <MSHelp:Keyword Index="F">
+ <xsl:attribute name="Term">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='F']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </MSHelp:Keyword>
+ </xsl:for-each>
+
+ <!-- authored B -->
+ <xsl:for-each select="/document/metadata/keyword[@index='B']">
+ <MSHelp:Keyword Index="B">
+ <xsl:attribute name="Term">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='B']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </MSHelp:Keyword>
+ </xsl:for-each>
+
+ <!-- Topic version -->
+ <MSHelp:Attr Name="RevisionNumber" Value="{/document/topic/@revisionNumber}" />
+
+ <!-- Asset ID -->
+ <MSHelp:Attr Name="AssetID" Value="{/document/topic/@id}" />
+
+ <!-- Abstract -->
+ <xsl:variable name="abstract" select="string(/document/topic//ddue:para[1])" />
+ <xsl:choose>
+ <xsl:when test="string-length($abstract) &gt; 254">
+ <MSHelp:Attr Name="Abstract" Value="{concat(substring($abstract,1,250), ' ...')}" />
+ </xsl:when>
+ <xsl:when test="string-length($abstract) &gt; 0">
+ <MSHelp:Attr Name="Abstract" Value="{$abstract}" />
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- Autogenerate codeLang attributes based on the snippets -->
+ <xsl:call-template name="mshelpCodelangAttributes">
+ <xsl:with-param name="snippets" select="/document/topic/*//ddue:snippets/ddue:snippet" />
+ </xsl:call-template>
+
+ <!-- authored attributes -->
+ <xsl:for-each select="/document/metadata/attribute">
+ <MSHelp:Attr Name="{@name}" Value="{text()}" />
+ </xsl:for-each>
+
+ <!-- TopicType attribute -->
+ <xsl:for-each select="/document/topic/*[1]">
+ <MSHelp:Attr Name="TopicType">
+ <includeAttribute name="Value" item="TT_{local-name()}"/>
+ </MSHelp:Attr>
+ </xsl:for-each>
+
+ <!-- Locale attribute -->
+ <MSHelp:Attr Name="Locale">
+ <includeAttribute name="Value" item="locale"/>
+ </MSHelp:Attr>
+
+ </xml>
+ </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp30.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp30.xsl
new file mode 100644
index 0000000..54af982
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/conceptualMetadataHelp30.xsl
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+
+ exclude-result-prefixes="msxsl"
+>
+
+ <xsl:template name="insertKeywordsF1Metadata">
+
+ <!-- authored K -->
+ <xsl:variable name="docset" select="translate(/document/metadata/attribute[@name='DocSet'][1]/text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz ')"/>
+ <xsl:for-each select="/document/metadata/keyword[@index='K']">
+ <xsl:variable name="nestedKeywordText">
+ <xsl:call-template name="nestedKeywordText"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="not(contains(text(),'[')) and ($docset='avalon' or $docset='wpf' or $docset='wcf' or $docset='windowsforms')">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="kIndexTermWithTechQualifier">
+ <parameter>
+ <xsl:value-of select="text()"/>
+ </parameter>
+ <parameter>
+ <xsl:value-of select="$docset"/>
+ </parameter>
+ <parameter>
+ <xsl:value-of select="$nestedKeywordText"/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:when>
+ <xsl:otherwise>
+ <meta name="System.Keywords" content="{concat(text(),$nestedKeywordText)}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+
+ <!-- authored F -->
+ <xsl:for-each select="/document/metadata/keyword[@index='F']">
+ <meta name="Microsoft.Help.F1">
+ <xsl:attribute name="content">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='F']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:for-each>
+
+ <!-- authored B -->
+ <xsl:for-each select="/document/metadata/keyword[@index='B']">
+ <meta name="Microsoft.Help.F1">
+ <xsl:attribute name="content">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='B']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:for-each>
+
+ </xsl:template>
+
+ <xsl:template name="insert30Metadata">
+
+ <!-- System.Language -->
+ <meta name="Language">
+ <includeAttribute name="content" item="locale" />
+ </meta>
+
+ <!-- System.Title -->
+ <!-- <title> is set elsewhere (eg, main_conceptual.xsl, utilities_reference.xsl) -->
+
+ <!-- System.Keywords -->
+ <xsl:call-template name="insertKeywordsF1Metadata" />
+
+ <!-- Microsoft.Help.Id -->
+ <meta name="Microsoft.Help.Id" content="{/document/topic/@id}" />
+
+ <!-- Microsoft.Help.Description -->
+ <xsl:variable name="abstract" select="string(/document/topic//ddue:para[1])" />
+ <xsl:if test="$abstract">
+ <meta name="Description">
+ <xsl:attribute name="content">
+ <xsl:call-template name="trimAtPeriod">
+ <xsl:with-param name="string" select="$abstract" />
+ </xsl:call-template>
+ </xsl:attribute>
+ </meta>
+ </xsl:if>
+
+ <!-- Microsoft.Help.TocParent -->
+ <xsl:for-each select="/document/metadata/attribute[@name='TOCParent']">
+ <meta name="Microsoft.Help.TocParent" content="{.}" />
+ <meta name="Microsoft.Help.TocOrder" content="0" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.Product -->
+ <!-- Added by MTPS -->
+
+ <!-- Microsoft.Help.ProductVersion -->
+ <!-- Added by MTPS -->
+
+ <!-- Microsoft.Help.Category -->
+ <xsl:for-each select="/document/metadata/attribute[@name='Category']">
+ <meta name="Microsoft.Help.Category" content="{.}" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.ContentFilter -->
+ <xsl:for-each select="/document/metadata/attribute[@name='ContentFilter']">
+ <meta name="Microsoft.Help.ContentFilter" content="{.}" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.ContentType -->
+ <xsl:variable name="contentTypeDocStudio">
+ <xsl:variable name="lookupValue">
+ <xsl:value-of select="local-name(/document/topic/*[1])"/>
+ </xsl:variable>
+ <xsl:value-of select="msxsl:node-set($topicTypes)/topic[@name = $lookupValue]/text()"/>
+ </xsl:variable>
+
+ <xsl:variable name="contentTypeTopicType">
+ <xsl:variable name="lookupValue">
+ <xsl:value-of select="translate(/document/metadata/topicType/@id,
+ 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
+ </xsl:variable>
+ <xsl:value-of select="msxsl:node-set($topicTypes)/topic[@guid = $lookupValue]/text()"/>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$contentTypeDocStudio">
+ <meta name="Microsoft.Help.ContentType" content="{$contentTypeDocStudio}" />
+ </xsl:when>
+ <xsl:when test="$contentTypeTopicType">
+ <meta name="Microsoft.Help.ContentType" content="{$contentTypeTopicType}" />
+ </xsl:when>
+ </xsl:choose>
+
+ <!-- Microsoft.Package.Book -->
+ <xsl:variable name="Book" select="/document/metadata/attribute[@name='Book']/text()" />
+ <xsl:if test="$Book">
+ <meta name="Microsoft.Package.Book" content="{$Book}" />
+ </xsl:if>
+
+ <!-- Source -->
+ <xsl:for-each select="/document/metadata/attribute[@name='Source']">
+ <meta name="Source" content="{.}" />
+ </xsl:for-each>
+
+ </xsl:template>
+
+
+ <xsl:variable name="topicTypes">
+ <topic guid="EF7DDB37-8ED3-4DFA-B38D-5A3CC1906034" name="">Concepts</topic>
+ <topic guid="1FE70836-AA7D-4515-B54B-E10C4B516E50" name="developerConceptualDocument">Concepts</topic>
+ <topic guid="B137C930-7BF7-48A2-A329-3ADCAEF8868E" name="developerOrientationDocument">Concepts</topic>
+ <topic guid="68F07632-C4C5-4645-8DFA-AC87DCB4BD54" name="developerSDKTechnologyOverviewArchitectureDocument">Concepts</topic>
+ <topic guid="CDB8C120-888F-447B-8AF8-F9540562E7CA" name="developerSDKTechnologyOverviewOrientationDocument">Concepts</topic>
+ <topic guid="356C57C4-384D-4AF2-A637-FDD6F088A033" name="developerSDKTechnologyOverviewScenariosDocument">Concepts</topic>
+ <topic guid="19F1BB0E-F32A-4D5F-80A9-211D92A8A715" name="developerSDKTechnologyOverviewTechnologySummaryDocument">Concepts</topic>
+ <topic guid="56DB00EC-28BA-4C0D-8694-28E8B244E236" name="developerWhitePaperDocument">Concepts</topic>
+ <topic guid="B137C930-7BF7-48A2-A329-3ADCAEF8868E" name="developerOrientationDocument">Concepts</topic>
+
+ <topic guid="DAC3A6A0-C863-4E5B-8F65-79EFC6A4BA09" name="developerHowToDocument">How To</topic>
+ <topic guid="4779DD54-5D0C-4CC3-9DB3-BF1C90B721B3" name="developerWalkthroughDocument">How To</topic>
+
+ <topic guid="A635375F-98C2-4241-94E7-E427B47C20B6" name="developerErrorMessageDocument">Reference</topic>
+ <topic guid="95DADC4C-A2A6-447A-AA36-B6BE3A4F8DEC" name="developerReferenceWithSyntaxDocument">Reference</topic>
+ <topic guid="F9205737-4DEC-4A58-AA69-0E621B1236BD" name="developerReferenceWithoutSyntaxDocument">Reference</topic>
+ <topic guid="38C8E0D1-D601-4DBA-AE1B-5BEC16CD9B01" name="developerTroubleshootingDocument">Reference</topic>
+ <topic guid="B8ED9F21-39A4-4967-928D-160CD2ED9DCE" name="developerUIReferenceDocument">Reference</topic>
+ <topic guid="3272D745-2FFC-48C4-9E9D-CF2B2B784D5F" name="developerXmlReference">Reference</topic>
+ <topic guid="A689E19C-2687-4881-8CE1-652FF60CF46C" name="developerGlossaryDocument">Reference</topic>
+
+ <topic guid="069EFD88-412D-4E2F-8848-2D5C3AD56BDE" name="developerSampleDocument">Samples</topic>
+ <topic guid="4BBAAF90-0E5F-4C86-9D31-A5CAEE35A416" name="developerSDKTechnologyOverviewCodeDirectoryDocument">Samples</topic>
+ <topic guid="4A273212-0AC8-4D72-8349-EC11CD2FF8CD" name="">Samples</topic>
+ </xsl:variable>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/globalTemplates.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/globalTemplates.xsl
index c878e22..a6cde9a 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/globalTemplates.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/globalTemplates.xsl
@@ -174,7 +174,8 @@
<tr>
<th>
<xsl:variable name="codeLangLC" select="translate($codeLang,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz ')"/>
- <xsl:if test="$codeLangLC='visualbasic' or $codeLangLC='csharp' or $codeLangLC='managedcplusplus' or $codeLangLC='jsharp' or $codeLangLC='jscript'">
+ <!-- Added JavaScript to look for AJAX snippets as JScript represents javascript snippets-->
+ <xsl:if test="$codeLangLC='visualbasic' or $codeLangLC='csharp' or $codeLangLC='managedcplusplus' or $codeLangLC='jsharp' or $codeLangLC='jscript' or $codeLangLC='javascript' or $codeLangLC='fsharp' ">
<include item="{$codeLang}"/>
</xsl:if>
<xsl:text>&#xa0;</xsl:text>
@@ -182,6 +183,7 @@
<th>
<span class="copyCode" onclick="CopyCode(this)" onkeypress="CopyCode_CheckKey(this, event)" onmouseover="ChangeCopyCodeIcon(this)" onmouseout="ChangeCopyCodeIcon(this)" tabindex="0">
<img class="copyCodeImage" name="ccImage" align="absmiddle">
+ <includeAttribute name="alt" item="copyImage" />
<includeAttribute name="title" item="copyImage" />
<includeAttribute name="src" item="iconPath">
<parameter>copycode.gif</parameter>
@@ -202,11 +204,6 @@
</div>
</xsl:template>
-
- <!-- sireeshm: fix bug 361746 - use copy-of, so that span class="keyword", "literal" and "comment" nodes are copied to preserve code colorization in snippets -->
- <xsl:template match="ddue:span[@class='keyword' or @class='literal' or @class='comment']">
- <xsl:copy-of select="."/>
- </xsl:template>
<xsl:template name="nonScrollingRegionTypeLinks">
<include item="nonScrollingTypeLinkText">
@@ -224,4 +221,107 @@
</include>
</xsl:template>
+ <xsl:template name="mshelpCodelangAttributes">
+ <xsl:param name="snippets" />
+ <xsl:for-each select="$snippets">
+
+ <xsl:if test="not(@language=preceding::*/@language)">
+ <xsl:variable name="codeLang">
+ <xsl:choose>
+ <xsl:when test="@language = 'VBScript' or @language = 'vbs'">
+ <xsl:text>VBScript</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'VisualBasic' or @language = 'vb' or @language = 'vb#' or @language = 'VB' or @language = 'kbLangVB'" >
+ <xsl:text>kbLangVB</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'CSharp' or @language = 'c#' or @language = 'cs' or @language = 'C#'" >
+ <xsl:text>CSharp</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'ManagedCPlusPlus' or @language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++' or @language = 'kbLangCPP'" >
+ <xsl:text>kbLangCPP</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'JSharp' or @language = 'j#' or @language = 'jsharp' or @language = 'VJ#'">
+ <xsl:text>VJ#</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'JScript' or @language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript' or @language = 'kbJScript'">
+ <xsl:text>kbJScript</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'XAML' or @language = 'xaml'">
+ <xsl:text>XAML</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'JavaScript' or @language = 'javascript'">
+ <xsl:text>JavaScript</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'xml'">
+ <xsl:text>xml</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'html'">
+ <xsl:text>html</xsl:text>
+ </xsl:when>
+ <xsl:when test="@language = 'vb-c#'">
+ <xsl:text>visualbasicANDcsharp</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>other</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$codeLang='other'" />
+ <!-- If $codeLang is already authored, then do nothing -->
+ <xsl:when test="/document/metadata/attribute[@name='codelang']/text() = $codeLang" />
+ <xsl:otherwise>
+ <xsl:call-template name="codeLang">
+ <xsl:with-param name="codeLang" select="$codeLang" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="codeLang">
+ <xsl:param name="codeLang" />
+ <MSHelp:Attr Name="codelang" Value="{$codeLang}" />
+ </xsl:template>
+
+ <xsl:template name="trimAtPeriod">
+ <xsl:param name="string" />
+
+ <xsl:variable name="trimmedString" select="substring(normalize-space($string), 1, 256)" />
+ <xsl:choose>
+ <xsl:when test="normalize-space($string) != $trimmedString">
+ <xsl:choose>
+ <xsl:when test="not(contains($trimmedString, '.'))">
+ <xsl:value-of select="$trimmedString"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="substringAndLastPeriod">
+ <xsl:with-param name="string" select="$trimmedString" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="normalize-space($string)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="substringAndLastPeriod">
+ <xsl:param name="string" />
+
+ <xsl:if test="contains($string, '.')">
+ <xsl:variable name="after" select="substring-after($string, '.')" />
+ <xsl:value-of select="concat(substring-before($string, '.'),'.')" />
+ <xsl:if test="contains($after, '.')">
+ <xsl:call-template name="substringAndLastPeriod">
+ <xsl:with-param name="string" select="$after" />
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+
</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/htmlBody.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/htmlBody.xsl
index 099857d..b12b082 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/htmlBody.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/htmlBody.xsl
@@ -110,27 +110,32 @@
<!--all members only -->
<xsl:if test="$subgroup='members'">
- <xsl:if test="/document/reference/elements/element/apidata[@subgroup='constructor']">
+ <xsl:if test="/document/reference/elements/element[apidata[@subgroup='constructor']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<!-- add a link to the member list section for this subgroup -->
<xsl:call-template name="memberTableLink">
<xsl:with-param name="headerGroup">constructor</xsl:with-param>
</xsl:call-template>
</xsl:if>
-
- <!-- method subgroup includes operators -->
- <xsl:if test="/document/reference/elements/element/apidata[@subgroup='method']">
+
+ <xsl:if test="/document/reference/elements/element[apidata[@subgroup='method']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberTableLink">
<xsl:with-param name="headerGroup">method</xsl:with-param>
</xsl:call-template>
</xsl:if>
- <xsl:if test="/document/reference/elements/element/apidata[@subgroup='field']">
+ <xsl:if test="/document/reference/elements/element/apidata[@subsubgroup='operator']">
+ <xsl:call-template name="memberTableLink">
+ <xsl:with-param name="headerGroup">operator</xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+
+ <xsl:if test="/document/reference/elements/element[apidata[@subgroup='field']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberTableLink">
<xsl:with-param name="headerGroup">field</xsl:with-param>
</xsl:call-template>
</xsl:if>
- <xsl:if test="/document/reference/elements/element/apidata[@subgroup='property' and not(@subsubgroup)]">
+ <xsl:if test="/document/reference/elements/element[apidata[@subgroup='property' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberTableLink">
<xsl:with-param name="headerGroup">property</xsl:with-param>
</xsl:call-template>
@@ -142,7 +147,7 @@
</xsl:call-template>
</xsl:if>
- <xsl:if test="/document/reference/elements/element/apidata[@subgroup='event' and not(@subsubgroup)]">
+ <xsl:if test="/document/reference/elements/element[apidata[@subgroup='event' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberTableLink">
<xsl:with-param name="headerGroup">event</xsl:with-param>
</xsl:call-template>
@@ -203,7 +208,7 @@
<xsl:template name="bodyHeaderTopTable">
<xsl:variable name="showDevlangsFilter" select="boolean(($languages != 'false') and (count($languages/language) &gt; 0))"/>
<xsl:variable name="showMemberOptionsFilter" select="boolean($group='list' and $subgroup!='DerivedTypeList')"/>
- <xsl:variable name="showMemberFrameworksFilter" select="boolean($group='list' and $subgroup!='DerivedTypeList' and /document/reference/elements//element/versions/versions)"/>
+ <xsl:variable name="showMemberFrameworksFilter" select="boolean($group='list' and $subgroup!='DerivedTypeList' and /document/reference/elements//element[count(versions/versions) &gt; 1])"/>
<table id="topTable" cellspacing="0" cellpadding="0">
<tr>
<td>
@@ -448,12 +453,14 @@ copyHoverImage - overview (not namespace); list (only overload lists ctor, metho
<includeAttribute name="src" item="iconPath">
<parameter>collapse_all.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="collapseImage" />
<includeAttribute name="title" item="collapseImage" />
</img>
<img id="expandImage" style="display:none; height:0; width:0;">
<includeAttribute name="src" item="iconPath">
<parameter>expand_all.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="expandImage" />
<includeAttribute name="title" item="expandImage" />
</img>
<img id="collapseAllImage" style="display:none; height:0; width:0;">
@@ -480,12 +487,14 @@ copyHoverImage - overview (not namespace); list (only overload lists ctor, metho
<includeAttribute name="src" item="iconPath">
<parameter>copycode.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="copyImage" />
<includeAttribute name="title" item="copyImage" />
</img>
<img id="copyHoverImage" style="display:none; height:0; width:0;">
<includeAttribute name="src" item="iconPath">
<parameter>copycodeHighlight.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="copyHoverImage" />
<includeAttribute name="title" item="copyHoverImage" />
</img>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/main_conceptual.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/main_conceptual.xsl
index 41daf9c..427d8be 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/main_conceptual.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/main_conceptual.xsl
@@ -9,8 +9,12 @@
<xsl:output method="xml" indent="no" encoding="utf-8" />
+ <xsl:param name="changeHistoryOptions" />
<xsl:include href="htmlBody.xsl" />
<xsl:include href="utilities_dduexml.xsl" />
+ <xsl:include href="seeAlsoSection.xsl" />
+ <xsl:include href="conceptualMetadataHelp30.xsl"/>
+ <xsl:include href="conceptualMetadataHelp20.xsl"/>
<xsl:variable name="hasSeeAlsoSection" select="boolean(count(/document/topic/*/ddue:relatedTopics/*[local-name()!='sampleRef']) > 0)"/>
<xsl:variable name="examplesSection" select="boolean(string-length(/document/topic/*/ddue:codeExample[normalize-space(.)]) > 0)"/>
@@ -31,9 +35,11 @@
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"/>
<META NAME="save" CONTENT="history"/>
+ <xsl:call-template name="insertNoIndexNoFollow" />
<title>
<xsl:call-template name="topicTitlePlain"/>
</title>
+ <xsl:call-template name="insert30Metadata" />
<xsl:call-template name="insertStylesheets" />
<xsl:call-template name="insertScripts" />
<xsl:call-template name="insertMetadata" />
@@ -47,6 +53,12 @@
<!-- document head -->
+ <xsl:template name="insertNoIndexNoFollow">
+ <xsl:if test="/document/metadata/attribute[@name='NoSearch']">
+ <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW" />
+ </xsl:if>
+ </xsl:template>
+
<xsl:template name="insertStylesheets">
<link rel="stylesheet" type="text/css" href="../styles/presentation.css" />
<!-- make mshelp links work -->
@@ -100,151 +112,6 @@
</xsl:template>
- <xsl:template name="insertMetadata">
- <xsl:if test="$metadata='true'">
- <xml>
- <!-- mshelp metadata -->
-
- <!-- insert toctitle -->
- <xsl:if test="normalize-space(/document/metadata/tableOfContentsTitle) and (/document/metadata/tableOfContentsTitle != /document/metadata/title)">
- <MSHelp:TOCTitle Title="{/document/metadata/tableOfContentsTitle}" />
- </xsl:if>
-
- <!-- link index -->
- <MSHelp:Keyword Index="A" Term="{$key}" />
-
- <!-- authored K -->
- <xsl:variable name="docset" select="translate(/document/metadata/attribute[@name='DocSet'][1]/text(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz ')"/>
- <xsl:for-each select="/document/metadata/keyword[@index='K']">
- <xsl:variable name="nestedKeywordText">
- <xsl:call-template name="nestedKeywordText"/>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="not(contains(text(),'[')) and ($docset='avalon' or $docset='wpf' or $docset='wcf' or $docset='windowsforms')">
- <MSHelp:Keyword Index="K">
- <includeAttribute name="Term" item="kIndexTermWithTechQualifier">
- <parameter>
- <xsl:value-of select="text()"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$docset"/>
- </parameter>
- <parameter>
- <xsl:value-of select="$nestedKeywordText"/>
- </parameter>
- </includeAttribute>
- </MSHelp:Keyword>
- </xsl:when>
- <xsl:otherwise>
- <MSHelp:Keyword Index="K" Term="{concat(text(),$nestedKeywordText)}" />
- </xsl:otherwise>
- </xsl:choose>
- <!--
- <MSHelp:Keyword Index="K">
- <xsl:choose>
- <xsl:when test="normalize-space($docset)='' or contains(text(),'[')">
- <xsl:attribute name="Term">
- <xsl:value-of select="concat(text(),$nestedKeywordText)"/>
- </xsl:attribute>
- </xsl:when>
- <xsl:otherwise>
- <includeAttribute name="Term" item="kIndexTermWithTechQualifier">
- <parameter><xsl:value-of select="text()"/></parameter>
- <parameter><xsl:value-of select="$docset"/></parameter>
- <parameter><xsl:value-of select="$nestedKeywordText"/></parameter>
- </includeAttribute>
- </xsl:otherwise>
- </xsl:choose>
- </MSHelp:Keyword>
- -->
- </xsl:for-each>
-
- <!-- authored S -->
- <xsl:for-each select="/document/metadata/keyword[@index='S']">
- <MSHelp:Keyword Index="S">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='S']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- <!-- S index keywords need to be converted to F index keywords -->
- <MSHelp:Keyword Index="F">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='S']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored F -->
- <xsl:for-each select="/document/metadata/keyword[@index='F']">
- <MSHelp:Keyword Index="F">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='F']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- authored B -->
- <xsl:for-each select="/document/metadata/keyword[@index='B']">
- <MSHelp:Keyword Index="B">
- <xsl:attribute name="Term">
- <xsl:value-of select="text()" />
- <xsl:for-each select="keyword[@index='B']">
- <xsl:text>, </xsl:text>
- <xsl:value-of select="text()"/>
- </xsl:for-each>
- </xsl:attribute>
- </MSHelp:Keyword>
- </xsl:for-each>
-
- <!-- Topic version -->
- <MSHelp:Attr Name="RevisionNumber" Value="{/document/topic/@revisionNumber}" />
-
- <!-- Asset ID -->
- <MSHelp:Attr Name="AssetID" Value="{/document/topic/@id}" />
-
- <!-- Abstract -->
- <xsl:variable name="abstract" select="string(/document/topic//ddue:para[1])" />
- <xsl:choose>
- <xsl:when test="string-length($abstract) &gt; 254">
- <MSHelp:Attr Name="Abstract" Value="{concat(substring($abstract,1,250), ' ...')}" />
- </xsl:when>
- <xsl:when test="string-length($abstract) &gt; 0">
- <MSHelp:Attr Name="Abstract" Value="{$abstract}" />
- </xsl:when>
- </xsl:choose>
-
- <!-- authored attributes -->
- <xsl:for-each select="/document/metadata/attribute">
- <MSHelp:Attr Name="{@name}" Value="{text()}" />
- </xsl:for-each>
-
- <!-- TopicType attribute -->
- <xsl:for-each select="/document/topic/*[1]">
- <MSHelp:Attr Name="TopicType">
- <includeAttribute name="Value" item="TT_{local-name()}"/>
- </MSHelp:Attr>
- </xsl:for-each>
-
- <!-- Locale attribute -->
- <MSHelp:Attr Name="Locale">
- <includeAttribute name="Value" item="locale"/>
- </MSHelp:Attr>
-
- </xml>
- </xsl:if>
- </xsl:template>
<xsl:template name="nestedKeywordText">
<xsl:for-each select="keyword[@index='K']">
@@ -286,10 +153,11 @@
<div id="mainSection">
<div id="mainBody">
- <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()">
- <include item="header" />
- </div>
- <!--<xsl:call-template name="head" />-->
+ <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()"/>
+
+ <!-- 'header' shared content item is used to show optional boilerplate at the top of the topic's scrolling region, e.g. pre-release boilerplate -->
+ <include item="header" />
+
<xsl:call-template name="body" />
</div>
<xsl:call-template name="foot" />
@@ -297,12 +165,17 @@
</xsl:template>
- <!--<xsl:template name="head">
- <include item="header" />
- </xsl:template>-->
-
<xsl:template name="body">
+ <!-- freshness date -->
+ <xsl:call-template name="writeFreshnessDate">
+ <xsl:with-param name="ChangedHistoryDate" select="/document/topic/*//ddue:section[ddue:title = 'Change History']/ddue:content/ddue:table/ddue:row[1]/ddue:entry[1] |
+ /document/topic/*/ddue:changeHistory/ddue:content/ddue:table/ddue:row[1]/ddue:entry[1]" />
+ </xsl:call-template>
+
<xsl:apply-templates select="topic" />
+
+ <!-- changed table section -->
+ <xsl:call-template name="writeChangeHistorySection" />
</xsl:template>
<!-- sections that behave differently in conceptual and reference -->
@@ -332,13 +205,30 @@
<xsl:template match="ddue:returnValue">
<xsl:if test="normalize-space(.)">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'returnValue'"/>
- <xsl:with-param name="title"><include item="returnValueTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <xsl:apply-templates />
- </xsl:with-param>
- </xsl:call-template>
+ <xsl:choose>
+ <xsl:when test="(normalize-space(ddue:content)='') and ddue:sections/ddue:section[ddue:title='Property Value']">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'returnValue'"/>
+ <xsl:with-param name="title">
+ <include item="propertyValueTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:apply-templates select="ddue:sections/ddue:section[ddue:title='Property Value']/*" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'returnValue'"/>
+ <xsl:with-param name="title">
+ <include item="returnValueTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:apply-templates />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:if>
</xsl:template>
@@ -366,76 +256,20 @@
</xsl:if>
</xsl:template>
- <xsl:template match="ddue:relatedTopics">
+ <xsl:template match="ddue:relatedTopics">
<xsl:if test="$hasSeeAlsoSection">
- <xsl:call-template name="section">
+ <xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'seeAlso'"/>
- <xsl:with-param name="title"><include item="relatedTopicsTitle" /></xsl:with-param>
+ <xsl:with-param name="title">
+ <include item="relatedTopicsTitle" />
+ </xsl:with-param>
<xsl:with-param name="content">
-
- <!-- Concepts sub-section -->
- <xsl:if test="normalize-space(ddue:link) or normalize-space(ddue:dynamicLink[@type='inline'])">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoConcepts"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'link' or (name() = 'dynamicLink' and @type = 'inline') or (name() = 'legacyLink' and not(starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Reference sub-section -->
- <xsl:if test="normalize-space(ddue:codeEntityReference)">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoReference"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'codeEntityReference' or (name() = 'legacyLink' and (starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Other Resources sub-section -->
- <xsl:if test="ddue:externalLink">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoOtherResources"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="*">
- <xsl:if test="name() = 'externalLink'">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:with-param>
- </xsl:call-template>
+ <xsl:apply-templates select="/document/topic/*/ddue:relatedTopics" mode="seeAlso" />
+ </xsl:with-param>
+ </xsl:call-template>
</xsl:if>
- </xsl:template>
-
+ </xsl:template>
+
<xsl:template match="ddue:codeExample">
<!-- create Example section for the first codeExample node -->
<xsl:if test="not(preceding-sibling::ddue:codeExample) and ../ddue:codeExample[normalize-space(.)!='']">
@@ -475,6 +309,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>footer.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="footerImage" />
<includeAttribute name="title" item="footerImage" />
</img>
</div>
@@ -544,7 +379,7 @@
<xsl:if test="starts-with($outlineType,'toplevel') and //ddue:relatedTopics[normalize-space(.)!='']">
<li>
<A>
- <xsl:attribute name="HREF">#seeAlsoSection</xsl:attribute>
+ <xsl:attribute name="HREF">#seeAlsoToggle</xsl:attribute>
<include item="RelatedTopicsLinkText"/>
</A>
</li>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/main_reference.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/main_reference.xsl
index b2a3f63..970ac6d 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/main_reference.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/main_reference.xsl
@@ -7,11 +7,17 @@
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
>
- <!-- stuff specific to comments authored in DDUEXML -->
+ <xsl:param name="omitAptcaBoilerplate"/>
+ <xsl:param name="changeHistoryOptions" />
+ <xsl:param name="omitXmlnsBoilerplate" select="'false'" />
+ <xsl:param name="omitVersionInformation" select="'false'" />
+
+ <!-- stuff specific to comments authored in DDUEXML -->
<xsl:include href="utilities_reference.xsl" />
<xsl:include href="utilities_dduexml.xsl" />
<xsl:include href="htmlBody.xsl"/>
+ <xsl:include href="seeAlsoSection.xsl"/>
<xsl:variable name="summary" select="normalize-space(/document/comments/ddue:dduexml/ddue:summary)" />
@@ -26,18 +32,65 @@
(count(/document/comments/ddue:dduexml/ddue:relatedTopics/*) > 0) or
($group='type' or $group='member' or $group='list')
)"/>
- <xsl:variable name="examplesSection" select="boolean(string-length(/document/comments/ddue:dduexml/ddue:codeExamples[normalize-space(.)]) > 0)"/>
+ <xsl:variable name="examplesSection" select="boolean(string-length(/document/comments/ddue:dduexml/ddue:codeExamples[normalize-space(.)]) > 0) and not($securityCriticalSection)"/>
<xsl:variable name="languageFilterSection" select="boolean(string-length(/document/comments/ddue:dduexml/ddue:codeExamples[normalize-space(.)]) > 0)" />
+ <xsl:variable name="securityCriticalSection"
+ select="boolean(
+ (/document/reference/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and
+ not(/document/reference/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute'])) or
+ (/document/reference/containers/type/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and
+ not(/document/reference/containers/type/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute'])) or
+ ($api-subgroup='property' and
+ (((/document/reference/getter and (/document/reference/getter/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/getter/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))) and
+ (/document/reference/setter and (/document/reference/setter/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/setter/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute'])))) or
+ ((/document/reference/getter and (/document/reference/getter/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/getter/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))) and not(/document/reference/setter)) or
+ (not(/document/reference/getter) and (/document/reference/setter and (/document/reference/setter/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/setter/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))))
+ )) or
+ ($api-subgroup='event' and
+ (((/document/reference/adder and (/document/reference/adder/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/adder/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))) and
+ (/document/reference/remover and (/document/reference/remover/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/remover/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute'])))) or
+ ((/document/reference/adder and (/document/reference/adder/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/adder/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))) and not(/document/reference/remover)) or
+ (not(/document/reference/adder) and (/document/reference/remover and (/document/reference/remover/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and not(/document/reference/remover/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))))
+ ))
+ )" />
+
<xsl:template name="body">
+ <!-- freshness date -->
+ <xsl:call-template name="writeFreshnessDate">
+ <xsl:with-param name="ChangedHistoryDate" select="/document/comments/ddue:dduexml//ddue:section[ddue:title = 'Change History']/ddue:content/ddue:table/ddue:row[1]/ddue:entry[1] |
+ /document/comments/ddue:dduexml/ddue:changeHistory/ddue:content/ddue:table/ddue:row[1]/ddue:entry[1]"/>
+ </xsl:call-template>
<!--internalOnly boilerplate -->
+ <xsl:if test="not($securityCriticalSection)">
<xsl:call-template name="internalOnly"/>
+ </xsl:if>
<!-- obsolete boilerplate -->
<xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
<xsl:call-template name="obsoleteSection" />
</xsl:if>
+ <!-- SecurityCritical boilerplate -->
+ <xsl:if test="$securityCriticalSection">
+ <xsl:choose>
+ <xsl:when test="boolean($api-group='type')">
+ <include item="typeSecurityCriticalBoilerplate" />
+ </xsl:when>
+ <xsl:when test="boolean($api-group='member')">
+ <xsl:choose>
+ <xsl:when test="(/document/reference/containers/type/attributes/attribute/type[@api='T:System.Security.SecurityCriticalAttribute'] and
+ not(/document/reference/containers/type/attributes/attribute/type[@api='T:System.Security.SecurityTreatAsSafeAttribute']))">
+ <include item="typeSecurityCriticalBoilerplate" />
+ </xsl:when>
+ <xsl:otherwise>
+ <include item="memberSecurityCriticalBoilerplate" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:if>
+
<!-- summary -->
<!-- useBase boilerplate -->
<xsl:if test="/document/comments/ddue:dduexml/ddue:useBase and /document/reference/overrides/member">
@@ -49,7 +102,10 @@
</xsl:if>
<xsl:choose>
<xsl:when test="normalize-space(/document/comments/ddue:dduexml/ddue:summary[1]) != ''">
- <span data="authoredSummary">
+ <span sdata="authoredSummary">
+ <xsl:if test="$securityCriticalSection">
+ <p><include item="securityCritical" /></p>
+ </xsl:if>
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:summary[1]" />
</span>
</xsl:when>
@@ -70,7 +126,7 @@
<xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.FlagsAttribute']">
<p>
<include item="flagsSummary">
- <parameter><referenceLink target="{/document/reference/attributes/attribute/type/@api}" /></parameter>
+ <parameter><referenceLink target="T:System.FlagsAttribute" /></parameter>
</include>
</p>
</xsl:if>
@@ -142,22 +198,30 @@
</xsl:when>
</xsl:choose>
<!-- exceptions -->
+ <xsl:if test="not($securityCriticalSection)">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:exceptions" />
+ </xsl:if>
<!-- remarks -->
- <xsl:if test="not($group='namespace')">
+ <xsl:if test="not($group='namespace') and not($securityCriticalSection)">
<xsl:choose>
- <xsl:when test="normalize-space(/document/comments/ddue:dduexml/ddue:remarks[1])">
- <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:remarks[1]" />
- </xsl:when>
- <xsl:when test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:call-template name="hostProtectionSection" />
+ <xsl:when test="/document/comments/ddue:dduexml/ddue:remarks">
+ <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:remarks" />
</xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="WriteRemarksSection">
+ <xsl:with-param name="node" select="document/comments/ddue:dduexml" />
+ </xsl:call-template>
+ </xsl:otherwise>
</xsl:choose>
</xsl:if>
<!-- example -->
+ <xsl:if test="not($securityCriticalSection)">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:codeExamples" />
+ </xsl:if>
<!-- permissions -->
+ <xsl:if test="not($securityCriticalSection)">
<xsl:call-template name="permissionsSection"/>
+ </xsl:if>
<!-- inheritance -->
<xsl:apply-templates select="/document/reference/family" />
<!-- other comment sections -->
@@ -173,6 +237,9 @@
<!-- see also -->
<xsl:call-template name="seeAlsoSection"/>
+ <!-- changed table section -->
+ <xsl:call-template name="writeChangeHistorySection" />
+
</xsl:template>
<xsl:template name="obsoleteSection">
@@ -204,7 +271,7 @@
<xsl:param name="name" />
<xsl:choose>
<xsl:when test="normalize-space(/document/comments/ddue:dduexml/ddue:parameters[1]/ddue:parameter) != ''">
- <span data="authoredParameterSummary">
+ <span sdata="authoredParameterSummary">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:parameters[1]/ddue:parameter[string(ddue:parameterReference)=$name]/ddue:content" />
</span>
</xsl:when>
@@ -217,7 +284,7 @@
<xsl:template name="getReturnsDescription">
<xsl:choose>
<xsl:when test="normalize-space(/document/comments/ddue:dduexml/ddue:returnValue[1]) != ''">
- <span data="authoredValueSummary">
+ <span sdata="authoredValueSummary">
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:returnValue[1]" />
</span>
</xsl:when>
@@ -228,6 +295,9 @@
</xsl:template>
<xsl:template match="returns">
+ <xsl:choose>
+ <xsl:when test="$api-subgroup='field' and normalize-space(/document/comments/ddue:dduexml/ddue:returnValue[1]) = '' and normalize-space(/document/comments/ddue:dduexml/ddue:returnValue[2]) = ''"/>
+ <xsl:otherwise>
<div id="returns">
<xsl:call-template name="subSection">
<xsl:with-param name="title">
@@ -252,6 +322,8 @@
</xsl:with-param>
</xsl:call-template>
</div>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
<xsl:template match="templates">
<div id="genericParameters">
@@ -260,12 +332,19 @@
<xsl:with-param name="content">
<xsl:for-each select="template">
<xsl:variable name="parameterName" select="@name" />
+ <xsl:variable name="contravariant">
+ <xsl:if test="variance/@contravariant='true'"><include item="inKeyword"/></xsl:if>
+ </xsl:variable>
+ <xsl:variable name="covariant">
+ <xsl:if test="variance/@covariant='true'"><include item="outKeyword" /></xsl:if>
+ </xsl:variable>
<dl paramName="{$parameterName}">
<dt>
- <span class="parameter"><xsl:value-of select="$parameterName"/></span>
+ <xsl:copy-of select="$contravariant"/><xsl:copy-of select="$covariant" /><span class="parameter"><xsl:value-of select="$parameterName"/></span>
</dt>
<dd>
<xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:genericParameters/ddue:genericParameter[string(ddue:parameterReference)=$parameterName]/ddue:content" />
+ <xsl:if test="variance"><p><xsl:if test="variance/@contravariant='true'"><include item="contravariant" /></xsl:if><xsl:if test="variance/@covariant='true'"><include item="covariant" /></xsl:if><include item="variance" /></p></xsl:if>
</dd>
</dl>
</xsl:for-each>
@@ -277,7 +356,7 @@
<xsl:template name="getElementDescription">
<xsl:choose>
<xsl:when test="normalize-space(ddue:summary[1]) != ''">
- <span data="memberAuthoredSummary">
+ <span sdata="memberAuthoredSummary">
<xsl:apply-templates select="ddue:summary[1]/ddue:para/node()" />
</span>
</xsl:when>
@@ -326,6 +405,11 @@
<div id="syntaxCodeBlocks" class="code">
<xsl:call-template name="syntaxBlocks" />
</div>
+ <xsl:apply-templates select="/document/syntax/div[@codeLanguage=XAML]"/>
+
+ <!-- Show the authored XAML Values section, if any. -->
+ <xsl:call-template name="showXamlValuesSection"/>
+
<!-- parameters & return value -->
<xsl:apply-templates select="/document/reference/templates" />
<xsl:apply-templates select="/document/reference/parameters" />
@@ -392,7 +476,7 @@
<xsl:template name="permissionsSection">
<!-- the containers/library/noAptca is added to reflection data by the ApplyVsDocModel transform -->
- <xsl:variable name="showAptcaBoilerplate" select="boolean(/document/reference/containers/library/noAptca)"/>
+ <xsl:variable name="showAptcaBoilerplate" select="boolean(/document/reference/containers/library/noAptca and $omitAptcaBoilerplate!='true')"/>
<xsl:if test="/document/comments/ddue:dduexml/ddue:permissions[normalize-space(.)] or $showAptcaBoilerplate">
<xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'permissions'" />
@@ -434,56 +518,10 @@
<xsl:call-template name="memberIntroBoilerplate"/>
</xsl:template>
- <xsl:template name="mshelpCodelangAttributes">
-
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/ddue:snippets/ddue:snippet">
-
- <xsl:if test="not(@language=preceding::*/@language)">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'VBScript' or @language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'VisualBasic' or @language = 'vb' or @language = 'vb#' or @language = 'VB' or @language = 'kbLangVB'" >
- <xsl:text>kbLangVB</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'CSharp' or @language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'ManagedCPlusPlus' or @language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++' or @language = 'kbLangCPP'" >
- <xsl:text>kbLangCPP</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JSharp' or @language = 'j#' or @language = 'jsharp' or @language = 'VJ#'">
- <xsl:text>VJ#</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JScript' or @language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript' or @language = 'kbJScript'">
- <xsl:text>kbJScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xml</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$codeLang='other'" />
- <xsl:otherwise>
- <xsl:call-template name="codeLang">
- <xsl:with-param name="codeLang" select="$codeLang" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
-
- </xsl:for-each>
+ <xsl:template name="codelangAttributes">
+ <xsl:call-template name="mshelpCodelangAttributes">
+ <xsl:with-param name="snippets" select="/document/comments/ddue:dduexml/ddue:codeExamples/ddue:codeExample/ddue:legacy/ddue:content/ddue:snippets/ddue:snippet" />
+ </xsl:call-template>
</xsl:template>
<xsl:template match="ddue:codeEntityReference" mode="abstract">
@@ -492,20 +530,6 @@
</xsl:call-template>
</xsl:template>
- <xsl:template name="hostProtectionSection">
- <xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'remarks'"/>
- <xsl:with-param name="title">
- <include item="remarksTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="hostProtectionContent" />
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
<!-- Footer stuff -->
<xsl:template name="foot">
@@ -515,6 +539,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>footer.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="footerImage" />
<includeAttribute name="title" item="footerImage" />
</img>
</div>
@@ -535,5 +560,37 @@
</include>
</div>
</xsl:template>
-
+
+ <xsl:template name="seeAlsoSection">
+
+ <xsl:if test="$hasSeeAlsoSection">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'seeAlso'"/>
+ <xsl:with-param name="title">
+ <include item="relatedTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:choose>
+ <xsl:when test="count(/document/comments/ddue:dduexml/ddue:relatedTopics/*) > 0">
+ <xsl:apply-templates select="/document/comments/ddue:dduexml/ddue:relatedTopics" mode="seeAlso">
+ <xsl:with-param name="autoGenerateLinks" select="'true'" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="subSection">
+ <xsl:with-param name="title">
+ <include item="SeeAlsoReference"/>
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:call-template name="autogenSeeAlsoLinks"/>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/main_sandcastle.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/main_sandcastle.xsl
index 3b9b642..9954a00 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/main_sandcastle.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/main_sandcastle.xsl
@@ -1,25 +1,25 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
- <!-- stuff specified to comments authored in DDUEXML -->
+ <!-- stuff specified to comments authored in DDUEXML -->
+ <xsl:param name="omitXmlnsBoilerplate" select="'false'" />
-
- <xsl:include href="htmlBody.xsl"/>
+ <xsl:include href="htmlBody.xsl"/>
<xsl:include href="utilities_reference.xsl" />
- <xsl:variable name="summary" select="normalize-space(/document/comments/summary)" />
+ <xsl:variable name="summary" select="normalize-space(/document/comments/summary)" />
<xsl:variable name="abstractSummary" select="/document/comments/summary" />
- <xsl:variable name="hasSeeAlsoSection" select="boolean((count(/document/comments/seealso | /document/comments/summary/seealso) > 0) or
+ <xsl:variable name="hasSeeAlsoSection" select="boolean((count(/document/comments//seealso | /document/reference/elements/element/overloads//seealso) > 0) or
($group='type' or $group='member' or $group='list'))"/>
<xsl:variable name="examplesSection" select="boolean(string-length(/document/comments/example[normalize-space(.)]) > 0)"/>
<xsl:variable name="languageFilterSection" select="boolean(string-length(/document/comments/example[normalize-space(.)]) > 0)" />
-
+
<xsl:template name="body">
-
- <!-- auto-inserted info -->
- <!-- <xsl:apply-templates select="/document/reference/attributes" /> -->
+
+ <!-- auto-inserted info -->
+ <!-- <xsl:apply-templates select="/document/reference/attributes" /> -->
<xsl:apply-templates select="/document/comments/preliminary" />
- <xsl:apply-templates select="/document/comments/summary" />
+ <xsl:apply-templates select="/document/comments/summary" />
<xsl:if test="$subgroup='overload'">
<xsl:apply-templates select="/document/reference/elements" mode="overloadSummary" />
</xsl:if>
@@ -27,72 +27,74 @@
<xsl:if test="not($group='list' or $group='root' or $group='namespace')">
<xsl:call-template name="requirementsInfo"/>
</xsl:if>
- <!-- syntax -->
+ <!-- syntax -->
<xsl:if test="not($group='list' or $group='namespace')">
<xsl:apply-templates select="/document/syntax" />
</xsl:if>
- <!-- members -->
- <xsl:choose>
- <xsl:when test="$group='root'">
- <xsl:apply-templates select="/document/reference/elements" mode="root" />
- </xsl:when>
- <xsl:when test="$group='namespace'">
- <xsl:apply-templates select="/document/reference/elements" mode="namespace" />
- </xsl:when>
- <xsl:when test="$subgroup='enumeration'">
- <xsl:apply-templates select="/document/reference/elements" mode="enumeration" />
- </xsl:when>
- <xsl:when test="$group='type'">
- <xsl:apply-templates select="/document/reference/elements" mode="type" />
- </xsl:when>
- <xsl:when test="$group='list'">
- <xsl:choose>
- <xsl:when test="$subgroup='overload'">
- <xsl:apply-templates select="/document/reference/elements" mode="overload" />
- </xsl:when>
- <xsl:when test="$subgroup='DerivedTypeList'">
- <xsl:apply-templates select="/document/reference/elements" mode="derivedType" />
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates select="/document/reference/elements" mode="member" />
- </xsl:otherwise>
- </xsl:choose>
+ <!-- members -->
+ <xsl:choose>
+ <xsl:when test="$group='root'">
+ <xsl:apply-templates select="/document/reference/elements" mode="root" />
+ </xsl:when>
+ <xsl:when test="$group='namespace'">
+ <xsl:apply-templates select="/document/reference/elements" mode="namespace" />
+ </xsl:when>
+ <xsl:when test="$subgroup='enumeration'">
+ <xsl:apply-templates select="/document/reference/elements" mode="enumeration" />
+ </xsl:when>
+ <xsl:when test="$group='type'">
+ <xsl:apply-templates select="/document/reference/elements" mode="type" />
+ </xsl:when>
+ <xsl:when test="$group='list'">
+ <xsl:choose>
+ <xsl:when test="$subgroup='overload'">
+ <xsl:apply-templates select="/document/reference/elements" mode="overload" />
+ </xsl:when>
+ <xsl:when test="$subgroup='DerivedTypeList'">
+ <xsl:apply-templates select="/document/reference/elements" mode="derivedType" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="/document/reference/elements" mode="member" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
- </xsl:choose>
- <!-- remarks -->
- <xsl:apply-templates select="/document/comments/remarks" />
- <!-- example -->
- <xsl:apply-templates select="/document/comments/example" />
- <!-- other comment sections -->
- <!-- permissions -->
+ </xsl:choose>
+ <!-- remarks -->
+ <xsl:apply-templates select="/document/comments/remarks" />
+ <!-- example -->
+ <xsl:apply-templates select="/document/comments/example" />
+ <!-- other comment sections -->
+ <!-- permissions -->
<xsl:call-template name="permissions" />
- <!-- exceptions -->
- <xsl:call-template name="exceptions" />
- <!-- inheritance -->
- <xsl:apply-templates select="/document/reference/family" />
+ <!-- exceptions -->
+ <xsl:call-template name="exceptions" />
+ <!-- contracts -->
+ <xsl:call-template name="contracts" />
+ <!-- inheritance -->
+ <xsl:apply-templates select="/document/reference/family" />
<xsl:apply-templates select="/document/comments/threadsafety" />
<!--versions-->
<xsl:if test="not($group='list' or $group='namespace' or $group='root' )">
<xsl:apply-templates select="/document/reference/versions" />
</xsl:if>
- <!-- see also -->
+ <!-- see also -->
<xsl:call-template name="seealso" />
- </xsl:template>
+ </xsl:template>
- <xsl:template name="getParameterDescription">
- <xsl:param name="name" />
- <xsl:apply-templates select="/document/comments/param[@name=$name]" />
- </xsl:template>
+ <xsl:template name="getParameterDescription">
+ <xsl:param name="name" />
+ <xsl:apply-templates select="/document/comments/param[@name=$name]" />
+ </xsl:template>
- <xsl:template name="getReturnsDescription">
- <xsl:param name="name" />
- <xsl:apply-templates select="/document/comments/param[@name=$name]" />
- </xsl:template>
+ <xsl:template name="getReturnsDescription">
+ <xsl:param name="name" />
+ <xsl:apply-templates select="/document/comments/param[@name=$name]" />
+ </xsl:template>
- <xsl:template name="getElementDescription">
- <xsl:apply-templates select="summary[1]" />
- </xsl:template>
+ <xsl:template name="getElementDescription">
+ <xsl:apply-templates select="summary[1]" />
+ </xsl:template>
<xsl:template name="getOverloadSummary">
<xsl:apply-templates select="overloads" mode="summary"/>
@@ -103,28 +105,28 @@
</xsl:template>
<xsl:template name="getInternalOnlyDescription">
-
+
</xsl:template>
<!-- block sections -->
- <xsl:template match="summary">
- <div class="summary">
- <xsl:apply-templates />
- </div>
- </xsl:template>
+ <xsl:template match="summary">
+ <div class="summary">
+ <xsl:apply-templates />
+ </div>
+ </xsl:template>
<xsl:template match="overloads" mode="summary">
<xsl:choose>
- <xsl:when test="count(summary) > 0">
- <xsl:apply-templates select="summary" />
- </xsl:when>
- <xsl:otherwise>
- <div class="summary">
- <xsl:apply-templates/>
- </div>
- </xsl:otherwise>
+ <xsl:when test="count(summary) > 0">
+ <xsl:apply-templates select="summary" />
+ </xsl:when>
+ <xsl:otherwise>
+ <div class="summary">
+ <xsl:apply-templates/>
+ </div>
+ </xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -133,7 +135,7 @@
<xsl:apply-templates select="example"/>
</xsl:template>
- <xsl:template match="value">
+ <xsl:template match="value">
<xsl:call-template name="subSection">
<xsl:with-param name="title">
<include item="fieldValueTitle" />
@@ -142,9 +144,9 @@
<xsl:apply-templates />
</xsl:with-param>
</xsl:call-template>
- </xsl:template>
+ </xsl:template>
- <xsl:template match="returns">
+ <xsl:template match="returns">
<xsl:call-template name="subSection">
<xsl:with-param name="title">
<include item="methodValueTitle" />
@@ -179,28 +181,38 @@
</xsl:call-template>
</xsl:template>
- <xsl:template match="remarks">
- <xsl:call-template name="section">
+ <xsl:template match="remarks">
+ <xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'remarks'"/>
- <xsl:with-param name="title"><include item="remarksTitle" /></xsl:with-param>
- <xsl:with-param name="content"><xsl:apply-templates /></xsl:with-param>
- </xsl:call-template>
- </xsl:template>
+ <xsl:with-param name="title">
+ <include item="remarksTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:apply-templates />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
- <xsl:template match="example">
- <xsl:call-template name="section">
+ <xsl:template match="example">
+ <xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'example'"/>
- <xsl:with-param name="title"><include item="examplesTitle" /></xsl:with-param>
- <xsl:with-param name="content"><xsl:apply-templates /></xsl:with-param>
- </xsl:call-template>
- </xsl:template>
+ <xsl:with-param name="title">
+ <include item="examplesTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:apply-templates />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
- <xsl:template match="para">
- <p><xsl:apply-templates /></p>
- </xsl:template>
+ <xsl:template match="para">
+ <p>
+ <xsl:apply-templates />
+ </p>
+ </xsl:template>
+
+ <xsl:template match="code">
- <xsl:template match="code">
-
<xsl:variable name="codeLang">
<xsl:choose>
<xsl:when test="@language = 'vbs'">
@@ -243,34 +255,253 @@
<xsl:with-param name="codeLang" select="$codeLang" />
</xsl:call-template>
- </xsl:template>
+ </xsl:template>
- <xsl:template name="exceptions">
- <xsl:if test="count(/document/comments/exception) &gt; 0">
- <xsl:call-template name="section">
+ <xsl:template name="exceptions">
+ <xsl:if test="count(/document/comments/exception) &gt; 0">
+ <xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'exceptions'"/>
- <xsl:with-param name="title"><include item="exceptionsTitle" /></xsl:with-param>
- <xsl:with-param name="content">
+ <xsl:with-param name="title">
+ <include item="exceptionsTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
<div class="tableSection">
<table width="100%" cellspacing="2" cellpadding="5" frame="lhs" >
- <tr>
- <th class="exceptionNameColumn"><include item="exceptionNameHeader" /></th>
- <th class="exceptionConditionColumn"><include item="exceptionConditionHeader" /></th>
- </tr>
- <xsl:for-each select="/document/comments/exception">
- <tr>
- <td><referenceLink target="{@cref}" qualified="true" /></td>
- <td>
- <xsl:apply-templates select="." />
- </td>
- </tr>
- </xsl:for-each>
- </table>
+ <tr>
+ <th class="exceptionNameColumn">
+ <include item="exceptionNameHeader" />
+ </th>
+ <th class="exceptionConditionColumn">
+ <include item="exceptionConditionHeader" />
+ </th>
+ </tr>
+ <xsl:for-each select="/document/comments/exception">
+ <tr>
+ <td>
+ <referenceLink target="{@cref}" qualified="true" />
+ </td>
+ <td>
+ <xsl:apply-templates select="." />
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </div>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="contracts">
+ <xsl:variable name="requires" select="/document/comments/requires" />
+ <xsl:variable name="ensures" select="/document/comments/ensures" />
+ <xsl:variable name="ensuresOnThrow" select="/document/comments/ensuresOnThrow" />
+ <xsl:variable name="invariants" select="/document/comments/invariant" />
+ <xsl:variable name="setter" select="/document/comments/setter" />
+ <xsl:variable name="getter" select="/document/comments/getter" />
+ <xsl:variable name="pure" select="/document/comments/pure" />
+ <xsl:if test="$requires or $ensures or $ensuresOnThrow or $invariants or $setter or $getter or $pure">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'contracts'"/>
+ <xsl:with-param name="title">
+ <include item="contractsTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <!--Purity-->
+ <xsl:if test="$pure">
+ <xsl:text>This method is pure.</xsl:text>
+ </xsl:if>
+ <!--Contracts-->
+ <div class="tableSection">
+ <xsl:if test="$getter">
+ <xsl:variable name="getterRequires" select="$getter/requires"/>
+ <xsl:variable name="getterEnsures" select="$getter/ensures"/>
+ <xsl:variable name="getterEnsuresOnThrow" select="$getter/ensuresOnThrow"/>
+ <xsl:call-template name="subSection">
+ <xsl:with-param name="title">
+ <include item="getterTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:if test="$getterRequires">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="requiresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$getterRequires"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$getterEnsures">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$getterEnsures"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$getterEnsuresOnThrow">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresOnThrowNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$getterEnsuresOnThrow"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$setter">
+ <xsl:variable name="setterRequires" select="$setter/requires"/>
+ <xsl:variable name="setterEnsures" select="$setter/ensures"/>
+ <xsl:variable name="setterEnsuresOnThrow" select="$setter/ensuresOnThrow"/>
+ <xsl:call-template name="subSection">
+ <xsl:with-param name="title">
+ <include item="setterTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:if test="$setterRequires">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="requiresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$setterRequires"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$setterEnsures">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$setterEnsures"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$setterEnsuresOnThrow">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresOnThrowNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$setterEnsuresOnThrow"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$requires">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="requiresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$requires"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$ensures">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$ensures"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$ensuresOnThrow">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="ensuresOnThrowNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$ensuresOnThrow"/>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="$invariants">
+ <xsl:call-template name="contractsTable">
+ <xsl:with-param name="title">
+ <include item="invariantsNameHeader"/>
+ </xsl:with-param>
+ <xsl:with-param name="contracts" select="$invariants"/>
+ </xsl:call-template>
+ </xsl:if>
+ </div>
+ <!--Contracts link-->
+ <div class="contractsLink">
+ <a>
+ <xsl:attribute name="target">
+ <xsl:text>_blank</xsl:text>
+ </xsl:attribute>
+ <xsl:attribute name="href">
+ <xsl:text>http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx</xsl:text>
+ </xsl:attribute>
+ <xsl:text>Learn more about contracts</xsl:text>
+ </a>
</div>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template name="contractsTable">
+ <xsl:param name="title"/>
+ <xsl:param name="contracts"/>
+ <table width="100%" cellspacing="3" cellpadding="5" frame="lhs" >
+ <tr>
+ <th class="contractsNameColumn">
+ <xsl:copy-of select="$title"/>
+ </th>
+ </tr>
+ <xsl:for-each select="$contracts">
+ <tr>
+ <td>
+ <div class="code" style="margin-bottom: 0pt; white-space: pre-wrap;">
+ <pre style="margin-bottom: 0pt">
+ <xsl:value-of select="."/>
+ </pre>
+ </div>
+ <xsl:if test="@description or @inheritedFrom or @exception">
+ <div style="font-size:95%; margin-left: 10pt;
+ margin-bottom: 0pt">
+ <table
+ class="contractaux"
+ width="100%" frame="void" rules="none" border="0">
+ <colgroup>
+ <col width="10%"/>
+ <col width="90%"/>
+ </colgroup>
+ <xsl:if test="@description">
+ <tr style="border-bottom: 0px none;">
+ <td style="border-bottom: 0px none;">
+ <i><xsl:text>Description: </xsl:text></i>
+ </td>
+ <td style="border-bottom: 0px none;">
+ <xsl:value-of select="@description"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="@inheritedFrom">
+ <tr style="border-bottom: 0px none;">
+ <td style="border-bottom: 0px none;">
+ <i><xsl:text>Inherited From: </xsl:text></i>
+ </td>
+ <td style="border-bottom: 0px none;">
+ <referenceLink target="{@inheritedFrom}">
+ <xsl:value-of select="@inheritedFromTypeName"/>
+ </referenceLink>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:if test="@exception">
+ <tr style="border-bottom: 0px none;">
+ <td style="border-bottom: 0px none;">
+ <i><xsl:text>Exception: </xsl:text></i>
+ </td>
+ <td style="border-bottom: 0px none;">
+ <referenceLink target="{@exception}" qualified="true" />
+ </td>
+ </tr>
+ </xsl:if>
+ </table>
+ </div>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
<xsl:template name="permissions">
<xsl:if test="count(/document/comments/permission) &gt; 0">
@@ -282,25 +513,25 @@
<xsl:with-param name="content">
<div class="tableSection">
<table width="100%" cellspacing="2" cellpadding="5" frame="lhs" >
- <tr>
- <th class="permissionNameColumn">
- <include item="permissionNameHeader" />
- </th>
- <th class="permissionDescriptionColumn">
- <include item="permissionDescriptionHeader" />
- </th>
- </tr>
- <xsl:for-each select="/document/comments/permission">
<tr>
- <td>
- <referenceLink target="{@cref}" qualified="true" />
- </td>
- <td>
- <xsl:apply-templates select="." />
- </td>
+ <th class="permissionNameColumn">
+ <include item="permissionNameHeader" />
+ </th>
+ <th class="permissionDescriptionColumn">
+ <include item="permissionDescriptionHeader" />
+ </th>
</tr>
- </xsl:for-each>
- </table>
+ <xsl:for-each select="/document/comments/permission">
+ <tr>
+ <td>
+ <referenceLink target="{@cref}" qualified="true" />
+ </td>
+ <td>
+ <xsl:apply-templates select="." />
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
</div>
</xsl:with-param>
</xsl:call-template>
@@ -308,7 +539,7 @@
</xsl:template>
<xsl:template name="seealso">
- <xsl:if test="$hasSeeAlsoSection">
+ <xsl:if test="$hasSeeAlsoSection">
<xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'seeAlso'" />
<xsl:with-param name="title">
@@ -316,9 +547,11 @@
</xsl:with-param>
<xsl:with-param name="content">
<xsl:call-template name="autogenSeeAlsoLinks"/>
- <xsl:for-each select="/document/comments/seealso | /document/comments/summary/seealso">
+ <xsl:for-each select="/document/comments//seealso | /document/reference/elements/element/overloads//seealso">
<div class="seeAlsoStyle">
- <xsl:apply-templates select="." />
+ <xsl:apply-templates select=".">
+ <xsl:with-param name="displaySeeAlso" select="true()" />
+ </xsl:apply-templates>
</div>
</xsl:for-each>
</xsl:with-param>
@@ -326,46 +559,52 @@
</xsl:if>
</xsl:template>
- <xsl:template match="list[@type='bullet']">
- <ul>
- <xsl:for-each select="item">
- <li><xsl:apply-templates /></li>
- </xsl:for-each>
- </ul>
- </xsl:template>
+ <xsl:template match="list[@type='bullet']">
+ <ul>
+ <xsl:for-each select="item">
+ <li>
+ <xsl:apply-templates />
+ </li>
+ </xsl:for-each>
+ </ul>
+ </xsl:template>
- <xsl:template match="list[@type='number']">
- <ol>
- <xsl:for-each select="item">
- <li><xsl:apply-templates /></li>
- </xsl:for-each>
- </ol>
- </xsl:template>
+ <xsl:template match="list[@type='number']">
+ <ol>
+ <xsl:for-each select="item">
+ <li>
+ <xsl:apply-templates />
+ </li>
+ </xsl:for-each>
+ </ol>
+ </xsl:template>
- <xsl:template match="list[@type='table']">
+ <xsl:template match="list[@type='table']">
<div class="tableSection">
<table width="100%" cellspacing="2" cellpadding="5" frame="lhs" >
- <xsl:for-each select="listheader">
- <tr>
- <xsl:for-each select="*">
- <th><xsl:apply-templates /></th>
- </xsl:for-each>
- </tr>
- </xsl:for-each>
- <xsl:for-each select="item">
- <tr>
- <xsl:for-each select="*">
- <td>
- <xsl:apply-templates />
- </td>
- </xsl:for-each>
- </tr>
- </xsl:for-each>
- </table>
+ <xsl:for-each select="listheader">
+ <tr>
+ <xsl:for-each select="*">
+ <th>
+ <xsl:apply-templates />
+ </th>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ <xsl:for-each select="item">
+ <tr>
+ <xsl:for-each select="*">
+ <td>
+ <xsl:apply-templates />
+ </td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </table>
</div>
- </xsl:template>
+ </xsl:template>
- <!-- inline tags -->
+ <!-- inline tags -->
<xsl:template match="see[@cref]">
<xsl:choose>
@@ -380,59 +619,87 @@
</xsl:choose>
</xsl:template>
- <xsl:template match="seealso[@href]">
+ <xsl:template match="see[@href]">
<xsl:choose>
<xsl:when test="normalize-space(.)">
<a>
- <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
+ <xsl:attribute name="href">
+ <xsl:value-of select="@href"/>
+ </xsl:attribute>
<xsl:value-of select="." />
</a>
</xsl:when>
<xsl:otherwise>
<a>
- <xsl:attribute name="href"><xsl:value-of select="@href"/></xsl:attribute>
+ <xsl:attribute name="href">
+ <xsl:value-of select="@href"/>
+ </xsl:attribute>
<xsl:value-of select="@href" />
</a>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
+ <xsl:template match="seealso[@href]">
+ <xsl:param name="displaySeeAlso" select="false()" />
+ <xsl:if test="$displaySeeAlso">
+ <xsl:choose>
+ <xsl:when test="normalize-space(.)">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="@href"/>
+ </xsl:attribute>
+ <xsl:value-of select="." />
+ </a>
+ </xsl:when>
+ <xsl:otherwise>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="@href"/>
+ </xsl:attribute>
+ <xsl:value-of select="@href" />
+ </a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:template>
+
<xsl:template match="see[@langword]">
<span class="keyword">
<xsl:choose>
<xsl:when test="@langword='null' or @langword='Nothing' or @langword='nullptr'">
<span class="languageSpecificText">
- <span class="cs">null</span>
- <span class="vb">Nothing</span>
- <span class="cpp">nullptr</span>
+ <span class="cs">null</span>
+ <span class="vb">Nothing</span>
+ <span class="cpp">nullptr</span>
</span>
</xsl:when>
<xsl:when test="@langword='static' or @langword='Shared'">
<span class="languageSpecificText">
- <span class="cs">static</span>
- <span class="vb">Shared</span>
- <span class="cpp">static</span>
+ <span class="cs">static</span>
+ <span class="vb">Shared</span>
+ <span class="cpp">static</span>
</span>
</xsl:when>
<xsl:when test="@langword='virtual' or @langword='Overridable'">
<span class="languageSpecificText">
- <span class="cs">virtual</span>
- <span class="vb">Overridable</span>
- <span class="cpp">virtual</span>
+ <span class="cs">virtual</span>
+ <span class="vb">Overridable</span>
+ <span class="cpp">virtual</span>
</span>
</xsl:when>
<xsl:when test="@langword='true' or @langword='True'">
<span class="languageSpecificText">
- <span class="cs">true</span>
- <span class="vb">True</span>
- <span class="cpp">true</span>
+ <span class="cs">true</span>
+ <span class="vb">True</span>
+ <span class="cpp">true</span>
</span>
</xsl:when>
<xsl:when test="@langword='false' or @langword='False'">
<span class="languageSpecificText">
- <span class="cs">false</span>
- <span class="vb">False</span>
- <span class="cpp">false</span>
+ <span class="cs">false</span>
+ <span class="vb">False</span>
+ <span class="cpp">false</span>
</span>
</xsl:when>
<xsl:when test="@langword='abstract'">
@@ -449,43 +716,58 @@
</span>
<xsl:choose>
<xsl:when test="@langword='null' or @langword='Nothing' or @langword='nullptr'">
- <span class="nu"><include item="nullKeyword"/></span>
+ <span class="nu">
+ <include item="nullKeyword"/>
+ </span>
</xsl:when>
<xsl:when test="@langword='static' or @langword='Shared'">
- <span class="nu"><include item="staticKeyword"/></span>
+ <span class="nu">
+ <include item="staticKeyword"/>
+ </span>
</xsl:when>
<xsl:when test="@langword='virtual' or @langword='Overridable'">
- <span class="nu"><include item="virtualKeyword"/></span>
+ <span class="nu">
+ <include item="virtualKeyword"/>
+ </span>
</xsl:when>
<xsl:when test="@langword='true' or @langword='True'">
- <span class="nu"><include item="trueKeyword"/></span>
+ <span class="nu">
+ <include item="trueKeyword"/>
+ </span>
</xsl:when>
<xsl:when test="@langword='false' or @langword='False'">
- <span class="nu"><include item="falseKeyword"/></span>
+ <span class="nu">
+ <include item="falseKeyword"/>
+ </span>
</xsl:when>
<xsl:when test="@langword='abstract'">
- <span class="nu"><include item="abstractKeyword"/></span>
+ <span class="nu">
+ <include item="abstractKeyword"/>
+ </span>
</xsl:when>
</xsl:choose>
-
+
</xsl:template>
<xsl:template match="seealso">
- <xsl:choose>
- <xsl:when test="normalize-space(.)">
- <referenceLink target="{@cref}" qualified="true">
- <xsl:value-of select="." />
- </referenceLink>
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@cref}" qualified="true" />
- </xsl:otherwise>
- </xsl:choose>
+ <xsl:param name="displaySeeAlso" select="false()" />
+ <xsl:if test="$displaySeeAlso">
+ <xsl:choose>
+ <xsl:when test="normalize-space(.)">
+ <referenceLink target="{@cref}" qualified="true">
+ <xsl:value-of select="." />
+ </referenceLink>
+ </xsl:when>
+ <xsl:otherwise>
+ <referenceLink target="{@cref}" qualified="true" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
</xsl:template>
<xsl:template match="c">
<span class="code">
- <xsl:value-of select="." />
+ <xsl:apply-templates/>
</span>
</xsl:template>
@@ -527,14 +809,14 @@
<include item="runningHeaderText" />
</xsl:template>
- <!-- pass through html tags -->
+ <!-- pass through html tags -->
- <xsl:template match="p|ol|ul|li|dl|dt|dd|table|tr|th|td|a|img|b|i|strong|em|del|sub|sup|br|hr|h1|h2|h3|h4|h5|h6|pre|div|span|blockquote|abbr|acronym|u|font">
- <xsl:copy>
- <xsl:copy-of select="@*" />
- <xsl:apply-templates />
- </xsl:copy>
- </xsl:template>
+ <xsl:template match="p|ol|ul|li|dl|dt|dd|table|tr|th|td|a|img|b|i|strong|em|del|sub|sup|br|hr|h1|h2|h3|h4|h5|h6|pre|div|span|blockquote|abbr|acronym|u|font|map|area">
+ <xsl:copy>
+ <xsl:copy-of select="@*" />
+ <xsl:apply-templates />
+ </xsl:copy>
+ </xsl:template>
<!-- extra tag support -->
@@ -574,6 +856,7 @@
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="noteAltText" />
<includeAttribute name="title" item="noteAltText" />
</img>
<xsl:text> </xsl:text>
@@ -588,40 +871,40 @@
</div>
</xsl:template>
- <!-- move these off into a shared file -->
+ <!-- move these off into a shared file -->
<xsl:template name="createReferenceLink">
<xsl:param name="id" />
<xsl:param name="qualified" select="false()" />
-
- <referenceLink target="{$id}" qualified="{$qualified}" />
-
+
+ <referenceLink target="{$id}" qualified="{$qualified}" />
+
</xsl:template>
-
- <xsl:template name="section">
+
+ <xsl:template name="section">
<xsl:param name="toggleSwitch" />
- <xsl:param name="title" />
- <xsl:param name="content" />
-
+ <xsl:param name="title" />
+ <xsl:param name="content" />
+
<xsl:variable name="toggleTitle" select="concat($toggleSwitch,'Toggle')" />
<xsl:variable name="toggleSection" select="concat($toggleSwitch,'Section')" />
-
- <h1 class="heading">
- <span onclick="ExpandCollapse({$toggleTitle})" style="cursor:default;" onkeypress="ExpandCollapse_CheckKey({$toggleTitle}, event)" tabindex="0">
- <img id="{$toggleTitle}" class="toggle" name="toggleSwitch">
- <includeAttribute name="src" item="iconPath">
- <parameter>collapse_all.gif</parameter>
- </includeAttribute>
- </img>
- <xsl:copy-of select="$title" />
- </span>
- </h1>
-
+
+ <h1 class="heading">
+ <span onclick="ExpandCollapse({$toggleTitle})" style="cursor:default;" onkeypress="ExpandCollapse_CheckKey({$toggleTitle}, event)" tabindex="0">
+ <img id="{$toggleTitle}" class="toggle" name="toggleSwitch">
+ <includeAttribute name="src" item="iconPath">
+ <parameter>collapse_all.gif</parameter>
+ </includeAttribute>
+ </img>
+ <xsl:copy-of select="$title" />
+ </span>
+ </h1>
+
<div id="{$toggleSection}" class="section" name="collapseableSection" style="">
<xsl:copy-of select="$content" />
</div>
-
- </xsl:template>
+
+ </xsl:template>
<xsl:template name="subSection">
<xsl:param name="title" />
@@ -631,7 +914,7 @@
<xsl:copy-of select="$title" />
</h4>
<xsl:copy-of select="$content" />
-
+
</xsl:template>
<xsl:template name="memberIntro">
@@ -643,55 +926,10 @@
<xsl:call-template name="memberIntroBoilerplate"/>
</xsl:template>
- <xsl:template name="mshelpCodelangAttributes">
- <xsl:for-each select="/document/comments/example/code">
-
- <xsl:if test="not(@language=preceding::*/@language)">
- <xsl:variable name="codeLang">
- <xsl:choose>
- <xsl:when test="@language = 'VBScript' or @language = 'vbs'">
- <xsl:text>VBScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'VisualBasic' or @language = 'vb' or @language = 'vb#' or @language = 'VB' or @language = 'kbLangVB'" >
- <xsl:text>kbLangVB</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'CSharp' or @language = 'c#' or @language = 'cs' or @language = 'C#'" >
- <xsl:text>CSharp</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'ManagedCPlusPlus' or @language = 'cpp' or @language = 'cpp#' or @language = 'c' or @language = 'c++' or @language = 'C++' or @language = 'kbLangCPP'" >
- <xsl:text>kbLangCPP</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JSharp' or @language = 'j#' or @language = 'jsharp' or @language = 'VJ#'">
- <xsl:text>VJ#</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'JScript' or @language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript' or @language = 'kbJScript'">
- <xsl:text>kbJScript</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'xml'">
- <xsl:text>xml</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'html'">
- <xsl:text>html</xsl:text>
- </xsl:when>
- <xsl:when test="@language = 'vb-c#'">
- <xsl:text>visualbasicANDcsharp</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>other</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$codeLang='other'" />
- <xsl:otherwise>
- <xsl:call-template name="codeLang">
- <xsl:with-param name="codeLang" select="$codeLang" />
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
-
- </xsl:for-each>
+ <xsl:template name="codelangAttributes">
+ <xsl:call-template name="mshelpCodelangAttributes">
+ <xsl:with-param name="snippets" select="/document/comments/example/code" />
+ </xsl:call-template>
</xsl:template>
<!-- Footer stuff -->
@@ -704,10 +942,11 @@
<includeAttribute name="src" item="iconPath">
<parameter>footer.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="footerImage" />
<includeAttribute name="title" item="footerImage" />
</img>
</div>
-
+
<include item="footer">
<parameter>
<xsl:value-of select="$key"/>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_metadata.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp20.xsl
index 8869703..59fe84a 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_metadata.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp20.xsl
@@ -44,7 +44,12 @@
</xsl:when>
</xsl:choose>
- <xsl:call-template name="mshelpCodelangAttributes" />
+ <!-- Assembly Version-->
+ <xsl:if test="$api-group != 'namespace'">
+ <MSHelp:Attr Name="AssemblyVersion" Value="{/document/reference/containers/library/assemblydata/@version}" />
+ </xsl:if>
+
+ <xsl:call-template name="codelangAttributes" />
<xsl:call-template name="versionMetadata" />
<xsl:call-template name="authoredMetadata" />
</xml>
@@ -217,7 +222,7 @@
<MSHelp:Attr Name="APIName" Value="{$apiTypeName}" />
<xsl:choose>
<xsl:when test="boolean($api-subgroup='delegate')">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.ctor')}" />
+ <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'..ctor')}" />
<MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','Invoke')}" />
<MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','BeginInvoke')}" />
<MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.','EndInvoke')}" />
@@ -231,33 +236,38 @@
</xsl:choose>
</xsl:when>
<xsl:when test="$api-group='member'">
- <xsl:variable name="apiTypeName">
- <xsl:value-of select="concat(/document/reference/containers/namespace/apidata/@name,'.',/document/reference/containers/type/apidata/@name)" />
- <xsl:if test="count(/document/reference/templates/template) > 0">
- <xsl:value-of select="concat('`',count(/document/reference/templates/template))" />
- </xsl:if>
- </xsl:variable>
- <!-- Namespace + Type + Member -->
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.',/document/reference/apidata/@name)}" />
+ <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
+ <xsl:variable name="type">
+ <xsl:for-each select="/document/reference/containers/type[1]">
+ <xsl:call-template name="typeNameWithTicks" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="member" select="/document/reference/apidata/@name" />
+ <!-- Namespace + Type + Member -->
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.', $member)}" />
<xsl:choose>
<!-- for properties, add APIName attribute get/set accessor methods -->
<xsl:when test="boolean($api-subgroup='property')">
<xsl:if test="/document/reference/propertydata[@get='true']">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.get_',/document/reference/apidata/@name)}" />
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.get_', $member)}" />
</xsl:if>
<xsl:if test="/document/reference/propertydata[@set='true']">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.set_',/document/reference/apidata/@name)}" />
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.set_', $member)}" />
</xsl:if>
</xsl:when>
<!-- for events, add APIName attribute add/remove accessor methods -->
<xsl:when test="boolean($api-subgroup='event')">
<xsl:if test="/document/reference/eventdata[@add='true']">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.add_',/document/reference/apidata/@name)}" />
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.add_', $member)}" />
</xsl:if>
<xsl:if test="/document/reference/eventdata[@remove='true']">
- <MSHelp:Attr Name="APIName" Value="{concat($apiTypeName,'.remove_',/document/reference/apidata/@name)}" />
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.remove_', $member)}" />
</xsl:if>
</xsl:when>
+ <!-- for operators, add APIName attribute op accessor methods -->
+ <xsl:when test="boolean($api-subsubgroup='operator')">
+ <MSHelp:Attr Name="APIName" Value="{concat($namespace, '.', $type, '.op_', $member)}" />
+ </xsl:when>
</xsl:choose>
</xsl:when>
</xsl:choose>
@@ -502,11 +512,6 @@
</xsl:choose>
</xsl:template>
- <xsl:template name="codeLang">
- <xsl:param name="codeLang" />
- <MSHelp:Attr Name="codelang" Value="{$codeLang}" />
- </xsl:template>
-
<!-- make a semicolon-separated list of the $languages-->
<xsl:template name="languagesList">
<xsl:for-each select="$languages/language">
@@ -531,6 +536,11 @@
</xsl:variable>
<xsl:choose>
<xsl:when test="normalize-space($devlang)=''"/>
+ <xsl:when test="$devlang = 'VJ#'">
+ <xsl:if test="boolean(/document/reference/versions/versions[@name='netfw']//version[not(@name='netfw35')])">
+ <MSHelp:Attr Name="DevLang" Value="{$devlang}" />
+ </xsl:if>
+ </xsl:when>
<xsl:otherwise>
<MSHelp:Attr Name="DevLang" Value="{$devlang}" />
</xsl:otherwise>
@@ -615,6 +625,9 @@
<xsl:when test="$devlang = 'JSharp' or $devlang = 'j#' or $devlang = 'jsharp' or $devlang = 'VJ#'">
<xsl:text>VJ#</xsl:text>
</xsl:when>
+ <xsl:when test="$devlang = 'FSharp' or $devlang = 'f#' or $devlang = 'fs' or $devlang = 'F#'" >
+ <xsl:text>FSharp</xsl:text>
+ </xsl:when>
<xsl:when test="$devlang = 'xaml' or $devlang = 'XAML'">
<xsl:text>XAML</xsl:text>
</xsl:when>
@@ -768,6 +781,41 @@
<xsl:call-template name="textNames" />
</xsl:for-each>
</xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$topic-subgroup='Operators'">
+ <xsl:variable name="operators" select="document/reference/elements/element[not(apidata[@name='Explicit' or @name='Implicit'])]"/>
+ <xsl:variable name="conversions" select="document/reference/elements/element[apidata[@name='Explicit' or @name='Implicit']]" />
+ <xsl:variable name="entryType">
+ <xsl:choose>
+ <!-- operators + type conversions -->
+ <xsl:when test="count($operators) &gt; 0 and count($conversions) &gt; 0">
+ <xsl:value-of select="'operatorsAndTypeConversions'" />
+ </xsl:when>
+ <!-- no operators + type conversions -->
+ <xsl:when test="not(count($operators) &gt; 0) and count($conversions) &gt; 0">
+ <xsl:value-of select="'typeConversions'" />
+ </xsl:when>
+ <!-- operators + no type conversions -->
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <MSHelp:Keyword Index="K">
+ <includeAttribute name="Term" item="{$entryType}IndexEntry">
+ <parameter>
+ <include item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </MSHelp:Keyword>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
<xsl:for-each select="msxsl:node-set($names)/name">
<MSHelp:Keyword Index="K">
<includeAttribute name="Term" item="{$subgroup}IndexEntry">
@@ -781,9 +829,12 @@
</includeAttribute>
</MSHelp:Keyword>
</xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<!-- constructor (or constructor overload) topics get unqualified sub-entries using the type names -->
<xsl:when test="($topic-group='api' and $api-subgroup='constructor' and not(/document/reference/memberdata/@overload)) or ($topic-subgroup='overload' and $api-subgroup = 'constructor')">
+ <xsl:variable name="typeSubgroup" select="/document/reference/containers/type/apidata/@subgroup" />
<xsl:variable name="names">
<xsl:for-each select="/document/reference/containers/type">
<xsl:call-template name="textNames" />
@@ -793,7 +844,7 @@
<MSHelp:Keyword Index="K">
<includeAttribute name="Term" item="constructorIndexEntry">
<parameter>
- <include item="{$api-subgroup}IndexEntry">
+ <include item="{$typeSubgroup}IndexEntry">
<parameter>
<xsl:value-of select="." />
</parameter>
@@ -817,10 +868,30 @@
</MSHelp:Keyword>
</xsl:for-each>
</xsl:when>
+ <!-- op_explicit and op_implicit members -->
+ <xsl:when test="$topic-group='api' and $api-subsubgroup='operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="operatorTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <MSHelp:Keyword Index="K">
+ <includeAttribute name="Term" item="conversionOperatorIndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </MSHelp:Keyword>
+ </xsl:for-each>
+ </xsl:when>
<!-- other member (or overload) topics get qualified and unqualified entries using the member names -->
<xsl:when test="($topic-group='api' and $api-group='member' and not(/document/reference/memberdata/@overload)) or $topic-subgroup='overload'">
<xsl:choose>
+ <!-- overload op_explicit and op_implicit topics -->
+ <xsl:when test="$api-subsubgroup='operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ </xsl:when>
<!-- explicit interface implementation -->
<xsl:when test="/document/reference/proceduredata/@virtual='true' and /document/reference/memberdata/@visibility='private'">
<xsl:variable name="entryType">
@@ -877,6 +948,9 @@
</xsl:when>
<xsl:otherwise>
<xsl:choose>
+ <xsl:when test="$api-subsubgroup='operator'">
+ <xsl:value-of select="$api-subsubgroup"/>
+ </xsl:when>
<xsl:when test="$subgroup='overload'">
<xsl:value-of select="/document/reference/apidata/@subgroup"/>
</xsl:when>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp30.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp30.xsl
new file mode 100644
index 0000000..a5b7e77
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/metadataHelp30.xsl
@@ -0,0 +1,589 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ >
+
+ <!-- <xsl:import href="../../shared/transforms/utilities_metadata.xsl" /> -->
+
+ <xsl:template name="authoredMetadata30">
+
+ <xsl:for-each select="/document/metadata/keyword[@index='K']">
+ <meta name="System.Keywords">
+ <xsl:attribute name="content">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='K']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:for-each>
+
+ <!-- authored F -->
+ <xsl:for-each select="/document/metadata/keyword[@index='F']">
+ <meta name="Microsoft.Help.F1">
+ <xsl:attribute name="content">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='F']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:for-each>
+
+ <!-- authored B -->
+ <xsl:for-each select="/document/metadata/keyword[@index='B']">
+ <meta name="Microsoft.Help.F1">
+ <xsl:attribute name="content">
+ <xsl:value-of select="text()" />
+ <xsl:for-each select="keyword[@index='B']">
+ <xsl:text>, </xsl:text>
+ <xsl:value-of select="text()"/>
+ </xsl:for-each>
+ </xsl:attribute>
+ </meta>
+ </xsl:for-each>
+
+ </xsl:template>
+
+
+
+ <xsl:template name="helpMetadata30">
+ <!-- F keywords -->
+ <xsl:choose>
+
+ <!-- namespace pages get the namespace keyword, if it exists -->
+ <xsl:when test="$group='namespace'">
+ <xsl:variable name="namespace" select="/document/reference/apidata/@name" />
+ <xsl:if test="$namespace != ''">
+ <meta name="Microsoft.Help.F1" content="{$namespace}" />
+ </xsl:if>
+ </xsl:when>
+
+ <!-- type memberlist topics do NOT get F keywords -->
+ <xsl:when test="$group='list' and $subgroup='members'"/>
+
+ <!-- type overview pages get namespace.type keywords -->
+ <xsl:when test="$group='type'">
+ <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
+ <xsl:variable name="type">
+ <xsl:for-each select="/document/reference[1]">
+ <xsl:call-template name="typeNameWithTicks" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$namespace=''">
+ <meta name="Microsoft.Help.F1" content="{$type}" />
+ </xsl:when>
+ <xsl:otherwise>
+ <meta name="Microsoft.Help.F1" content="{concat($namespace,'.',$type)}" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!-- for enums, write F1 keywords for each enum member -->
+ <xsl:if test="$subgroup = 'enumeration'">
+ <xsl:for-each select="/document/reference/elements/element">
+ <xsl:choose>
+ <xsl:when test="$namespace=''">
+ <meta name="Microsoft.Help.F1" content="{concat($type, '.', apidata/@name)}" />
+ </xsl:when>
+ <xsl:otherwise>
+ <meta name="Microsoft.Help.F1" content="{concat($namespace,'.',$type, '.', apidata/@name)}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:if>
+
+ <!-- Insert additional F1 keywords to support XAML for class, struct, and enum topics in a set of namespaces. -->
+ <xsl:call-template name="xamlMSHelpFKeywords30"/>
+ </xsl:when>
+
+ <!-- overload list pages get namespace.type.member keyword -->
+ <xsl:when test="$group='list' and $subgroup='overload'">
+ <xsl:variable name="containingTypeId" select="/document/reference/containers/type[1]/@api" />
+ <!-- do not write F1 keyword for overload list topics that contain only inherited members -->
+ <xsl:if test="/document/reference/elements//element/containers/type[1][@api=$containingTypeId]">
+ <xsl:call-template name="memberF1KeywordsHelp30"/>
+ </xsl:if>
+ </xsl:when>
+
+
+ <!-- member pages -->
+ <xsl:when test="$group='member'">
+ <xsl:choose>
+ <!-- no F1 help entries for overload signature topics -->
+ <xsl:when test="/document/reference/memberdata/@overload"/>
+
+ <!-- no F1 help entries for explicit interface implementation members -->
+ <xsl:when test="/document/reference[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]"/>
+
+ <!-- other member pages get namespace.type.member keywords -->
+ <xsl:otherwise>
+ <xsl:call-template name="memberF1KeywordsHelp30"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="memberF1KeywordsHelp30">
+ <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
+ <xsl:variable name="type">
+ <xsl:for-each select="/document/reference/containers/type[1]">
+ <xsl:call-template name="typeNameWithTicks" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="member">
+ <xsl:choose>
+ <!-- if the member is a constructor, use "#ctor" as the member name -->
+ <xsl:when test="/document/reference/apidata[@subgroup='constructor']">#ctor</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="/document/reference/apidata/@name"/>
+ <!-- for generic members, include tick notation for number of generic template parameters. -->
+ <xsl:if test="/document/reference/templates/template">
+ <xsl:text>``</xsl:text>
+ <xsl:value-of select="count(/document/reference/templates/template)"/>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$namespace=''">
+ <meta name="Microsoft.Help.F1" content="{concat($type, '.', $member)}" />
+ </xsl:when>
+ <xsl:otherwise>
+ <meta name="Microsoft.Help.F1" content="{concat($namespace, '.', $type, '.', $member)}" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!--
+ Insert additional F1 keywords for class, struct, and enum topics in a set of WPF namespaces.
+ The keyword prefixes and the WPF namespaces are hard-coded in variables.
+ -->
+<!-- <xsl:variable name="var_wpf_f1index_prefix_1">http://schemas.microsoft.com/winfx/2006/xaml/presentation#</xsl:variable>
+ <xsl:variable name="var_wpf_f1index_prefix_1_namespaces">N:System.Windows.Controls#N:System.Windows.Documents#N:System.Windows.Shapes#N:System.Windows.Navigation#N:System.Windows.Data#N:System.Windows#N:System.Windows.Controls.Primitives#N:System.Windows.Media.Animation#N:System.Windows.Annotations#N:System.Windows.Annotations.Anchoring#N:System.Windows.Annotations.Storage#N:System.Windows.Media#N:System.Windows.Media.Animation#N:System.Windows.Media.Media3D#N:</xsl:variable> -->
+
+ <xsl:template name="xamlMSHelpFKeywords30">
+ <xsl:if test="$subgroup='class' or $subgroup='enumeration' or $subgroup='structure'">
+ <xsl:if test="boolean(contains($var_wpf_f1index_prefix_1_namespaces, concat('#',/document/reference/containers/namespace/@api,'#'))
+ or starts-with($var_wpf_f1index_prefix_1_namespaces, concat(/document/reference/containers/namespace/@api,'#')))">
+ <meta name="Microsoft.Help.F1" content="{concat($var_wpf_f1index_prefix_1, /document/reference/apidata/@name)}"/>
+ </xsl:if>
+ </xsl:if>
+ </xsl:template>
+
+ <!-- Index Logic -->
+
+ <xsl:template name="indexMetadata30">
+ <xsl:choose>
+ <!-- namespace topics get one unqualified index entry -->
+ <xsl:when test="$topic-group='api' and $api-group='namespace'">
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="namespaceIndexEntry">
+ <parameter>
+ <xsl:value-of select="msxsl:node-set($names)/name" />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:when>
+ <!-- type overview topics get qualified and unqualified index entries, and an about index entry -->
+ <xsl:when test="$topic-group='api' and $api-group='type'">
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ <xsl:if test="boolean($namespace != '')">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="$namespace"/>
+ <xsl:text>.</xsl:text>
+ <xsl:copy-of select="." />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:if>
+ <!-- multi-topic types (not delegates and enumerations) get about entries, too-->
+ <xsl:if test="$api-subgroup='class' or $api-subgroup='structure' or $api-subgroup='interface'">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="aboutTypeIndexEntry">
+ <parameter>
+ <include item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:if>
+ </xsl:for-each>
+ <!-- enumerations get the index entries for their members -->
+ <xsl:if test="$api-subgroup='enumeration'">
+ <xsl:for-each select="/document/reference/elements/element">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$api-subgroup}MemberIndexEntry">
+ <parameter>
+ <xsl:value-of select="apidata/@name" />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:when>
+ <!-- all member lists get unqualified entries, qualified entries, and unqualified sub-entries -->
+ <xsl:when test="$topic-group='list' and $topic-subgroup='members'">
+ <xsl:variable name="namespace" select="/document/reference/containers/namespace/apidata/@name" />
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="membersIndexEntry">
+ <parameter>
+ <include item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ <xsl:variable name="qnames">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="qualifiedTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:if test="boolean($namespace != '')">
+ <xsl:for-each select="msxsl:node-set($qnames)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:when>
+ <!-- other member list pages get unqualified sub-entries -->
+ <xsl:when test="$topic-group='list' and not($topic-subgroup = 'overload')">
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$topic-subgroup='Operators'">
+ <xsl:variable name="operators" select="document/reference/elements/element[not(apidata[@name='Explicit' or @name='Implicit'])]"/>
+ <xsl:variable name="conversions" select="document/reference/elements/element[apidata[@name='Explicit' or @name='Implicit']]" />
+ <xsl:variable name="entryType">
+ <xsl:choose>
+ <!-- operators + type conversions -->
+ <xsl:when test="count($operators) &gt; 0 and count($conversions) &gt; 0">
+ <xsl:value-of select="'operatorsAndTypeConversions'" />
+ </xsl:when>
+ <!-- no operators + type conversions -->
+ <xsl:when test="not(count($operators) &gt; 0) and count($conversions) &gt; 0">
+ <xsl:value-of select="'typeConversions'" />
+ </xsl:when>
+ <!-- operators + no type conversions -->
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$entryType}IndexEntry">
+ <parameter>
+ <include item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$subgroup}IndexEntry">
+ <parameter>
+ <include item="{$api-subgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- constructor (or constructor overload) topics get unqualified sub-entries using the type names -->
+ <xsl:when test="($topic-group='api' and $api-subgroup='constructor' and not(/document/reference/memberdata/@overload)) or ($topic-subgroup='overload' and $api-subgroup = 'constructor')">
+ <xsl:variable name="typeSubgroup" select="/document/reference/containers/type/apidata/@subgroup" />
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference/containers/type">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="constructorIndexEntry">
+ <parameter>
+ <include item="{$typeSubgroup}IndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </include>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ <xsl:variable name="qnames">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="qualifiedTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($qnames)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="constructorTypeIndexEntry">
+ <parameter>
+ <xsl:value-of select="." />
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:when>
+ <!-- op_explicit and op_implicit members -->
+ <xsl:when test="$topic-group='api' and $api-subsubgroup='operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="operatorTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="conversionOperatorIndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:when>
+ <!-- other member (or overload) topics get qualified and unqualified entries using the member names -->
+ <xsl:when test="($topic-group='api' and $api-group='member' and not(/document/reference/memberdata/@overload)) or $topic-subgroup='overload'">
+
+ <xsl:choose>
+ <!-- overload op_explicit and op_implicit topics -->
+ <xsl:when test="$api-subsubgroup='operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ </xsl:when>
+ <!-- explicit interface implementation -->
+ <xsl:when test="/document/reference/proceduredata/@virtual='true' and /document/reference/memberdata/@visibility='private'">
+ <xsl:variable name="entryType">
+ <xsl:choose>
+ <xsl:when test="string($subsubgroup)">
+ <xsl:value-of select="$subsubgroup" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$subgroup='overload'">
+ <xsl:value-of select="/document/reference/apidata/@subgroup"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference/implements/member">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$entryType}ExplicitIndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ <xsl:variable name="qnames">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="qualifiedTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($qnames)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$entryType}ExplicitIndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="entryType">
+ <xsl:choose>
+ <xsl:when test="string($subsubgroup)">
+ <xsl:value-of select="$subsubgroup" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="$api-subsubgroup='operator'">
+ <xsl:value-of select="$api-subsubgroup"/>
+ </xsl:when>
+ <xsl:when test="$subgroup='overload'">
+ <xsl:value-of select="/document/reference/apidata/@subgroup"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="names">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="textNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($names)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$entryType}IndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ <xsl:variable name="qnames">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="qualifiedTextNames" />
+ </xsl:for-each>
+ </xsl:variable>
+ <xsl:for-each select="msxsl:node-set($qnames)/name">
+ <meta name="System.Keywords">
+ <includeAttribute name="content" item="{$entryType}IndexEntry">
+ <parameter>
+ <xsl:copy-of select="."/>
+ </parameter>
+ </includeAttribute>
+ </meta>
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:when>
+ <!-- derived type lists get unqualified sub-entries -->
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="insert30Metadata">
+
+ <!-- System.Language -->
+ <meta name="Language">
+ <includeAttribute name="content" item="locale" />
+ </meta>
+
+ <!-- System.Title -->
+ <!-- <title> is set elsewhere (eg, main_conceptual.xsl, utilities_reference.xsl) -->
+
+ <!-- System.Keywords -->
+ <!-- Microsoft.Help.F1 -->
+ <xsl:call-template name="indexMetadata30" />
+ <xsl:call-template name="helpMetadata30" />
+ <xsl:call-template name="authoredMetadata30" />
+
+ <!-- Microsoft.Help.Id -->
+ <meta name="Microsoft.Help.Id" content="{$key}" />
+
+ <!-- Microsoft.Help.Description -->
+ <xsl:if test="$abstractSummary">
+ <meta name="Description">
+ <xsl:attribute name="content">
+ <xsl:call-template name="trimAtPeriod">
+ <xsl:with-param name="string" select="$abstractSummary" />
+ </xsl:call-template>
+ </xsl:attribute>
+ </meta>
+ </xsl:if>
+
+ <!-- Microsoft.Help.TocParent -->
+ <xsl:for-each select="/document/metadata/attribute[@name='TOCParent']">
+ <meta name="Microsoft.Help.TocParent" content="{.}" />
+ <meta name="Microsoft.Help.TocOrder" content="0" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.Product -->
+ <!-- Added by MTPS -->
+
+ <!-- Microsoft.Help.ProductVersion -->
+ <!-- Added by MTPS -->
+
+ <!-- Microsoft.Help.Category -->
+ <xsl:for-each select="/document/metadata/attribute[@name='Category']">
+ <meta name="Microsoft.Help.Category" content="{.}" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.ContentFilter -->
+ <xsl:for-each select="/document/metadata/attribute[@name='ContentFilter']">
+ <meta name="Microsoft.Help.ContentFilter" content="{.}" />
+ </xsl:for-each>
+
+ <!-- Microsoft.Help.ContentType -->
+ <meta name="Microsoft.Help.ContentType" content="Reference" />
+
+ <!-- Microsoft.Package.Book -->
+ <xsl:variable name="Book" select="/document/metadata/attribute[@name='Book']/text()" />
+ <xsl:if test="$Book">
+ <meta name="Microsoft.Package.Book" content="{$Book}" />
+ </xsl:if>
+
+
+
+ </xsl:template>
+
+
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/seeAlsoSection.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/seeAlsoSection.xsl
new file mode 100644
index 0000000..f9a234f
--- /dev/null
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/seeAlsoSection.xsl
@@ -0,0 +1,168 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1"
+ xmlns:MSHelp="http://msdn.microsoft.com/mshelp"
+ xmlns:mshelp="http://msdn.microsoft.com/mshelp"
+ xmlns:ddue="http://ddue.schemas.microsoft.com/authoring/2003/5"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:msxsl="urn:schemas-microsoft-com:xslt"
+ >
+
+ <msxsl:script language="C#" implements-prefix="ddue">
+ <msxsl:using namespace="System" />
+ <msxsl:using namespace="System.Globalization"/>
+ <msxsl:using namespace="System.Text.RegularExpressions" />
+ <![CDATA[
+ public static string ToUpper(string id) {
+ return id.Trim().ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ }
+ //Regular expression to check that a string is in a valid Guid representation.
+ private static Regex guidChecker = new Regex("[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}", RegexOptions.None);
+
+ public static string GuidChecker(string id) {
+ return guidChecker.IsMatch(id).ToString();
+ }
+
+ public static string CompareDate(string RTMReleaseDate, string changedHistoryDate) {
+
+ CultureInfo culture = CultureInfo.InvariantCulture;
+ DateTime dt1 = DateTime.MinValue;
+ DateTime dt2 = DateTime.MinValue;
+
+ try {
+ dt1 = DateTime.Parse(RTMReleaseDate, culture);
+ }
+ catch (FormatException) {
+ Console.WriteLine(string.Format("Error: CompareDate: Unable to convert '{0}' for culture {1}.", RTMReleaseDate, culture.Name));
+ return "notValidDate";
+ }
+
+ try {
+ dt2 = DateTime.Parse(changedHistoryDate,culture);
+ }
+ catch (FormatException) {
+ Console.WriteLine(string.Format("Error: CompareDate: Unable to convert '{0}' for culture {1}.", changedHistoryDate, culture.Name));
+ return "notValidDate";
+ }
+
+ if (DateTime.Compare(dt2, dt1) > 0) return changedHistoryDate;
+ else return RTMReleaseDate;
+ }
+
+ public static string IsValidDate(string dateString) {
+
+ CultureInfo culture = CultureInfo.InvariantCulture;
+ DateTime dt = DateTime.MinValue;
+
+ try {
+ dt = DateTime.Parse(dateString, culture);
+ }
+ catch (FormatException) {
+ Console.WriteLine(string.Format("Error: IsValidDate: Unable to convert '{0}' for culture {1}.", dateString, culture.Name));
+ return "false";
+ }
+
+ return "true";
+ }
+
+ ]]>
+ </msxsl:script>
+
+ <!-- Tasks -->
+ <xsl:variable name="HowTo" select="'DAC3A6A0-C863-4E5B-8F65-79EFC6A4BA09'" />
+ <xsl:variable name="Walkthrough" select="'4779DD54-5D0C-4CC3-9DB3-BF1C90B721B3'" />
+ <xsl:variable name="Sample" select="'069EFD88-412D-4E2F-8848-2D5C3AD56BDE'" />
+ <xsl:variable name="Troubleshooting" select="'38C8E0D1-D601-4DBA-AE1B-5BEC16CD9B01'" />
+
+ <!-- Reference -->
+ <xsl:variable name="ReferenceWithoutSyntax" select="'F9205737-4DEC-4A58-AA69-0E621B1236BD'" />
+ <xsl:variable name="ReferenceWithSyntax" select="'95DADC4C-A2A6-447A-AA36-B6BE3A4F8DEC'" />
+ <xsl:variable name="XMLReference" select="'3272D745-2FFC-48C4-9E9D-CF2B2B784D5F'" />
+ <xsl:variable name="ErrorMessage" select="'A635375F-98C2-4241-94E7-E427B47C20B6'" />
+ <xsl:variable name="UIReference" select="'B8ED9F21-39A4-4967-928D-160CD2ED9DCE'" />
+
+ <!-- Concepts -->
+ <xsl:variable name="Conceptual" select="'1FE70836-AA7D-4515-B54B-E10C4B516E50'" />
+ <xsl:variable name="SDKTechnologyOverviewArchitecture" select="'68F07632-C4C5-4645-8DFA-AC87DCB4BD54'" />
+ <xsl:variable name="SDKTechnologyOverviewCodeDirectory" select="'4BBAAF90-0E5F-4C86-9D31-A5CAEE35A416'" />
+ <xsl:variable name="SDKTechnologyOverviewScenarios" select="'356C57C4-384D-4AF2-A637-FDD6F088A033'" />
+ <xsl:variable name="SDKTechnologyOverviewTechnologySummary" select="'19F1BB0E-F32A-4D5F-80A9-211D92A8A715'" />
+
+ <!-- Other Resources -->
+ <xsl:variable name="Orientation" select="'B137C930-7BF7-48A2-A329-3ADCAEF8868E'" />
+ <xsl:variable name="WhitePaper" select="'56DB00EC-28BA-4C0D-8694-28E8B244E236'" />
+ <xsl:variable name="CodeEntity" select="'4A273212-0AC8-4D72-8349-EC11CD2FF8CD'" />
+ <xsl:variable name="Glossary" select="'A689E19C-2687-4881-8CE1-652FF60CF46C'" />
+ <xsl:variable name="SDKTechnologyOverviewOrientation" select="'CDB8C120-888F-447B-8AF8-F9540562E7CA'" />
+
+ <xsl:template match="ddue:relatedTopics" mode="seeAlso">
+ <xsl:param name="autoGenerateLinks" select="'false'" />
+
+ <!-- Tasks -->
+ <xsl:if test="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) = $HowTo or ddue:ToUpper(@topicType_id) = $Walkthrough or ddue:ToUpper(@topicType_id) = $Sample or ddue:ToUpper(@topicType_id) = $Troubleshooting) and ddue:GuidChecker(@xlink:href) = 'True']" >
+ <xsl:call-template name="seeAlsoSubSection">
+ <xsl:with-param name="headerGroup" select="'SeeAlsoTasks'" />
+ <xsl:with-param name="members" select="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) = $HowTo or ddue:ToUpper(@topicType_id) = $Walkthrough or ddue:ToUpper(@topicType_id) = $Sample or ddue:ToUpper(@topicType_id) = $Troubleshooting) and ddue:GuidChecker(@xlink:href) = 'True']" />
+ <xsl:with-param name="autoGenerateLinks" select="'false'" />
+ </xsl:call-template>
+ </xsl:if>
+
+ <!-- Reference -->
+ <xsl:if test="(ddue:link | ddue:legacyLink)[((ddue:ToUpper(@topicType_id) = $ReferenceWithoutSyntax or ddue:ToUpper(@topicType_id) = $ReferenceWithSyntax or ddue:ToUpper(@topicType_id) = $XMLReference or ddue:ToUpper(@topicType_id) = $ErrorMessage or ddue:ToUpper(@topicType_id) = $UIReference) and ddue:GuidChecker(@xlink:href) = 'True') or ddue:GuidChecker(@xlink:href) = 'False'] |
+ ddue:codeEntityReference or
+ $autoGenerateLinks = 'true'">
+ <xsl:call-template name="seeAlsoSubSection">
+ <xsl:with-param name="headerGroup" select="'SeeAlsoReference'" />
+ <xsl:with-param name="members" select="(ddue:link | ddue:legacyLink)[((ddue:ToUpper(@topicType_id) = $ReferenceWithoutSyntax or ddue:ToUpper(@topicType_id) = $ReferenceWithSyntax or ddue:ToUpper(@topicType_id) = $XMLReference or ddue:ToUpper(@topicType_id) = $ErrorMessage or ddue:ToUpper(@topicType_id) = $UIReference) and ddue:GuidChecker(@xlink:href) = 'True') or ddue:GuidChecker(@xlink:href) = 'False'] |
+ ddue:codeEntityReference" />
+ <xsl:with-param name="autoGenerateLinks" select="$autoGenerateLinks" />
+ </xsl:call-template>
+ </xsl:if>
+
+ <!-- Concepts -->
+ <xsl:if test="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) = $Conceptual or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewArchitecture or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewCodeDirectory or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewScenarios or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewTechnologySummary) and ddue:GuidChecker(@xlink:href) = 'True']">
+ <xsl:call-template name="seeAlsoSubSection">
+ <xsl:with-param name="headerGroup" select="'SeeAlsoConcepts'" />
+ <xsl:with-param name="members" select="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) = $Conceptual or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewArchitecture or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewCodeDirectory or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewScenarios or ddue:ToUpper(@topicType_id) = $SDKTechnologyOverviewTechnologySummary) and ddue:GuidChecker(@xlink:href) = 'True']" />
+ <xsl:with-param name="autoGenerateLinks" select="'false'" />
+ </xsl:call-template>
+ </xsl:if>
+
+ <!-- Other Resources -->
+ <xsl:if test="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) != $HowTo and ddue:ToUpper(@topicType_id) != $Walkthrough and ddue:ToUpper(@topicType_id) != $Sample and ddue:ToUpper(@topicType_id) != $Troubleshooting and ddue:ToUpper(@topicType_id) != $Conceptual and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewArchitecture and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewCodeDirectory and
+ ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewScenarios and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewTechnologySummary and ddue:ToUpper(@topicType_id) != $ReferenceWithoutSyntax and ddue:ToUpper(@topicType_id) != $ReferenceWithSyntax and ddue:ToUpper(@topicType_id) != $XMLReference and ddue:ToUpper(@topicType_id) != $ErrorMessage and ddue:ToUpper(@topicType_id) != $UIReference and
+ ddue:GuidChecker(@xlink:href) = 'True') or (not(@topicType_id) and ddue:GuidChecker(@xlink:href) = 'True')] or
+ ddue:dynamicLink[@type = 'inline'] or
+ ddue:externalLink" >
+ <xsl:call-template name="seeAlsoSubSection">
+ <xsl:with-param name="headerGroup" select="'SeeAlsoOtherResources'" />
+ <xsl:with-param name="members" select="(ddue:link | ddue:legacyLink)[(ddue:ToUpper(@topicType_id) != $HowTo and ddue:ToUpper(@topicType_id) != $Walkthrough and ddue:ToUpper(@topicType_id) != $Sample and ddue:ToUpper(@topicType_id) != $Troubleshooting and ddue:ToUpper(@topicType_id) != $Conceptual and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewArchitecture and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewCodeDirectory and
+ ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewScenarios and ddue:ToUpper(@topicType_id) != $SDKTechnologyOverviewTechnologySummary and ddue:ToUpper(@topicType_id) != $ReferenceWithoutSyntax and ddue:ToUpper(@topicType_id) != $ReferenceWithSyntax and ddue:ToUpper(@topicType_id) != $XMLReference and ddue:ToUpper(@topicType_id) != $ErrorMessage and ddue:ToUpper(@topicType_id) != $UIReference and
+ ddue:GuidChecker(@xlink:href) = 'True') or (not(@topicType_id) and ddue:GuidChecker(@xlink:href) = 'True')] |
+ ddue:dynamicLink[@type = 'inline'] |
+ ddue:externalLink" />
+ <xsl:with-param name="autoGenerateLinks" select="'false'" />
+ </xsl:call-template>
+ </xsl:if>
+
+ </xsl:template>
+
+ <xsl:template name="seeAlsoSubSection">
+ <xsl:param name="headerGroup" />
+ <xsl:param name="members" />
+ <xsl:param name="autoGenerateLinks" />
+ <xsl:call-template name="subSection">
+ <xsl:with-param name="title">
+ <include item="{$headerGroup}"/>
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:if test="$autoGenerateLinks='true'">
+ <xsl:call-template name="autogenSeeAlsoLinks"/>
+ </xsl:if>
+ <xsl:for-each select="$members">
+ <div class="seeAlsoStyle">
+ <xsl:apply-templates select="." />
+ </div>
+ </xsl:for-each>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_dduexml.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/utilities_dduexml.xsl
index 24b78ca..40d4cbe 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_dduexml.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/utilities_dduexml.xsl
@@ -13,14 +13,16 @@
<!-- the Remarks section includes content from these nodes, excluding the xaml sections are captured in the xaml syntax processing -->
<xsl:template name="HasRemarksContent">
+ <xsl:param name="node" />
+
<xsl:choose>
<xsl:when test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">true</xsl:when>
- <xsl:when test="normalize-space(ddue:content)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForImplementers)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForCallers)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:notesForInheritors)">true</xsl:when>
- <xsl:when test="normalize-space(../ddue:platformNotes)">true</xsl:when>
- <xsl:when test="normalize-space(ddue:sections/ddue:section[not(
+ <xsl:when test="normalize-space($node/ddue:remarks/ddue:content)">true</xsl:when>
+ <xsl:when test="normalize-space($node/ddue:notesForImplementers)">true</xsl:when>
+ <xsl:when test="normalize-space($node/ddue:notesForCallers)">true</xsl:when>
+ <xsl:when test="normalize-space($node/ddue:notesForInheritors)">true</xsl:when>
+ <xsl:when test="normalize-space($node/ddue:platformNotes)">true</xsl:when>
+ <xsl:when test="normalize-space($node/ddue:remarks/ddue:sections/ddue:section[not(
starts-with(@address,'xamlValues') or
starts-with(@address,'xamlTextUsage') or
starts-with(@address,'xamlAttributeUsage') or
@@ -34,40 +36,10 @@
</xsl:template>
<xsl:template match="ddue:remarks">
- <xsl:variable name="hasRemarks">
- <xsl:call-template name="HasRemarksContent"/>
- </xsl:variable>
- <xsl:if test="$hasRemarks='true'">
- <xsl:choose>
- <xsl:when test="not($group = 'namespace')">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'remarks'"/>
- <xsl:with-param name="title"><include item="remarksTitle" /></xsl:with-param>
- <xsl:with-param name="content">
- <!-- HostProtectionAttribute -->
- <xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
- <xsl:call-template name="hostProtectionContent" />
- </xsl:if>
- <xsl:apply-templates />
- <xsl:apply-templates select="../ddue:notesForImplementers"/>
- <xsl:apply-templates select="../ddue:notesForCallers"/>
- <xsl:apply-templates select="../ddue:notesForInheritors"/>
- <xsl:apply-templates select="../ddue:platformNotes"/>
- <include item="mshelpKTable">
- <parameter>
- <xsl:text>tt_</xsl:text>
- <xsl:value-of select="$key"/>
- </parameter>
- </include>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
+ <xsl:call-template name="WriteRemarksSection">
+ <xsl:with-param name="node" select=".." />
+ </xsl:call-template>
+ </xsl:template>
<xsl:template match="ddue:codeExamples">
<xsl:if test="normalize-space(.)">
@@ -204,6 +176,10 @@
</xsl:for-each>
</xsl:template>
+ <xsl:template match="ddue:platformNotes/ddue:platformNote/ddue:content/ddue:para">
+ <xsl:apply-templates />
+ </xsl:template>
+
<xsl:template match="ddue:schemaHierarchy">
<xsl:for-each select="ddue:link">
<xsl:call-template name="indent">
@@ -238,6 +214,9 @@
<xsl:when test="@language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript'">
<xsl:text>JScript</xsl:text>
</xsl:when>
+ <xsl:when test="@language = 'f#' or @language = 'fs' or @language = 'F#'" >
+ <xsl:text>FSharp</xsl:text>
+ </xsl:when>
<xsl:when test="@language = 'xml'">
<xsl:text>xmlLang</xsl:text>
</xsl:when>
@@ -278,79 +257,6 @@
</div>
</xsl:template>
- <xsl:template name="seeAlsoSection">
-
- <xsl:if test="$hasSeeAlsoSection">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'seeAlso'"/>
- <xsl:with-param name="title"><include item="relatedTitle" /></xsl:with-param>
- <xsl:with-param name="content">
-
- <!-- Concepts sub-section -->
- <xsl:if test="normalize-space(/document/comments/ddue:dduexml/ddue:relatedTopics/ddue:link) or normalize-space(/document/comments/ddue:dduexml/ddue:relatedTopics/ddue:dynamicLink[@type='inline'])">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoConcepts"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'link' or (name() = 'dynamicLink' and @type = 'inline') or (name() = 'legacyLink' and not(starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Reference sub-section (always one of these in an API topic) -->
- <xsl:if test="(normalize-space(/document/comments/ddue:dduexml/ddue:relatedTopics/ddue:codeEntityReference) or normalize-space(/document/comments/ddue:dduexml/ddue:relatedTopics/ddue:legacyLink)) or not(/document/reference/apidata/@group = 'namespace')">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoReference"/>
- </xsl:with-param>
-
- <xsl:with-param name="content">
- <xsl:call-template name="autogenSeeAlsoLinks"/>
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'codeEntityReference' or (name() = 'legacyLink' and (starts-with(@xlink:href,'frlrf')
- or starts-with(@xlink:href,'N:') or starts-with(@xlink:href,'T:') or starts-with(@xlink:href,'M:') or starts-with(@xlink:href,'P:')
- or starts-with(@xlink:href,'F:') or starts-with(@xlink:href,'E:') or starts-with(@xlink:href,'Overload:')))">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- <!-- Other Resources sub-section -->
- <xsl:if test="/document/comments/ddue:dduexml/ddue:relatedTopics/ddue:externalLink">
- <xsl:call-template name="subSection">
- <xsl:with-param name="title">
- <include item="SeeAlsoOtherResources"/>
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:for-each select="/document/comments/ddue:dduexml/ddue:relatedTopics/*">
- <xsl:if test="name() = 'externalLink'">
- <div class="seeAlsoStyle">
- <xsl:apply-templates select="."/>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
-
- </xsl:with-param>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
-
<!-- just skip over these -->
<xsl:template match="ddue:content | ddue:legacy">
<xsl:apply-templates />
@@ -428,6 +334,9 @@
<xsl:when test="@language = 'js' or @language = 'jscript#' or @language = 'jscript' or @language = 'JScript'">
<xsl:text>JScript</xsl:text>
</xsl:when>
+ <xsl:when test="@language = 'f#' or @language = 'fs' or @language = 'F#'">
+ <xsl:text>FSharp</xsl:text>
+ </xsl:when>
<xsl:when test="@language = 'xml'">
<xsl:text>xmlLang</xsl:text>
</xsl:when>
@@ -440,6 +349,9 @@
<xsl:when test="@language = 'xaml' or @language = 'XAML'">
<xsl:text>XAML</xsl:text>
</xsl:when>
+ <xsl:when test="@language = 'javascript' or @language = 'JavaScript'">
+ <xsl:text>JavaScript</xsl:text>
+ </xsl:when>
<xsl:otherwise>
<xsl:text>other</xsl:text>
</xsl:otherwise>
@@ -500,6 +412,7 @@
<xsl:choose>
<xsl:when test="@class='tip'">
<img class="note">
+ <includeAttribute name="alt" item="tipAltText" />
<includeAttribute name="title" item="tipAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -509,6 +422,7 @@
</xsl:when>
<xsl:when test="@class='caution' or @class='warning'">
<img class="note">
+ <includeAttribute name="alt" item="cautionAltText" />
<includeAttribute name="title" item="cautionAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_caution.gif</parameter>
@@ -518,6 +432,7 @@
</xsl:when>
<xsl:when test="@class='security note'">
<img class="note">
+ <includeAttribute name="alt" item="securityAltText" />
<includeAttribute name="title" item="securityAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_security.gif</parameter>
@@ -527,6 +442,7 @@
</xsl:when>
<xsl:when test="@class='important'">
<img class="note">
+ <includeAttribute name="alt" item="importantAltText" />
<includeAttribute name="title" item="importantAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_caution.gif</parameter>
@@ -536,6 +452,7 @@
</xsl:when>
<xsl:when test="@class='visual basic note'">
<img class="note">
+ <includeAttribute name="alt" item="visualBasicAltText" />
<includeAttribute name="title" item="visualBasicAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -545,6 +462,7 @@
</xsl:when>
<xsl:when test="@class='visual c# note'">
<img class="note">
+ <includeAttribute name="alt" item="visualC#AltText" />
<includeAttribute name="title" item="visualC#AltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -554,6 +472,7 @@
</xsl:when>
<xsl:when test="@class='visual c++ note'">
<img class="note">
+ <includeAttribute name="alt" item="visualC++AltText" />
<includeAttribute name="title" item="visualC++AltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -563,6 +482,7 @@
</xsl:when>
<xsl:when test="@class='visual j# note'">
<img class="note">
+ <includeAttribute name="alt" item="visualJ#AltText" />
<includeAttribute name="title" item="visualJ#AltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -572,6 +492,7 @@
</xsl:when>
<xsl:when test="@class='note'">
<img class="note">
+ <includeAttribute name="alt" item="noteAltText" />
<includeAttribute name="title" item="noteAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -581,6 +502,7 @@
</xsl:when>
<xsl:otherwise>
<img class="note">
+ <includeAttribute name="alt" item="noteAltText" />
<includeAttribute name="title" item="noteAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -605,7 +527,8 @@
</xsl:template>
<xsl:template match="ddue:section">
- <xsl:if test="descendant::ddue:content[normalize-space(.)]">
+ <!-- display the section only if it has content (text or media)-->
+ <xsl:if test="descendant::ddue:content[normalize-space(.)] or descendant::ddue:mediaLink">
<xsl:apply-templates select="@address" />
<!-- Count all the possible ancestor root nodes -->
@@ -630,6 +553,9 @@
<xsl:variable name="a19" select="count(ancestor::ddue:section)" />
<xsl:variable name="total" select="$a1+$a2+$a3+$a4+$a5+$a6+$a7+$a8+$a9+$a10+$a11+$a12+$a13+$a14+$a15+$a16+$a17+$a18+$a19" />
<xsl:choose>
+ <!-- Don't render the 'Change History' section here; it's handled in the writeChangeHistorySection template. -->
+ <xsl:when test="ddue:title = 'Change History'" />
+
<xsl:when test="$total = 0">
<xsl:variable name="sectionCount">
<xsl:value-of select="count(preceding-sibling::ddue:section)"/>
@@ -686,15 +612,13 @@
</xsl:template>
-->
<xsl:template match="ddue:mediaLink|ddue:mediaLinkInline">
- <span class="media">
- <xsl:if test="ddue:caption">
- <div class="caption">
- <xsl:apply-templates select="ddue:caption" />
- </div>
- <br />
- </xsl:if>
- <artLink target="{ddue:image/@xlink:href}" />
- </span>
+ <xsl:if test="ddue:caption">
+ <div class="caption">
+ <xsl:apply-templates select="ddue:caption" />
+ </div>
+ <br />
+ </xsl:if>
+ <artLink target="{ddue:image/@xlink:href}" />
</xsl:template>
<xsl:template match="ddue:procedure">
@@ -791,7 +715,7 @@
<xsl:template match="ddue:languageKeyword">
<xsl:variable name="word" select="." />
- <span data="langKeyword" value="{$word}">
+ <span sdata="langKeyword" value="{$word}">
<xsl:choose>
<!-- mref topics get special handling for keywords like null, etc. -->
<xsl:when test="/document/reference/apidata">
@@ -802,12 +726,16 @@
<span class="cs">null</span>
<span class="vb">Nothing</span>
<span class="cpp">nullptr</span>
+ <span class="fs">unit</span>
</span>
</xsl:when>
<!-- need to comment out special handling for static, virtual, true, and false
until UE teams review authored content to make sure the auto-text works with the authored text.
For example, auto-text with authored content like the following will result in bad customer experience.
- <languageKeyword>static</languageKeyword> (<languageKeyword>Shared</languageKeyword> in Visual Basic) -->
+ <languageKeyword>static</languageKeyword> (<languageKeyword>Shared</languageKeyword> in Visual Basic)
+
+ This also needs to have F# added should it be uncommented.
+ -->
<!--
<xsl:when test="$word='static' or $word='Shared'">
<span class="cs">static</span>
@@ -1327,6 +1255,7 @@
<tr>
<th align="left">
<img class="note">
+ <includeAttribute name="alt" item="noteAltText" />
<includeAttribute name="title" item="noteAltText" />
<includeAttribute item="iconPath" name="src">
<parameter>alert_note.gif</parameter>
@@ -1360,4 +1289,138 @@
</div>
</xsl:template>
+ <!-- Display a date to show when the topic was last updated. -->
+ <xsl:template name="writeFreshnessDate">
+ <!-- The $ChangedHistoryDate param is from the authored changeHistory table, if any. -->
+ <xsl:param name="ChangedHistoryDate" />
+ <!-- Determine whether the authored date is a valid date string. -->
+ <xsl:variable name="validChangeHistoryDate">
+ <xsl:choose>
+ <xsl:when test="normalize-space($ChangedHistoryDate)=''"/>
+ <xsl:when test="ddue:IsValidDate(normalize-space($ChangedHistoryDate)) = 'true'">
+ <xsl:value-of select="normalize-space($ChangedHistoryDate)"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:choose>
+ <!-- display nothing if the 'changeHistoryOptions' argument is set to 'omit' -->
+ <xsl:when test="$changeHistoryOptions = 'omit'"/>
+
+ <!-- if it's a valid date, display the freshness line. -->
+ <xsl:when test="normalize-space($validChangeHistoryDate)">
+ <p>
+ <include item="UpdateTitle">
+ <parameter>
+ <xsl:value-of select="normalize-space($validChangeHistoryDate)"/>
+ </parameter>
+ </include>
+ </p>
+ </xsl:when>
+
+ <!-- use a default date if no ChangedHistoryDate and the 'changeHistoryOptions' argument is set to 'showDefaultFreshnessDate' -->
+ <xsl:when test="$changeHistoryOptions = 'showDefaultFreshnessDate'">
+ <p>
+ <include item="UpdateTitle">
+ <parameter>
+ <include item="defaultFreshnessDate"/>
+ </parameter>
+ </include>
+ </p>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="writeChangeHistorySection">
+ <xsl:if test="$changeHistoryOptions!='omit'">
+ <!-- conceptual authored content is in /document/topic/*; mref content is in /document/comments/ddue:dduexml. -->
+ <xsl:for-each select="/document/comments/ddue:dduexml | /document/topic/*">
+ <!-- Get the change history section content, which can be in changeHistory or a section with title='Change History'. -->
+ <xsl:variable name="changeHistoryContent">
+ <xsl:choose>
+ <xsl:when test="ddue:changeHistory/ddue:content/ddue:table/ddue:row/ddue:entry[normalize-space(.)]">
+ <xsl:apply-templates select="ddue:changeHistory/ddue:content"/>
+ </xsl:when>
+ <xsl:when test=".//ddue:section[ddue:title = 'Change History']/ddue:content/ddue:table/ddue:row/ddue:entry[normalize-space(.)]">
+ <xsl:apply-templates select=".//ddue:section[ddue:title = 'Change History']/ddue:content"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:if test="normalize-space($changeHistoryContent)">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'changeHistory'"/>
+ <xsl:with-param name="title">
+ <include item="changeHistory" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:copy-of select="$changeHistoryContent" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="ddue:span">
+ <xsl:choose>
+ <!-- Process the markup added by MTMarkup tool -->
+ <xsl:when test="@class='tgtSentence' or @class='srcSentence'">
+ <span>
+ <xsl:copy-of select="@*" />
+ <xsl:apply-templates />
+ </span>
+ </xsl:when>
+ <!-- fix bug 361746 - use copy-of, so that span class="keyword", "literal" and "comment"
+ nodes are copied to preserve code colorization in snippets -->
+ <xsl:when test="@class='keyword' or @class='literal' or @class='comment'">
+ <xsl:copy-of select="."/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Don't render the changeHistory section here; it's handled in the writeChangeHistorySection template. -->
+ <xsl:template match="ddue:changeHistory"/>
+
+ <xsl:template name="WriteRemarksSection">
+ <xsl:param name="node" />
+
+ <xsl:variable name="hasRemarks">
+ <xsl:call-template name="HasRemarksContent">
+ <xsl:with-param name="node" select="$node" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:if test="$hasRemarks='true'">
+ <xsl:choose>
+ <xsl:when test="not($group = 'namespace')">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'remarks'"/>
+ <xsl:with-param name="title">
+ <include item="remarksTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <!-- HostProtectionAttribute -->
+ <xsl:if test="/document/reference/attributes/attribute/type[@api='T:System.Security.Permissions.HostProtectionAttribute']">
+ <xsl:call-template name="hostProtectionContent" />
+ </xsl:if>
+ <xsl:apply-templates select="$node/ddue:remarks/*" />
+ <xsl:apply-templates select="$node/ddue:notesForImplementers"/>
+ <xsl:apply-templates select="$node/ddue:notesForCallers"/>
+ <xsl:apply-templates select="$node/ddue:notesForInheritors"/>
+ <xsl:apply-templates select="$node/ddue:platformNotes"/>
+ <include item="mshelpKTable">
+ <parameter>
+ <xsl:text>tt_</xsl:text>
+ <xsl:value-of select="$key"/>
+ </parameter>
+ </include>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="$node/ddue:remarks/*" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:template>
+
</xsl:stylesheet>
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_reference.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/utilities_reference.xsl
index 2137e5f..8edafbc 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/utilities_reference.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/utilities_reference.xsl
@@ -16,8 +16,10 @@
<xsl:param name="key" />
<xsl:param name="metadata" value="false" />
<xsl:param name="languages">false</xsl:param>
+ <xsl:param name="componentizeBy">namespace</xsl:param>
- <xsl:include href="utilities_metadata.xsl" />
+ <xsl:include href="metadataHelp30.xsl" />
+ <xsl:include href="metadataHelp20.xsl"/>
<xsl:include href="xamlSyntax.xsl"/>
<xsl:template match="/">
@@ -25,7 +27,9 @@
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"/>
<META NAME="save" CONTENT="history"/>
+ <xsl:call-template name="insertNoIndexNoFollow" />
<title><xsl:call-template name="topicTitlePlain"/></title>
+ <xsl:call-template name="insert30Metadata" />
<xsl:call-template name="insertStylesheets" />
<xsl:call-template name="insertScripts" />
<xsl:call-template name="insertFilename" />
@@ -80,6 +84,12 @@
<!-- document head -->
+ <xsl:template name="insertNoIndexNoFollow">
+ <xsl:if test="/document/metadata/attribute[@name='NoSearch']">
+ <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW" />
+ </xsl:if>
+ </xsl:template>
+
<xsl:template name="insertStylesheets">
<link rel="stylesheet" type="text/css" href="../styles/presentation.css" />
<!-- make mshelp links work -->
@@ -240,6 +250,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>CFW.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="CompactFrameworkAltText" />
<includeAttribute name="title" item="CompactFrameworkAltText" />
</img>
</xsl:if>
@@ -249,6 +260,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>xna.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="XNAFrameworkAltText" />
<includeAttribute name="title" item="XNAFrameworkAltText" />
</img>
</xsl:if>
@@ -262,11 +274,28 @@
<xsl:text> </xsl:text>
<include item="obsoleteRed" />
</xsl:if>
- <xsl:call-template name="getElementDescription" />
+ <xsl:call-template name="getEnumMemberDescription" />
</td>
</tr>
</xsl:template>
+ <xsl:template name="getEnumMemberDescription">
+ <xsl:choose>
+ <xsl:when test="normalize-space(ddue:summary[1]) != ''">
+ <span sdata="memberAuthoredSummary">
+ <xsl:apply-templates select="ddue:summary[1]/ddue:para/node()" />
+ </span>
+ </xsl:when>
+ <xsl:otherwise>
+ <span sdata="memberAuthoredSummary">
+ <xsl:apply-templates select="ddue:summary[2]/ddue:para/node()" />
+ </span>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- enum members may have additional authored content in the remarks node -->
+ <xsl:apply-templates select="ddue:remarks/ddue:content" />
+ </xsl:template>
+
<xsl:template match="element" mode="derivedType">
<tr>
<td>
@@ -291,141 +320,52 @@
</tr>
</xsl:template>
- <xsl:template match="element" mode="overload">
- <xsl:variable name="supportedOnXna">
- <xsl:call-template name="IsMemberSupportedOnXna"/>
- </xsl:variable>
- <xsl:variable name="supportedOnCf">
- <xsl:call-template name="IsMemberSupportedOnCf"/>
- </xsl:variable>
- <xsl:variable name="staticMember">
- <xsl:call-template name="IsMemberStatic"/>
- </xsl:variable>
- <xsl:variable name="inheritedMember">
- <xsl:call-template name="IsMemberInherited"/>
- </xsl:variable>
- <xsl:variable name="protectedMember">
- <xsl:call-template name="IsMemberProtected"/>
- </xsl:variable>
- <xsl:variable name="privateMember">
- <xsl:call-template name="IsMemberPrivate"/>
+ <xsl:template name="extensionMethodDisplayLink">
+ <xsl:variable name="showParameters">
+ <xsl:choose>
+ <xsl:when test="@overload='true'">true</xsl:when>
+ <xsl:otherwise>false</xsl:otherwise>
+ </xsl:choose>
</xsl:variable>
-
- <tr>
- <xsl:if test="normalize-space($inheritedMember)!=''">
- <xsl:attribute name="name">inheritedMember</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($protectedMember)!=''">
- <xsl:attribute name="protected">true</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($supportedOnXna)=''">
- <xsl:attribute name="notSupportedOnXna">true</xsl:attribute>
- </xsl:if>
- <xsl:if test="normalize-space($supportedOnCf)=''">
- <xsl:attribute name="notSupportedOn">netcf</xsl:attribute>
- </xsl:if>
-
- <xsl:attribute name="data">
- <xsl:value-of select="apidata/@subgroup" />
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='public'">
- <xsl:text>; public</xsl:text>
- </xsl:when>
- <xsl:when test="memberdata[@visibility='family' or @visibility='family or assembly' or @visibility='assembly']">
- <xsl:text>; protected</xsl:text>
- </xsl:when>
- <xsl:when test="memberdata/@visibility='private' and not(proceduredata[@virtual = 'true'])">
- <xsl:text>; private</xsl:text>
- </xsl:when>
- <!-- NOTE: EII members (private-virtual) fall through to this xsl:otherwise block -->
- <xsl:otherwise>
- <xsl:text>; public</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="memberdata/@static = 'true'">
- <xsl:text>; static</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; instance</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- <xsl:choose>
- <xsl:when test="normalize-space($inheritedMember)=''">
- <xsl:text>; declared</xsl:text>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>; inherited</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:attribute>
-
- <td>
- <!-- item icons -->
- <xsl:call-template name="memberIcons">
- <xsl:with-param name="memberVisibility">
- <xsl:choose>
- <xsl:when test="memberdata/@visibility='family' or memberdata/@visibility='family or assembly' or memberdata/@visibility='assembly'">prot</xsl:when>
- <xsl:when test="memberdata/@visibility='private'">priv</xsl:when>
- <xsl:otherwise>pub</xsl:otherwise>
- </xsl:choose>
- </xsl:with-param>
- <xsl:with-param name="staticMember" select="normalize-space($staticMember)" />
- <xsl:with-param name="supportedOnXna" select="normalize-space($supportedOnXna)"/>
- <xsl:with-param name="supportedOnCf" select="normalize-space($supportedOnCf)"/>
- </xsl:call-template>
- </td>
- <td>
- <!-- item name -->
- <xsl:choose>
- <xsl:when test="@display-api">
- <referenceLink target="{@api}" display-target="{@display-api}" />
- </xsl:when>
- <xsl:otherwise>
- <referenceLink target="{@api}" />
- </xsl:otherwise>
- </xsl:choose>
- </td>
- <td>
- <!-- item description -->
- <xsl:call-template name="getInternalOnlyDescription" />
- <xsl:if test="attributes/attribute/type[@api='T:System.ObsoleteAttribute']">
- <xsl:text> </xsl:text>
- <include item="obsoleteRed" />
- </xsl:if>
- <xsl:call-template name="getElementDescription" />
- <xsl:choose>
- <xsl:when test="normalize-space($inheritedMember)!=''">
- <xsl:text> </xsl:text>
- <include item="inheritedFrom">
- <parameter>
- <xsl:apply-templates select="containers/type" mode="link" />
- </parameter>
- </include>
- </xsl:when>
- <xsl:when test="overrides">
- <xsl:text> </xsl:text>
- <include item="overridesMember">
- <parameter>
- <xsl:apply-templates select="overrides/member" mode="link" />
- </parameter>
- </include>
- </xsl:when>
- </xsl:choose>
-
- </td>
- </tr>
+ <referenceLink target="{@api}" display-target="extension" show-parameters="{$showParameters}">
+ <extensionMethod>
+ <xsl:copy-of select="@*"/>
+ <xsl:copy-of select="apidata|templates|parameters|containers"/>
+ </extensionMethod>
+ </referenceLink>
</xsl:template>
-
+
<xsl:template name="insertFilename">
<meta name="container">
<xsl:attribute name="content">
<xsl:choose>
- <xsl:when test="normalize-space(/document/reference/containers/library/@assembly)">
- <xsl:value-of select="normalize-space(/document/reference/containers/library/@assembly)"/>
+ <xsl:when test="$componentizeBy='assembly'">
+ <xsl:choose>
+ <xsl:when test="normalize-space(/document/reference/containers/library/@assembly)">
+ <xsl:value-of select="normalize-space(/document/reference/containers/library/@assembly)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>Namespaces</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
+ <!-- the default is to componentize by namespace. For non-componentized builds, the <meta name="container"> value is ignored. -->
<xsl:otherwise>
- <xsl:text>Namespaces</xsl:text>
+ <xsl:choose>
+ <!-- get the namespace name from containers/namespace/@api for most members -->
+ <xsl:when test="normalize-space(substring-after(/document/reference/containers/namespace/@api,':'))">
+ <xsl:value-of select="normalize-space(substring-after(/document/reference/containers/namespace/@api,':'))"/>
+ </xsl:when>
+ <!-- use 'default_namespace' for members in the default namespace (where namespace/@api == 'N:') -->
+ <xsl:when test="normalize-space(/document/reference/containers/namespace/@api)"><xsl:text>default_namespace</xsl:text></xsl:when>
+ <!-- for the default namespace topic, use 'default_namespace' -->
+ <xsl:when test="/document/reference/apidata[@group='namespace' and @name='']"><xsl:text>default_namespace</xsl:text></xsl:when>
+ <!-- for other namespace topics, get the name from apidata/@name -->
+ <xsl:when test="/document/reference/apidata/@group='namespace'">
+ <xsl:value-of select="normalize-space(/document/reference/apidata/@name)"/>
+ </xsl:when>
+ <xsl:otherwise><xsl:text>unknown</xsl:text></xsl:otherwise>
+ </xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
@@ -518,7 +458,15 @@
<!-- the subsubgroup, subgroup, or group determines the title -->
<xsl:choose>
<xsl:when test="string($api-subsubgroup)">
- <xsl:value-of select="$api-subsubgroup" />
+ <xsl:choose>
+ <!-- topic title for op_explicit and op_implicit members -->
+ <xsl:when test="$api-subsubgroup='operator' and (document/reference/apidata/@name = 'Explicit' or document/reference/apidata/@name = 'Implicit')">
+ <xsl:value-of select="'typeConversion'"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$api-subsubgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<xsl:when test="string($api-subgroup)">
<xsl:value-of select="$api-subgroup"/>
@@ -531,13 +479,51 @@
<!-- overload topic titles -->
<xsl:when test="$topic-subgroup='overload'">
<!-- the api subgroup (e.g. "property") determines the title; do we want to use the subsubgoup name when it is available? -->
- <xsl:value-of select="$api-subgroup"/>
+ <xsl:choose>
+ <!-- topic title for overload op_explicit and op_implicit members -->
+ <xsl:when test="$api-subsubgroup = 'operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name = 'Implicit')">
+ <xsl:value-of select="'conversionOperator'"/>
+ </xsl:when>
+ <!-- topic title for overload operator members -->
+ <xsl:when test="$api-subsubgroup='operator'">
+ <xsl:value-of select="$api-subsubgroup" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$api-subgroup"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<!-- list topic titles -->
<xsl:when test="$topic-group='list'">
<!-- the topic subgroup (e.g. "methods") determines the title -->
- <xsl:value-of select="$topic-subgroup" />
+ <xsl:choose>
+ <xsl:when test="$topic-subgroup='Operators'">
+ <xsl:variable name="operators" select="document/reference/elements/element[not(apidata[@name='Explicit' or @name='Implicit'])]"/>
+ <xsl:variable name="conversions" select="document/reference/elements/element[apidata[@name='Explicit' or @name='Implicit']]" />
+ <xsl:choose>
+ <!-- operators + type conversions -->
+ <xsl:when test="count($operators) &gt; 0 and count($conversions) &gt; 0">
+ <xsl:value-of select="'OperatorsAndTypeConversions'" />
+ </xsl:when>
+ <!-- no operators + type conversions -->
+ <xsl:when test="not(count($operators) &gt; 0) and count($conversions) &gt; 0">
+ <xsl:value-of select="'TypeConversions'" />
+ </xsl:when>
+ <!-- operators + no type conversions -->
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
+ <!-- overload root titles -->
+ <xsl:when test="$topic-group='root'">
+ <xsl:value-of select="$topic-group" />
+ </xsl:when>
</xsl:choose>
<xsl:text>TopicTitle</xsl:text>
</xsl:attribute>
@@ -548,10 +534,19 @@
</parameter>
<parameter>
<!-- show parameters only for overloaded members -->
- <xsl:if test="document/reference/memberdata/@overload" >
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="parameterTypesPlain" />
- </xsl:for-each>
+ <xsl:if test="document/reference/memberdata/@overload or ($api-subsubgroup = 'operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit'))">
+ <xsl:choose>
+ <xsl:when test="$api-subsubgroup = 'operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="operatorTypesPlain" />
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="parameterTypesPlain" />
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:if>
</parameter>
</include>
@@ -580,7 +575,15 @@
<xsl:when test="$topic-group='api'">
<xsl:choose>
<xsl:when test="string($api-subsubgroup)">
- <xsl:value-of select="$api-subsubgroup" />
+ <xsl:choose>
+ <!-- topic tilte for op_explicit and op_implicit members -->
+ <xsl:when test="$api-subsubgroup='operator' and (document/reference/apidata/@name = 'Explicit' or document/reference/apidata/@name = 'Implicit')">
+ <xsl:value-of select="'typeConversion'"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$api-subsubgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<xsl:when test="string($api-subgroup)">
<xsl:value-of select="$api-subgroup" />
@@ -593,13 +596,51 @@
<!-- overload topic titles -->
<xsl:when test="$topic-subgroup='overload'">
<!-- the api subgroup (e.g. "property") determines the title; do we want to use the subsubgoup name when it is available? -->
- <xsl:value-of select="$api-subgroup"/>
+ <xsl:choose>
+ <!-- topic title for overload op_explicit and op_implicit members -->
+ <xsl:when test="$api-subsubgroup = 'operator' and (document/reference/apidata/@name= 'Explicit' or document/reference/apidata/@name= 'Implicit')">
+ <xsl:value-of select="'conversionOperator'"/>
+ </xsl:when>
+ <!-- topic title for overload operator members -->
+ <xsl:when test="$api-subsubgroup='operator'">
+ <xsl:value-of select="$api-subsubgroup" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$api-subgroup"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<!-- list topic titles -->
<xsl:when test="$topic-group='list'">
<!-- the topic subgroup (e.g. "methods") determines the title -->
- <xsl:value-of select="$topic-subgroup" />
+ <xsl:choose>
+ <xsl:when test="$topic-subgroup='Operators'">
+ <xsl:variable name="operators" select="document/reference/elements/element[not(apidata[@name='Explicit' or @name='Implicit'])]"/>
+ <xsl:variable name="conversions" select="document/reference/elements/element[apidata[@name='Explicit' or @name='Implicit']]" />
+ <xsl:choose>
+ <!-- operators + type conversions -->
+ <xsl:when test="count($operators) &gt; 0 and count($conversions) &gt; 0">
+ <xsl:value-of select="'OperatorsAndTypeConversions'" />
+ </xsl:when>
+ <!-- no operators + type conversions -->
+ <xsl:when test="not(count($operators) &gt; 0) and count($conversions) &gt; 0">
+ <xsl:value-of select="'TypeConversions'" />
+ </xsl:when>
+ <!-- operators + no type conversions -->
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$topic-subgroup" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
+ <!-- overload root titles -->
+ <xsl:when test="$topic-group='root'">
+ <xsl:value-of select="$topic-group" />
+ </xsl:when>
</xsl:choose>
<xsl:text>TopicTitle</xsl:text>
<!--</xsl:otherwise>
@@ -610,10 +651,19 @@
</parameter>
<parameter>
<!-- show parameters only from overloaded members -->
- <xsl:if test="document/reference/memberdata/@overload" >
- <xsl:for-each select="/document/reference">
- <xsl:call-template name="parameterTypesDecorated" />
- </xsl:for-each>
+ <xsl:if test="document/reference/memberdata/@overload or ($api-subsubgroup= 'operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit'))">
+ <xsl:choose>
+ <xsl:when test="$api-subsubgroup = 'operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="operatorTypesDecorated" />
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:for-each select="/document/reference">
+ <xsl:call-template name="parameterTypesDecorated" />
+ </xsl:for-each>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:if>
</parameter>
</include>
@@ -630,11 +680,11 @@
<div id="mainSection">
<div id="mainBody">
- <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()">
- <include item="header" />
- </div>
-
- <!--<xsl:call-template name="head" />-->
+ <div id="allHistory" class="saveHistory" onsave="saveAll()" onload="loadAll()"/>
+
+ <!-- 'header' shared content item is used to show optional boilerplate at the top of the topic's scrolling region, e.g. pre-release boilerplate -->
+ <include item="header" />
+
<xsl:call-template name="body" />
</div>
<xsl:call-template name="foot" />
@@ -642,10 +692,6 @@
</xsl:template>
- <!--<xsl:template name="head">
- <include item="header" />
- </xsl:template>-->
-
<xsl:template name="syntaxBlocks">
<xsl:for-each select="/document/syntax/div[@codeLanguage]">
@@ -852,7 +898,7 @@
<xsl:call-template name="memberIntro" />
- <xsl:if test="element/apidata[@subgroup='constructor']">
+ <xsl:if test="element[apidata[@subgroup='constructor']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup" select="'constructor'" />
<xsl:with-param name="members" select="element[apidata[@subgroup='constructor']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -860,7 +906,7 @@
</xsl:if>
<!-- method table -->
- <xsl:if test="element/apidata[@subgroup='method' and not(@subsubgroup)]">
+ <xsl:if test="element[apidata[@subgroup='method' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">method</xsl:with-param>
<xsl:with-param name="members" select="element[apidata[@subgroup='method' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -868,7 +914,7 @@
</xsl:if>
<!-- operator table -->
- <xsl:if test="element/apidata[@subsubgroup='operator']">
+ <xsl:if test="element[apidata[@subsubgroup='operator']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">operator</xsl:with-param>
<xsl:with-param name="members" select="element[apidata[@subsubgroup='operator']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -884,7 +930,7 @@
</xsl:if>
<!-- field table -->
- <xsl:if test="element/apidata[@subgroup='field']">
+ <xsl:if test="element[apidata[@subgroup='field']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">field</xsl:with-param>
<xsl:with-param name="members" select="element[apidata[@subgroup='field']][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -892,7 +938,7 @@
</xsl:if>
<!-- property table -->
- <xsl:if test="element/apidata[@subgroup='property' and not(@subsubgroup)]">
+ <xsl:if test="element[apidata[@subgroup='property' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">property</xsl:with-param>
<xsl:with-param name="members" select="element[apidata[@subgroup='property' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -908,7 +954,7 @@
</xsl:if>
<!-- event table -->
- <xsl:if test="element/apidata[@subgroup='event' and not(@subsubgroup)]">
+ <xsl:if test="element[apidata[@subgroup='event' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">event</xsl:with-param>
<xsl:with-param name="members" select="element[apidata[@subgroup='event' and not(@subsubgroup)]][.//memberdata[@visibility='public' or @visibility='family' or @visibility='family or assembly' or @visibility='assembly'] or (.//memberdata[@visibility='private'] and not(.//proceduredata[@virtual = 'true']))]" />
@@ -927,7 +973,7 @@
<xsl:if test="element[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]">
<xsl:call-template name="memberlistSection">
<xsl:with-param name="headerGroup">ExplicitInterfaceImplementation</xsl:with-param>
- <xsl:with-param name="members" select="element[memberdata[@visibility='private'] and proceduredata[@virtual = 'true']]" />
+ <xsl:with-param name="members" select="element[.//memberdata[@visibility='private'] and .//proceduredata[@virtual = 'true']]" />
</xsl:call-template>
</xsl:if>
@@ -937,7 +983,7 @@
<xsl:param name="members"/>
<xsl:param name="headerGroup" />
<xsl:param name="showParameters" select="'false'" />
-
+
<xsl:variable name="header">
<xsl:value-of select="concat($headerGroup, 'Table')"/>
</xsl:variable>
@@ -966,7 +1012,8 @@
<!-- add a row for each member of the current subgroup-visibility -->
<xsl:apply-templates select="$members" mode="memberlistRow">
<xsl:with-param name="showParameters" select="$showParameters" />
- <xsl:sort select="apidata/@name" />
+ <xsl:sort select="topicdata/@eiiName | apidata/@name" />
+ <xsl:sort select="count(templates/*)" />
</xsl:apply-templates>
</table>
</xsl:with-param>
@@ -1111,6 +1158,36 @@
</xsl:choose>
</xsl:template>
+ <xsl:template name="IsMemberExplicit">
+ <xsl:choose>
+ <xsl:when test="element">
+ <xsl:for-each select="element">
+ <xsl:call-template name="IsMemberExplicit"/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
+ <xsl:text>yes</xsl:text>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="IsConversionOperator">
+ <xsl:choose>
+ <xsl:when test="element">
+ <xsl:for-each select="element">
+ <xsl:call-template name="IsConversionOperator"/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:if test="apidata/@subsubgroup='operator' and (apidata/@name='Explicit' or apidata/@name='Implicit') and not(memberdata/@overload)">
+ <xsl:text>yes</xsl:text>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
<xsl:template match="element" mode="memberlistRow">
<xsl:param name="showParameters" select="'false'" />
<xsl:variable name="notsupportedOnNetfw">
@@ -1140,6 +1217,12 @@
<xsl:variable name="privateMember">
<xsl:call-template name="IsMemberPrivate"/>
</xsl:variable>
+ <xsl:variable name="explicitMember">
+ <xsl:call-template name="IsMemberExplicit" />
+ </xsl:variable>
+ <xsl:variable name="conversionOperator">
+ <xsl:call-template name="IsConversionOperator" />
+ </xsl:variable>
<!-- do not show non-static members of static types -->
<xsl:if test=".//memberdata/@static='true' or not(/document/reference/typedata[@abstract='true' and @sealed='true'])">
<tr>
@@ -1154,7 +1237,7 @@
<xsl:if test="normalize-space($privateMember)!=''">
<xsl:text>private;</xsl:text>
</xsl:if>
- <xsl:if test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
+ <xsl:if test="normalize-space($explicitMember) != ''">
<xsl:text>explicit;</xsl:text>
</xsl:if>
<xsl:if test="normalize-space($staticMember)!=''">
@@ -1210,6 +1293,12 @@
</td>
<td>
<xsl:choose>
+ <xsl:when test="normalize-space($conversionOperator)!=''">
+ <referenceLink target="{@api}" show-parameters="true" />
+ </xsl:when>
+ <xsl:when test="@source='extension'">
+ <xsl:call-template name="extensionMethodDisplayLink"/>
+ </xsl:when>
<xsl:when test="@display-api">
<referenceLink target="{@api}" display-target="{@display-api}" show-parameters="{$showParameters}" />
</xsl:when>
@@ -1224,7 +1313,7 @@
<xsl:text> </xsl:text>
<include item="obsoleteRed" />
</xsl:if>
- <xsl:if test="topicdata[@subgroup='overload']">
+ <xsl:if test="topicdata[@subgroup='overload'] or @overload='true'">
<include item="Overloaded"/>
<xsl:text> </xsl:text>
</xsl:if>
@@ -1397,6 +1486,7 @@
<xsl:value-of select="concat($typeVisibility,$typeSubgroup,'.gif')" />
</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="{concat($typeVisibility,$typeSubgroup,'AltText')}" />
<includeAttribute name="title" item="{concat($typeVisibility,$typeSubgroup,'AltText')}" />
</img>
@@ -1438,6 +1528,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>pubinterface.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="ExplicitInterfaceAltText" />
<includeAttribute name="title" item="ExplicitInterfaceAltText" />
</img>
</xsl:if>
@@ -1450,9 +1541,11 @@
</includeAttribute>
<xsl:choose>
<xsl:when test="apidata/@subsubgroup">
+ <includeAttribute name="alt" item="{concat($memberVisibility,apidata/@subsubgroup,'AltText')}" />
<includeAttribute name="title" item="{concat($memberVisibility,apidata/@subsubgroup,'AltText')}" />
</xsl:when>
<xsl:otherwise>
+ <includeAttribute name="alt" item="{concat($memberVisibility,$memberSubgroup,'AltText')}" />
<includeAttribute name="title" item="{concat($memberVisibility,$memberSubgroup,'AltText')}" />
</xsl:otherwise>
</xsl:choose>
@@ -1463,6 +1556,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>static.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="staticAltText" />
<includeAttribute name="title" item="staticAltText" />
</img>
</xsl:if>
@@ -1472,6 +1566,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>CFW.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="CompactFrameworkAltText" />
<includeAttribute name="title" item="CompactFrameworkAltText" />
</img>
</xsl:if>
@@ -1481,6 +1576,7 @@
<includeAttribute name="src" item="iconPath">
<parameter>xna.gif</parameter>
</includeAttribute>
+ <includeAttribute name="alt" item="XNAFrameworkAltText" />
<includeAttribute name="title" item="XNAFrameworkAltText" />
</img>
</xsl:if>
@@ -1497,14 +1593,16 @@
<xsl:call-template name="assembliesInfo"/>
<!-- some apis display a XAML xmlns uri -->
- <xsl:call-template name="xamlXmlnsInfo"/>
+ <xsl:if test="$omitXmlnsBoilerplate != 'true'">
+ <xsl:call-template name="xamlXmlnsInfo"/>
+ </xsl:if>
</xsl:template>
<xsl:template name="assemblyNameAndModule">
<xsl:param name="library" select="/document/reference/containers/library"/>
<include item="assemblyNameAndModule">
<parameter>
- <span data="assembly">
+ <span sdata="assembly">
<xsl:value-of select="$library/@assembly"/>
</span>
</parameter>
@@ -1546,23 +1644,32 @@
<!-- Platform information -->
- <xsl:template match="platforms">
+ <xsl:template match="platforms[platform]">
<xsl:call-template name="section">
<xsl:with-param name="toggleSwitch" select="'platformsTitle'"/>
<xsl:with-param name="title">
<include item="platformsTitle" />
</xsl:with-param>
<xsl:with-param name="content">
- <p>
- <xsl:for-each select="platform">
- <include item="{.}" /><xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>
- </xsl:for-each>
- </p>
- <xsl:if test="/document/reference/versions/versions[@name='netfw' or @name='netcfw']//version">
- <p>
- <include item="SystemRequirementsLinkBoilerplate"/>
- </p>
- </xsl:if>
+ <xsl:choose>
+ <xsl:when test="/document/reference/versions/versions[@name='silverlight']//version">
+ <p>
+ <include item="silverlightplatforms"/>
+ </p>
+ </xsl:when>
+ <xsl:otherwise>
+ <p>
+ <xsl:for-each select="platform">
+ <include item="{.}" /><xsl:if test="position()!=last()"><xsl:text>, </xsl:text></xsl:if>
+ </xsl:for-each>
+ </p>
+ <xsl:if test="/document/reference/versions/versions[@name='netfw' or @name='netcfw']//version">
+ <p>
+ <include item="SystemRequirementsLinkBoilerplate"/>
+ </p>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
@@ -1570,15 +1677,17 @@
<!-- Version information -->
<xsl:template match="versions">
- <xsl:call-template name="section">
- <xsl:with-param name="toggleSwitch" select="'versionsTitle'"/>
- <xsl:with-param name="title">
- <include item="versionsTitle" />
- </xsl:with-param>
- <xsl:with-param name="content">
- <xsl:call-template name="processVersions" />
- </xsl:with-param>
- </xsl:call-template>
+ <xsl:if test="$omitVersionInformation != 'true'">
+ <xsl:call-template name="section">
+ <xsl:with-param name="toggleSwitch" select="'versionsTitle'"/>
+ <xsl:with-param name="title">
+ <include item="versionsTitle" />
+ </xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:call-template name="processVersions" />
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
</xsl:template>
<xsl:template name="processVersions">
@@ -1664,6 +1773,7 @@
<xsl:for-each select="ancestors/type">
<xsl:sort select="position()" data-type="number" order="descending" />
+ <!-- <xsl:sort select="@api"/> -->
<xsl:call-template name="indent">
<xsl:with-param name="count" select="position()" />
@@ -1696,6 +1806,9 @@
<xsl:otherwise>
<xsl:for-each select="descendents/type">
+ <xsl:sort select="@api" />
+
+ <xsl:if test="not(self::type/@api=preceding-sibling::*/self::type/@api)">
<xsl:call-template name="indent">
<xsl:with-param name="count" select="$ancestorCount + 2" />
</xsl:call-template>
@@ -1705,6 +1818,7 @@
</xsl:apply-templates>
<br/>
+ </xsl:if>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
@@ -1761,6 +1875,7 @@
<span class="vb">.</span>
<span class="cpp">::</span>
<span class="nu">.</span>
+ <span class="fs">.</span>
</span>
<xsl:for-each select="/document/reference/implements/member">
<xsl:for-each select="type">
@@ -1771,6 +1886,7 @@
<span class="vb">.</span>
<span class="cpp">::</span>
<span class="nu">.</span>
+ <span class="fs">.</span>
</span>
<xsl:value-of select="apidata/@name" />
<xsl:apply-templates select="templates" mode="decorated" />
@@ -1781,14 +1897,37 @@
<xsl:for-each select="/document/reference/containers/type[1]">
<xsl:call-template name="typeNameDecorated" />
</xsl:for-each>
- <span class="languageSpecificText">
- <span class="cs">.</span>
- <span class="vb">.</span>
- <span class="cpp">::</span>
- <span class="nu">.</span>
- </span>
+ <xsl:if test="not($api-subsubgroup='operator'and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit'))">
+ <span class="languageSpecificText">
+ <span class="cs">.</span>
+ <span class="vb">.</span>
+ <span class="cpp">::</span>
+ <span class="nu">.</span>
+ <span class="fs">.</span>
+ </span>
+ </xsl:if>
<xsl:for-each select="/document/reference[1]">
- <xsl:value-of select="apidata/@name" />
+ <xsl:choose>
+ <xsl:when test="$api-subsubgroup='operator' and (apidata/@name='Explicit' or apidata/@name='Implicit')">
+ <xsl:text>&#xa0;</xsl:text>
+ <span class="languageSpecificText">
+ <span class="cs"><xsl:value-of select="apidata/@name" /></span>
+ <span class="vb">
+ <xsl:choose>
+ <xsl:when test="apidata/@name='Explicit'"><xsl:text>Narrowing</xsl:text></xsl:when>
+ <xsl:when test="apidata/@name='Implicit'"><xsl:text>Widening</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="apidata/@name" /></xsl:otherwise>
+ </xsl:choose>
+ </span>
+ <span class="cpp"><xsl:value-of select="apidata/@name" /></span>
+ <span class="nu"><xsl:value-of select="apidata/@name" /></span>
+ <span class="fs"><xsl:value-of select="apidata/@name" /></span>
+ </span>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="apidata/@name" />
+ </xsl:otherwise>
+ </xsl:choose>
<xsl:apply-templates select="templates" mode="decorated" />
</xsl:for-each>
</xsl:when>
@@ -1826,7 +1965,14 @@
<xsl:for-each select="/document/reference/containers/type[1]">
<xsl:call-template name="typeNamePlain" />
</xsl:for-each>
- <xsl:text>.</xsl:text>
+ <xsl:choose>
+ <xsl:when test="$api-subsubgroup='operator' and (document/reference/apidata/@name='Explicit' or document/reference/apidata/@name='Implicit')">
+ <xsl:text>&#xa0;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>.</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:if>
<xsl:choose>
<!-- EII names are interfaceName.interfaceMemberName, not memberName -->
diff --git a/tools/Sandcastle/Presentation/vs2005/transforms/xamlSyntax.xsl b/tools/Sandcastle/Presentation/vs2005/transforms/xamlSyntax.xsl
index 1fc6e45..0fe5223 100644
--- a/tools/Sandcastle/Presentation/vs2005/transforms/xamlSyntax.xsl
+++ b/tools/Sandcastle/Presentation/vs2005/transforms/xamlSyntax.xsl
@@ -109,8 +109,6 @@
</xsl:with-param>
</xsl:call-template>
</xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
</xsl:template>
<!-- XAML syntax for ENUMERATION topics. This is the logic:
@@ -151,8 +149,6 @@
</span>
</xsl:when>
</xsl:choose>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
</xsl:template>
<!-- XAML syntax for PROPERTY topics. This is the logic:
@@ -222,8 +218,6 @@
</xsl:with-param>
</xsl:call-template>
</xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
</xsl:template>
<!-- XAML syntax for EVENT topics. This is the logic:
@@ -259,8 +253,6 @@
</xsl:with-param>
</xsl:call-template>
</xsl:if>
- <!-- Show the authored XAML Values section, if any. -->
- <xsl:call-template name="showXamlValuesSection"/>
</xsl:template>
<!-- XAML syntax for members that cannot be used in XAML: interface, delegate, method, field, constructor.
@@ -283,19 +275,19 @@
<!-- Displays one of the standard XAML boilerplate strings. -->
<xsl:template name="ShowXamlSyntaxBoilerplate">
<xsl:param name="param0"/>
+ <!-- TFS bug 303004: DO NOT SHOW ANY xaml syntax boilerplate strings. -->
+ <xsl:variable name="boilerplateId"/>
+
+ <!-- If future requirements call for showing one or more boilerplate strings for xaml,
+ use the commented out code to specify the ids of the shared content items to include.
+ NOTE: the markup like div/@class[.='interfaceOverviewXamlSyntax' is added by XamlUsageSyntax.cs in BuildAssembler. -->
+ <!--
<xsl:variable name="boilerplateId">
- <xsl:choose>
- <!-- don't show boilerplate for apis that are not in xaml assemblies -->
- <xsl:when test="$showNonXamlAssemblyBoilerplate='false' and div[@class='nonXamlAssemblyBoilerplate']"/>
- <xsl:otherwise>
- <xsl:value-of select="div/@class[not(.='xamlAttributeUsageHeading' or
- .='xamlObjectElementUsageHeading' or
- .='xamlContentElementUsageHeading' or
- .='xamlPropertyElementUsageHeading' or
- .='xamlXmlnsUri')]"/>
- </xsl:otherwise>
- </xsl:choose>
+ <xsl:value-of select="div/@class[.='interfaceOverviewXamlSyntax' or
+ .='propertyXamlSyntax_abstractType' or
+ .='classXamlSyntax_abstract']"/>
</xsl:variable>
+ -->
<xsl:if test="$boilerplateId!=''">
<span codeLanguage="XAML">
@@ -402,7 +394,7 @@
<!-- Display the XAML Values section. -->
<xsl:template name="showXamlValuesSection">
<xsl:for-each select="//ddue:section[starts-with(@address,'xamlValues')]">
- <span codeLanguage="XAML">
+ <div id="xamlValues">
<p/>
<xsl:call-template name="subSection">
<xsl:with-param name="title">
@@ -412,7 +404,7 @@
<xsl:apply-templates select="ddue:content"/>
</xsl:with-param>
</xsl:call-template>
- </span>
+ </div>
</xsl:for-each>
</xsl:template>
diff --git a/tools/Sandcastle/ProductionTools/.gitignore b/tools/Sandcastle/ProductionTools/.gitignore
new file mode 100644
index 0000000..056527a
--- /dev/null
+++ b/tools/Sandcastle/ProductionTools/.gitignore
@@ -0,0 +1,4 @@
+*.exe
+*.dll
+*.pdb
+*.config
diff --git a/tools/Sandcastle/ProductionTools/AggregateByNamespace.exe b/tools/Sandcastle/ProductionTools/AggregateByNamespace.exe
deleted file mode 100644
index 66f7cd8..0000000
--- a/tools/Sandcastle/ProductionTools/AggregateByNamespace.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/BuildAssembler.exe b/tools/Sandcastle/ProductionTools/BuildAssembler.exe
deleted file mode 100644
index 2816d64..0000000
--- a/tools/Sandcastle/ProductionTools/BuildAssembler.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/BuildAssemblerLibrary.dll b/tools/Sandcastle/ProductionTools/BuildAssemblerLibrary.dll
deleted file mode 100644
index 8ef4359..0000000
--- a/tools/Sandcastle/ProductionTools/BuildAssemblerLibrary.dll
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/BuildComponents.dll b/tools/Sandcastle/ProductionTools/BuildComponents.dll
deleted file mode 100644
index 3e556a0..0000000
--- a/tools/Sandcastle/ProductionTools/BuildComponents.dll
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/ChmBuilder.exe b/tools/Sandcastle/ProductionTools/ChmBuilder.exe
deleted file mode 100644
index 1896cb1..0000000
--- a/tools/Sandcastle/ProductionTools/ChmBuilder.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/CommandLine.dll b/tools/Sandcastle/ProductionTools/CommandLine.dll
deleted file mode 100644
index b569b0a..0000000
--- a/tools/Sandcastle/ProductionTools/CommandLine.dll
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/DBCSFix.exe b/tools/Sandcastle/ProductionTools/DBCSFix.exe
deleted file mode 100644
index bcebc50..0000000
--- a/tools/Sandcastle/ProductionTools/DBCSFix.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/MrefBuilder.exe b/tools/Sandcastle/ProductionTools/MrefBuilder.exe
deleted file mode 100644
index e0fe3c7..0000000
--- a/tools/Sandcastle/ProductionTools/MrefBuilder.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/SegregateByAssembly.exe b/tools/Sandcastle/ProductionTools/SegregateByAssembly.exe
deleted file mode 100644
index e7632b8..0000000
--- a/tools/Sandcastle/ProductionTools/SegregateByAssembly.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/SyntaxComponents.dll b/tools/Sandcastle/ProductionTools/SyntaxComponents.dll
deleted file mode 100644
index 27e100b..0000000
--- a/tools/Sandcastle/ProductionTools/SyntaxComponents.dll
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/VersionBuilder.exe b/tools/Sandcastle/ProductionTools/VersionBuilder.exe
deleted file mode 100644
index cad3e4d..0000000
--- a/tools/Sandcastle/ProductionTools/VersionBuilder.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/XslTransform.exe b/tools/Sandcastle/ProductionTools/XslTransform.exe
deleted file mode 100644
index cc23488..0000000
--- a/tools/Sandcastle/ProductionTools/XslTransform.exe
+++ /dev/null
Binary files differ
diff --git a/tools/Sandcastle/ProductionTools/scbuild.ps1 b/tools/Sandcastle/ProductionTools/scbuild.ps1
index 62461c4..da26199 100644
--- a/tools/Sandcastle/ProductionTools/scbuild.ps1
+++ b/tools/Sandcastle/ProductionTools/scbuild.ps1
@@ -25,7 +25,7 @@
# -DxRoot {path} -- alternate DxRoot. Default: DxRoot environment variable.
#
# -Framework {version} -- build depends on framework version specified. Currently
-# supported: 2.0, 3.0. Default: no framework dependencies.
+# supported: 2.0, 3.0, 3.5. Default: no framework dependencies.
#
# -Lcid {version} -- locale ID for help file. Default: 1033
#
@@ -36,6 +36,8 @@
# -Name {path-name} -- name of output file (or directory for Website builds).
# Default: The name and location of the first assembly listed.
#
+# -ScriptSharp -- remove topics that do not apply for Script#
+#
# -Sources {files} -- comma separated list of files that should be added to the
# output, both assemblies and related comment files. To build, you must
# specify at least one assembly and comment file.
@@ -77,7 +79,7 @@ param (
[Switch]$BuildHxS,
[Switch]$BuildWebsite,
[Switch]$Clean,
- [Switch]$Test,
+ [Switch]$Test,
# Resources, Folders, Options
[String]$BuildAssemblerConfig,
@@ -92,7 +94,9 @@ param (
[String]$Style,
[String]$TempDir,
[String]$WebBuildConfig,
- [String]$WebTemplate
+ [String]$WebTemplate,
+ [Switch]$ScriptSharp
+
)
#
@@ -169,6 +173,8 @@ function Init {
InitOption BuildHxS $false
InitOption BuildWebSite $false
InitOption Test $false
+ InitOption ScriptSharp $false
+
if (-not ($Clean -or $BuildChm -or $BuildHxs -or $BuildWebsite -or $Test)) {
FatalError "You must specify a build action: -Clean, -BuildChm, -BuildHxs, -BuildWebsite."
}
@@ -390,16 +396,22 @@ function BuildWebsite {
# Generate reflection data if the current style does not match the style the caller is
# looking for.
#
+# The list of dependencies is split up and seperated by a comma to be passed to mrefbuilder.
+#
function GenerateReflectionData {
$fdirs = $($FrameworkDirs[$Framework])
if ($fdirs -is [String]) {
$fdirs = @($fdirs)
+ }
+
+ if($fdirs) {
+ foreach ($fdir in $fdirs) {
+ GenerateDependencyReflectionData (get-childitem -r -include "*.dll" $fdir) $TempDir\ReflectionData\Framework "" $false
+ }
}
- foreach ($fdir in $fdirs) {
- GenerateDependencyReflectionData (get-childitem -r -include "*.dll" $fdir) $TempDir\ReflectionData\Framework
- }
- GenerateDependencyReflectionData $Dependencies "$TempDir\ReflectionData\Dependencies"
- GenerateTargetReflectionData $Targets "$TempDir\ReflectionData\targets.xml"
+
+ GenerateDependencyReflectionData $Dependencies "$TempDir\ReflectionData\Dependencies" $Dependencies $ScriptSharp
+ GenerateTargetReflectionData $Targets "$TempDir\ReflectionData\targets.xml" $Dependencies $ScriptSharp
}
@@ -408,7 +420,7 @@ function GenerateReflectionData {
# dependencies. The data is used as is from MrefBuilder. No post processing occurs. The
# file is generated only if the output doesn't exist already.
#
-function GenerateDependencyReflectionData($assemblies, $outputDir) {
+function GenerateDependencyReflectionData($assemblies, $outputDir, $dependencyAssemblies, $applyScriptSharp) {
if ($assemblies -is [String]) {
$assemblies = ExpandWildcards $assemblies
}
@@ -416,7 +428,7 @@ function GenerateDependencyReflectionData($assemblies, $outputDir) {
foreach ($pn in $assemblies) {
$outputFile = "$outputDir\$([IO.Path]::ChangeExtension($pn.Name, '.xml'))"
if (-not (test-path $outputFile)) {
- GenerateTargetReflectionData $pn $outputFile
+ GenerateTargetReflectionData $pn $outputFile $dependencyAssemblies $applyScriptSharp
copy-item -ea SilentlyContinue $([IO.Path]::ChangeExtension($pn.FullName, '.xml')) $TempDir\Comments
}
}
@@ -429,16 +441,32 @@ function GenerateDependencyReflectionData($assemblies, $outputDir) {
# assemblies. The data for all target assemblies is combined into a single file and then
# post processed using different transforms depending on doc style.
#
-function GenerateTargetReflectionData($assemblies, $outputFile) {
+# Dependencies are passed to mrefbuilder if there are any.
+#
+function GenerateTargetReflectionData($assemblies, $outputFile, $dependencyAssemblies, $applyScriptSharp) {
if ($assemblies -is [String]) {
$assemblies = ExpandWildcards $assemblies
}
WriteInfo "Generate reflection data for: $assemblies"
$targetFiles = [String]::Join(" ", ($assemblies | foreach {"`"$_`""}))
$tmpName = "$TempDir\tmp.xml"
- &$MrefBuilder $targetFiles /out:$tmpName
+
+ if ($dependencyAssemblies) {
+ $dependencyFiles = [String]::Join(",", ($dependencyAssemblies | foreach {"`"$_`""}))
+ &$MrefBuilder /dep:$dependencyFiles /out:$tmpName $targetFiles
+ } else {
+ &$MrefBuilder /out:$tmpName $targetFiles
+ }
+
+ if ($applyScriptSharp) {
+ $tmpFixedName = "$TempDir\tmp-Fixed.xml"
+ ApplyFixScriptSharp $tmpName $tmpFixedName
+ SafeDelete $tmpName
+ $tmpName = $tmpFixedName
+ }
+
PostProcessReflectionData $tmpName $outputFile
- SafeDelete $tmpName
+ SafeDelete $tmpName
}
#
@@ -449,6 +477,15 @@ function PostProcessReflectionData {
FatalError "Doc Model must define a PostProcessReflectionData function."
}
+#
+# ScriptSharp requires an additional transform to remove unneeded elements.
+#
+function ApplyFixScriptSharp($tmpName, $tmpFixedName) {
+ &$XslTransform $tmpName `
+ /xsl:$DxRoot\ProductionTransforms\FixScriptSharp.xsl `
+ /out:$tmpFixedName
+}
+
#
# GenerateManifest() -- creates a manifest from the reflection data. This requires
@@ -610,6 +647,7 @@ function Test {
echo "+ Mixin: $Mixin"
echo "+ Name: $Name"
echo "+ [OutputDir]: $OutputDir"
+ echo "+ ScriptSharp: $ScriptSharp"
echo "+ Sources: $Sources"
echo "+ Style: $Style"
echo "+ [Targets]: $Targets"
diff --git a/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl b/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl
index bdfde07..bf7d441 100644
--- a/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl
+++ b/tools/Sandcastle/ProductionTransforms/ApplyPrototypeDocModel.xsl
@@ -128,7 +128,7 @@
<xsl:template name="projectTopic">
<api id="R:{$project}">
- <topicdata group="list" subgroup="namespaces" />
+ <topicdata group="root" />
<elements>
<xsl:for-each select="/*/apis/api[apidata/@group='namespace']">
<element api="{@id}" />
diff --git a/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl b/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl
index d5a3751..b7729d0 100644
--- a/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl
+++ b/tools/Sandcastle/ProductionTransforms/ApplyVSDocModel.xsl
@@ -10,13 +10,14 @@
<!-- Set to true for vs2005; set to false for vsorcas/prototype. -->
<xsl:param name="IncludeAllMembersTopic" select="'false'" />
-
+
<!-- If member list topics handle overloads with one row that points to an overload topic, set IncludeInheritedOverloadTopics to false. -->
<!-- If member list topics show a separate row for each overload signature, set IncludeInheritedOverloadTopics to false. -->
<xsl:param name="IncludeInheritedOverloadTopics" select="'true'" />
<xsl:key name="index" match="/reflection/apis/api" use="@id" />
+ <xsl:variable name="root" select="/" />
<xsl:template match="/">
<reflection>
<xsl:apply-templates select="/reflection/assemblies" />
@@ -32,13 +33,13 @@
<apis>
<xsl:apply-templates select="api" />
<xsl:if test="normalize-space($project)">
- <xsl:call-template name="projectTopic" />
+ <xsl:call-template name="projectTopic" />
</xsl:if>
</apis>
</xsl:template>
<!-- Process a generic API (for namespaces and members; types and overloads are handled explicitly below) -->
-
+
<xsl:template match="api">
<xsl:call-template name="updateApiNode" />
</xsl:template>
@@ -48,11 +49,21 @@
</xsl:template>
<xsl:template name="updateApiNode">
- <xsl:variable name="name" select="apidata/@name"/>
+ <xsl:variable name="apidataName" select="apidata/@name"/>
+ <xsl:variable name="templatesTotal" select="count(templates/*)"/>
+ <xsl:variable name="templateParams" select="count(templates/template)"/>
+ <xsl:variable name="templateArgs" select="count(templates/*[not(self::template)])"/>
+ <!-- strip off any parameters from the end of the id -->
+ <xsl:variable name="idWithoutParams">
+ <xsl:call-template name="RemoveParametersFromId"/>
+ </xsl:variable>
<xsl:variable name="subgroup" select="apidata/@subgroup"/>
- <xsl:variable name="subsubgroup" select="apidata/@subsubgroup"/>
+ <xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
<xsl:variable name="typeId" select="containers/type/@api"/>
<xsl:variable name="isEII" select="proceduredata/@eii"/>
+ <xsl:variable name="eiiTypeId" select="implements/member/type/@api" />
+ <xsl:variable name="containingType" select="containers/type/@api"/>
+
<api>
<xsl:copy-of select="@*"/>
<topicdata group="api">
@@ -60,69 +71,120 @@
<!-- enum members do not get separate topics; mark them so they are excluded from the manifest -->
<xsl:attribute name="notopic"/>
</xsl:if>
- </topicdata>
- <xsl:for-each select="*">
- <xsl:choose>
- <xsl:when test="local-name(.)='containers'">
- <xsl:variable name="assembly" select="library/@assembly"/>
+ <xsl:if test="proceduredata[@eii='true']">
+ <xsl:attribute name="eiiName">
<xsl:choose>
- <xsl:when test="not(/*/assemblies/assembly[@name=$assembly]/attributes/attribute[type/@api='T:System.Security.AllowPartiallyTrustedCallersAttribute'])">
- <containers>
- <library>
- <xsl:copy-of select="library/@*"/>
- <noAptca/>
- </library>
- <xsl:copy-of select="namespace"/>
- <xsl:copy-of select="type"/>
- </containers>
+ <xsl:when test="$templatesTotal>0">
+ <xsl:value-of select="concat(key('index', $eiiTypeId)/apidata/@name, '.', $apidataName,'``',string($templatesTotal))"/>
</xsl:when>
<xsl:otherwise>
- <xsl:copy-of select="."/>
+ <xsl:value-of select="concat(key('index', $eiiTypeId)/apidata/@name, '.', $apidataName)"/>
</xsl:otherwise>
</xsl:choose>
+ </xsl:attribute>
+ </xsl:if>
+ </topicdata>
+ <xsl:for-each select="*">
+ <xsl:choose>
+ <xsl:when test="local-name(.)='containers'">
+ <containers>
+ <xsl:for-each select="library">
+ <xsl:call-template name="addLibraryAssemblyData">
+ <xsl:with-param name="addNoAptca" select="'true'" />
+ </xsl:call-template>
+ </xsl:for-each>
+ <xsl:copy-of select="namespace"/>
+ <xsl:copy-of select="type"/>
+ </containers>
</xsl:when>
<xsl:when test="local-name(.)='memberdata'">
- <xsl:choose>
- <xsl:when test="$isEII='true'">
- <xsl:copy-of select="."/>
- </xsl:when>
- <xsl:otherwise>
- <memberdata>
- <xsl:copy-of select="@*"/>
- <!-- if the member is overloaded, add @overload = id of overload topic, if any -->
- <xsl:choose>
- <!-- skip this processing for members that cannot be overloaded -->
- <xsl:when test="$subgroup='field'"/>
- <xsl:otherwise>
- <xsl:variable name="siblingElements" select="key('index',$typeId)/elements"/>
- <xsl:variable name="siblingApiInfo" select="key('index',$siblingElements/element[not(apidata)]/@api) | $siblingElements/element[apidata]" />
- <xsl:variable name="overloadSet" select="$siblingApiInfo[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]" />
- <xsl:variable name="signatureSet">
- <xsl:call-template name="GetSignatureSet">
- <xsl:with-param name="name" select="$name" />
- <xsl:with-param name="overloadSet" select="$overloadSet"/>
- <xsl:with-param name="typeId" select="$typeId"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:if test="count(msxsl:node-set($signatureSet)/*) &gt; 1">
- <!-- the api is overloaded, so add @overload = idOfOverloadTopic -->
- <xsl:attribute name="overload">
- <xsl:call-template name="overloadId">
- <xsl:with-param name="typeId" select="$typeId"/>
- <xsl:with-param name="name" select="$name"/>
- <xsl:with-param name="subgroup" select="$subgroup"/>
- <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
- </xsl:call-template>
- </xsl:attribute>
- </xsl:if>
-
- </xsl:otherwise>
- </xsl:choose>
- <!-- memberdata shouldn't have any children, but copy just in case -->
- <xsl:copy-of select="*"/>
- </memberdata>
- </xsl:otherwise>
- </xsl:choose>
+ <memberdata>
+ <xsl:copy-of select="@*"/>
+ <!-- if the member is overloaded, add @overload = id of overload topic, if any -->
+ <xsl:choose>
+ <!-- skip this processing for members that cannot be overloaded -->
+ <xsl:when test="$subgroup='field'"/>
+ <xsl:when test="$isEII='true'">
+ <!-- get all the elements of this type -->
+ <xsl:variable name="siblingElements" select="key('index',$typeId)/elements"/>
+ <!-- get the reflection data for each element, e.g. parameters, apidata, etc. -->
+ <xsl:variable name="siblingApiInfo" select="key('index',$siblingElements/element[not(apidata)]/@api) | $siblingElements/element[apidata]" />
+ <!-- get the set of sibling elements that are overloads of the current member -->
+ <xsl:variable name="overloadSet" select="
+ $siblingApiInfo[
+ proceduredata/@eii='true' and implements/member/type/@api=$eiiTypeId and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]" />
+ <!-- When the reflection data includes multiple versions, $overloadSet may include multiple elements that have
+ the same signature (same params and return type), which we call a signatureset.
+ For example, NetFx and CF apis that have the same signature but different ids.
+ These are treated as a primary <element> node for the NetFx api, with a nested <element> node for CF api.
+ -->
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="apidataName" select="$apidataName" />
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <!-- it's an overload if there are multiple signaturesets -->
+ <xsl:if test="count(msxsl:node-set($signatureSet)/*) &gt; 1">
+ <!-- the api is overloaded, so add @overload = idOfOverloadTopic -->
+ <xsl:attribute name="overload">
+ <xsl:call-template name="eiiOverloadId">
+ <xsl:with-param name="typeId" select="$containingType" />
+ <xsl:with-param name="idWithoutParams" select="$idWithoutParams"/>
+ <xsl:with-param name="containingTypeName" select="substring($containingType,3)"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="siblingElements" select="key('index',$typeId)/elements"/>
+ <xsl:variable name="siblingApiInfo" select="key('index',$siblingElements/element[not(apidata)]/@api) | $siblingElements/element[apidata]" />
+ <xsl:variable name="overloadSet" select="
+ $siblingApiInfo[
+ not(proceduredata/@eii='true') and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]" />
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="apidataName" select="$apidataName" />
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="count(msxsl:node-set($signatureSet)/*) &gt; 1">
+ <!-- the api is overloaded, so add @overload = idOfOverloadTopic -->
+ <xsl:attribute name="overload">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ <xsl:with-param name="name" select="$apidataName"/>
+ <xsl:with-param name="templatesTotal" select="$templatesTotal"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- memberdata shouldn't have any children, but copy just in case -->
+ <xsl:copy-of select="*"/>
+ </memberdata>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
@@ -133,7 +195,7 @@
</xsl:template>
<!-- Special logic for type APIs -->
-
+
<xsl:template name="UpdateTypeApiNode">
<xsl:param name="derivedTypesTopicId" />
<xsl:param name="allMembersTopicId" />
@@ -148,7 +210,7 @@
<topicdata group="api" />
</xsl:otherwise>
</xsl:choose>
-
+
<xsl:for-each select="*">
<xsl:choose>
<xsl:when test="self::elements">
@@ -185,6 +247,15 @@
</descendents>
</family>
</xsl:when>
+ <xsl:when test="local-name(.)='containers'">
+ <containers>
+ <xsl:for-each select="library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="namespace"/>
+ <xsl:copy-of select="type"/>
+ </containers>
+ </xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
@@ -193,8 +264,22 @@
</api>
</xsl:template>
+ <xsl:template name="addLibraryAssemblyData">
+ <xsl:param name="addNoAptca" />
+ <xsl:variable name="assembly" select="@assembly"/>
+ <library>
+ <xsl:copy-of select="@*"/>
+ <xsl:for-each select="/*/assemblies/assembly[@name=$assembly]/assemblydata">
+ <assemblydata version="{@version}" />
+ </xsl:for-each>
+ <xsl:if test="$addNoAptca='true' and not(/*/assemblies/assembly[@name=$assembly]/attributes/attribute[type/@api='T:System.Security.AllowPartiallyTrustedCallersAttribute'])">
+ <noAptca/>
+ </xsl:if>
+ </library>
+ </xsl:template>
+
<!-- Type logic; types get a lot of massaging to create member list pages, overload pages, etc. -->
-
+
<xsl:template match="api[apidata/@group='type']">
<xsl:variable name="typeId" select="@id" />
@@ -236,7 +321,13 @@
<element api="{@api}" />
</xsl:for-each>
</elements>
- <xsl:copy-of select="containers" />
+ <containers>
+ <xsl:for-each select="containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="containers/namespace"/>
+ <xsl:copy-of select="containers/type"/>
+ </containers>
</api>
</xsl:if>
@@ -257,21 +348,31 @@
<xsl:with-param name="typeId" select="$typeId"/>
</xsl:call-template>
</xsl:for-each>
- <xsl:copy-of select="containers" />
+ <containers>
+ <xsl:for-each select="containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="containers/namespace"/>
+ <xsl:copy-of select="containers/type"/>
+ </containers>
</api>
</xsl:if>
- <!-- method/operator list topic -->
- <!-- pass in $declaredMembers and $members so subsubgroup=operator is not exclude -->
- <xsl:variable name="declaredPrefix" select="concat(substring-after($typeId,':'), '.')"/>
+ <!-- method/extension method list topic -->
+ <!-- pass in $members so subsubgroup=operator IS excluded and subsubgroup=extension IS NOT excluded -->
<xsl:call-template name="AddMemberlistAPI">
<xsl:with-param name="subgroup">method</xsl:with-param>
<xsl:with-param name="topicSubgroup">Methods</xsl:with-param>
<xsl:with-param name="typeId" select="$typeId" />
- <xsl:with-param name="declaredMembers" select="key('index',elements/element[not(apidata)][starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[@subgroup='method']]
- | elements/element[starts-with(substring-after(@api,':'), $declaredPrefix)][apidata[@subgroup='method']]"/>
- <xsl:with-param name="members" select="key('index',elements/element[not(apidata)]/@api)[apidata[@subgroup='method']]
- | elements/element[apidata[@subgroup='method']]"/>
+ <xsl:with-param name="members" select="key('index',elements/element[not(apidata)]/@api)[apidata[@subgroup='method' and not(@subsubgroup='operator')]]
+ | elements/element[apidata[@subgroup='method' and not(@subsubgroup='operator')]]"/>
+ </xsl:call-template>
+
+ <!-- operator list topic -->
+ <xsl:call-template name="AddMemberlistAPI">
+ <xsl:with-param name="subsubgroup">operator</xsl:with-param>
+ <xsl:with-param name="topicSubgroup">Operators</xsl:with-param>
+ <xsl:with-param name="typeId" select="$typeId" />
</xsl:call-template>
<!-- propety list topic -->
@@ -315,11 +416,25 @@
</xsl:call-template>
</xsl:if>
-
+
+ </xsl:template>
+
+ <!-- -->
+ <xsl:template name="RemoveParametersFromId">
+ <xsl:variable name="memberId" select="@id | @api"/>
+ <xsl:variable name="paramString" select="substring-after($memberId,'(')"/>
+ <xsl:choose>
+ <xsl:when test="boolean($paramString)">
+ <xsl:value-of select="substring-before($memberId,'(')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$memberId"/>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:template>
<!-- overload topics -->
-
+
<xsl:template name="overloadTopics">
<xsl:param name="allMembersTopicId"/>
<xsl:variable name="typeId" select="@id"/>
@@ -327,76 +442,212 @@
<xsl:variable name="declaredPrefix" select="concat(substring($typeId,2), '.')"/>
<xsl:for-each select="$members">
- <xsl:variable name="name" select="apidata/@name" />
- <xsl:variable name="memberId" select="@id | @api"/>
+ <xsl:variable name="apidataName" select="apidata/@name"/>
+ <xsl:variable name="templatesTotal" select="count(templates/*)"/>
+ <xsl:variable name="templateParams" select="count(templates/template)"/>
+ <xsl:variable name="templateArgs" select="count(templates/*[not(self::template)])"/>
+ <!-- strip off any parameters from the end of the id -->
+ <xsl:variable name="idWithoutParams">
+ <xsl:call-template name="RemoveParametersFromId"/>
+ </xsl:variable>
<xsl:variable name="subgroup" select="apidata/@subgroup" />
<xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
+ <xsl:variable name="memberId" select="@id | @api"/>
+
+ <xsl:choose>
+ <!-- handle EII members -->
+ <xsl:when test="proceduredata/@eii='true'">
+ <xsl:variable name="eiiTypeId" select="implements/member/type/@api" />
+ <!-- get the set of overloads: EII members with same name and subgroup -->
+ <xsl:variable name="overloadSet" select="
+ $members[
+ proceduredata/@eii='true' and implements/member/type/@api=$eiiTypeId and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]" />
+
+ <!-- are there any declared members in the overload set? -->
+ <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
- <!-- EII members are not treated as overloads -->
- <xsl:if test="not(proceduredata/@eii='true')">
- <!-- get the set of non-EII members with same name and subgroup -->
- <xsl:variable name="overloadSet" select="$members[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]" />
-
- <!-- are there any declared members in the overload set? -->
- <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
-
- <!-- if more than one member in overloadSet, add an overload topic if necessary -->
- <xsl:if test="(count($overloadSet) &gt; 1) and $overloadSet[1][@id=$memberId or @api=$memberId]">
- <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
+ <!-- if more than one member in overloadSet, add an overload topic if necessary -->
+ <xsl:if test="(count($overloadSet) &gt; 1) and $overloadSet[1][@id=$memberId or @api=$memberId]">
+ <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
e.g. when one version inherits a member and another version overrides it.
We want an overload topic only when there are multiple signatures. -->
- <!-- get the set of unique signatures for this overload set -->
- <xsl:variable name="signatureSet">
- <xsl:call-template name="GetSignatureSet">
- <xsl:with-param name="overloadSet" select="$overloadSet"/>
- <xsl:with-param name="typeId" select="$typeId"/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <!-- don't need an overload topic if only one signature -->
- <xsl:when test="count(msxsl:node-set($signatureSet)/*) &lt; 2"/>
- <!-- don't need an overload topic if all overloads are inherited and config'd to omit overload topics when all are inherited -->
- <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')"/>
- <xsl:otherwise>
- <api>
- <xsl:attribute name="id">
- <xsl:call-template name="overloadId">
- <xsl:with-param name="typeId" select="$typeId"/>
- <xsl:with-param name="name" select="$name"/>
- <xsl:with-param name="subgroup" select="$subgroup"/>
- <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
- </xsl:call-template>
- </xsl:attribute>
- <topicdata name="{apidata/@name}" group="list" subgroup="overload" memberSubgroup="{$subgroup}" pseudo="true" allMembersTopicId="{$allMembersTopicId}">
- <xsl:if test="not(boolean($declaredMembers))">
- <xsl:attribute name="allInherited">true</xsl:attribute>
- </xsl:if>
- </topicdata>
- <xsl:copy-of select="apidata" />
- <!-- elements -->
- <elements>
- <xsl:for-each select="msxsl:node-set($signatureSet)/*">
- <xsl:copy-of select="."/>
- </xsl:for-each>
- </elements>
- <!-- containers -->
- <xsl:choose>
- <xsl:when test="boolean($declaredMembers)">
- <xsl:copy-of select="$declaredMembers[1]/containers"/>
- </xsl:when>
- <xsl:otherwise>
- <containers>
- <xsl:copy-of select="key('index',$typeId)/containers/library"/>
- <xsl:copy-of select="key('index',$typeId)/containers/namespace"/>
- <type api="{$typeId}"/>
- </containers>
- </xsl:otherwise>
- </xsl:choose>
- </api>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:if>
+ <!-- get the set of unique signatures for this overload set -->
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <!-- don't need an overload topic if only one signature -->
+ <xsl:when test="count(msxsl:node-set($signatureSet)/*) &lt; 2"/>
+ <!-- don't need an overload topic if all overloads are inherited and config'd to omit overload topics when all are inherited -->
+ <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')"/>
+ <!-- otherwise, add an overload topic -->
+ <xsl:otherwise>
+ <api>
+ <xsl:attribute name="id">
+ <xsl:call-template name="eiiOverloadId">
+ <xsl:with-param name="typeId" select="$typeId" />
+ <xsl:with-param name="idWithoutParams" select="$idWithoutParams"/>
+ <xsl:with-param name="containingTypeName" select="substring(containers/type/@api,3)"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="overload" memberSubgroup="{$subgroup}" pseudo="true" allMembersTopicId="{$allMembersTopicId}">
+ <xsl:if test="not(boolean($declaredMembers))">
+ <xsl:attribute name="allInherited">true</xsl:attribute>
+ <xsl:attribute name="parentTopicId">
+ <xsl:call-template name="eiiOverloadId">
+ <xsl:with-param name="typeId" select="containers/type/@api" />
+ <xsl:with-param name="idWithoutParams" select="$idWithoutParams"/>
+ <xsl:with-param name="containingTypeName" select="substring(containers/type/@api,3)"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ </topicdata>
+ <xsl:copy-of select="apidata" />
+ <xsl:copy-of select="templates" />
+ <!-- elements -->
+ <elements>
+ <xsl:for-each select="msxsl:node-set($signatureSet)/*">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </elements>
+ <!-- containers -->
+ <xsl:choose>
+ <xsl:when test="boolean($declaredMembers)">
+ <containers>
+ <xsl:for-each select="$declaredMembers[1]/containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="$declaredMembers[1]/containers/namespace"/>
+ <xsl:copy-of select="$declaredMembers[1]/containers/type"/>
+ </containers>
+ </xsl:when>
+ <xsl:otherwise>
+ <containers>
+ <xsl:for-each select="key('index',$typeId)/containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="key('index',$typeId)/containers/namespace"/>
+ <type api="{$typeId}"/>
+ </containers>
+ </xsl:otherwise>
+ </xsl:choose>
+ </api>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:when>
+
+ <!-- handle non-EII members -->
+ <xsl:otherwise>
+ <!-- get the set of non-EII members with same name and subgroup -->
+ <xsl:variable name="overloadSet" select="
+ $members[
+ not(proceduredata/@eii='true') and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]" />
+
+ <!-- are there any declared members in the overload set? -->
+ <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
+
+ <!-- if more than one member in overloadSet, add an overload topic if necessary -->
+ <xsl:if test="(count($overloadSet) &gt; 1) and $overloadSet[1][@id=$memberId or @api=$memberId]">
+ <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
+ e.g. when one version inherits a member and another version overrides it.
+ We want an overload topic only when there are multiple signatures. -->
+ <!-- get the set of unique signatures for this overload set -->
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <!-- don't need an overload topic if only one signature -->
+ <xsl:when test="count(msxsl:node-set($signatureSet)/*) &lt; 2"/>
+ <!-- don't need an overload topic if all overloads are inherited and config'd to omit overload topics when all are inherited -->
+ <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')"/>
+ <!-- extension methods do not get overload topics -->
+ <xsl:when test="$subsubgroup='extension'"/>
+ <!-- otherwise, add an overload topic -->
+ <xsl:otherwise>
+ <api>
+ <xsl:attribute name="id">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="$typeId"/>
+ <xsl:with-param name="name" select="$apidataName"/>
+ <xsl:with-param name="templatesTotal" select="$templatesTotal"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <topicdata name="{apidata/@name}" group="list" subgroup="overload" memberSubgroup="{$subgroup}" pseudo="true" allMembersTopicId="{$allMembersTopicId}">
+ <xsl:if test="not(boolean($declaredMembers))">
+ <xsl:attribute name="allInherited">true</xsl:attribute>
+ <xsl:attribute name="parentTopicId">
+ <xsl:call-template name="overloadId">
+ <xsl:with-param name="typeId" select="containers/type/@api"/>
+ <xsl:with-param name="name" select="$apidataName"/>
+ <xsl:with-param name="templatesTotal" select="$templatesTotal"/>
+ <xsl:with-param name="subgroup" select="$subgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ </xsl:if>
+ </topicdata>
+ <xsl:copy-of select="apidata" />
+ <xsl:copy-of select="templates" />
+ <!-- elements -->
+ <elements>
+ <xsl:for-each select="msxsl:node-set($signatureSet)/*">
+ <xsl:copy-of select="."/>
+ </xsl:for-each>
+ </elements>
+ <!-- containers -->
+ <xsl:choose>
+ <xsl:when test="boolean($declaredMembers)">
+ <containers>
+ <xsl:for-each select="$declaredMembers[1]/containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="$declaredMembers[1]/containers/namespace"/>
+ <xsl:copy-of select="$declaredMembers[1]/containers/type"/>
+ </containers>
+ </xsl:when>
+ <xsl:otherwise>
+ <containers>
+ <xsl:for-each select="key('index',$typeId)/containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="key('index',$typeId)/containers/namespace"/>
+ <type api="{$typeId}"/>
+ </containers>
+ </xsl:otherwise>
+ </xsl:choose>
+ </api>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:for-each>
</xsl:template>
@@ -408,13 +659,15 @@
</xsl:when>
<xsl:otherwise>
<xsl:variable name="elementId" select="@id"/>
- <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$elementId]"/>
+ <xsl:for-each select="$root">
+ <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$elementId]"/>
+ </xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="GetSignatureSet">
- <xsl:param name="name" select="apidata/@name" />
+ <xsl:param name="apidataName" select="apidata/@name" />
<xsl:param name="overloadSet"/>
<xsl:param name="typeId"/>
@@ -428,12 +681,12 @@
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$overloadSet">
- <xsl:sort select="count(parameters/parameter)"/>
+ <xsl:sort select="count(parameters/parameter)" data-type="number"/>
<xsl:sort select="key('index', parameters/parameter[1]//type[1]/@api)/apidata/@name"/>
<xsl:variable name="memberId" select="@id | @api"/>
<xsl:variable name="signature">
<xsl:call-template name="GetSignature">
- <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="apidataName" select="$apidataName"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="sameParamSignatureSet" select="$overloadSet[contains(@id|@api,$signature) and string-length(substring-after(@id|@api,$signature))=0]"/>
@@ -471,7 +724,18 @@
</xsl:choose>
</xsl:variable>
<xsl:for-each select="$sameSignatureSet[@id=$primaryMemberId or @api=$primaryMemberId]">
- <element api="{$primaryMemberId}" signatureset="">
+ <xsl:variable name="nonPrimaryVersionElementSet">
+ <xsl:call-template name="nonPrimaryVersionElements">
+ <xsl:with-param name="usedIds" select="concat($primaryMemberId,';')"/>
+ <xsl:with-param name="elementSet" select="$elementSet"/>
+ <xsl:with-param name="sameSignatureSet" select="$sameSignatureSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <element api="{$primaryMemberId}">
+ <xsl:if test="count(msxsl:node-set($nonPrimaryVersionElementSet)/*) &gt; 0">
+ <xsl:attribute name="signatureset"/>
+ </xsl:if>
<!-- copy attributes and innerxml from the original element node -->
<xsl:choose>
<xsl:when test="local-name()='element'">
@@ -479,16 +743,13 @@
<xsl:copy-of select="*"/>
</xsl:when>
<xsl:otherwise>
- <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$primaryMemberId]/@*"/>
+ <xsl:for-each select="$root">
+ <xsl:copy-of select="key('index', $typeId)/elements/element[@api=$primaryMemberId]/@*"/>
+ </xsl:for-each>
</xsl:otherwise>
</xsl:choose>
<!-- for the secondary version groups, copy in the signatureset's latest member (if different from primary member) -->
- <xsl:call-template name="nonPrimaryVersionElements">
- <xsl:with-param name="usedIds" select="concat($primaryMemberId,';')"/>
- <xsl:with-param name="elementSet" select="$elementSet"/>
- <xsl:with-param name="sameSignatureSet" select="$sameSignatureSet"/>
- <xsl:with-param name="typeId" select="$typeId"/>
- </xsl:call-template>
+ <xsl:copy-of select="msxsl:node-set($nonPrimaryVersionElementSet)/*"/>
</element>
</xsl:for-each>
</xsl:if>
@@ -551,7 +812,7 @@
</xsl:if>
</xsl:if>
</xsl:template>
-
+
<xsl:template name="GetSignatureWithLatestVersion">
<xsl:param name="versionGroup"/>
<xsl:param name="signatureset"/>
@@ -582,19 +843,19 @@
<!-- -->
<xsl:template name="GetSignature">
- <xsl:param name="name" />
+ <xsl:param name="apidataName" />
<xsl:param name="memberId" select="@id | @api"/>
<xsl:variable name="paramString" select="substring-after($memberId,'(')"/>
<xsl:variable name="tickString" select="substring-after($memberId,'``')"/>
<xsl:variable name="memberName">
<xsl:choose>
- <xsl:when test="$name='.ctor' or $name='.cctor'">ctor</xsl:when>
+ <xsl:when test="$apidataName='.ctor' or $apidataName='.cctor'">ctor</xsl:when>
<!-- for explicit interface implementation members, return the membername with # instead of ., so it matches cref ids -->
<xsl:when test="memberdata[@visibility='private'] and proceduredata[@virtual = 'true']">
- <xsl:value-of select="translate($name,'.','#')"/>
+ <xsl:value-of select="translate($apidataName,'.','#')"/>
</xsl:when>
<xsl:otherwise>
- <xsl:value-of select="$name"/>
+ <xsl:value-of select="$apidataName"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
@@ -610,27 +871,23 @@
</xsl:otherwise>
</xsl:choose>
</xsl:template>
-
+
<!-- member list topics -->
-
+
<xsl:template name="AddMemberlistAPI">
<xsl:param name="subgroup"/>
<xsl:param name="subsubgroup"/>
<xsl:param name="topicSubgroup"/>
<xsl:param name="typeId" />
- <xsl:param name="declaredPrefix" select="concat(substring-after($typeId,':'), '.')"/>
- <!-- get the type's declared members for this subgroup -->
- <xsl:param name="declaredMembers" select="key('index',elements/element[not(apidata)][starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]
- | elements/element[starts-with(substring-after(@api,':'), $declaredPrefix)][apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]"/>
<!-- get all the type's members for this subgroup -->
<xsl:param name="members" select="key('index',elements/element[not(apidata)]/@api)[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]
| elements/element[apidata[($subgroup='' and @subsubgroup=$subsubgroup) or ($subsubgroup='' and not(@subsubgroup) and @subgroup=$subgroup)]]"/>
- <!-- add a member list topic only if the type has declared members -->
- <xsl:if test="count($declaredMembers) &gt; 0">
+ <!-- Fix for bug:365255, add a member list topic for all the type's members-->
+ <xsl:if test="count($members) &gt; 0">
<api>
<xsl:attribute name="id">
- <xsl:value-of select="concat($topicSubgroup, '.', $typeId)"/>
+ <xsl:value-of select="concat($topicSubgroup, '.', $typeId)"/>
</xsl:attribute>
<topicdata name="{apidata/@name}" group="list" subgroup="{$topicSubgroup}">
<xsl:if test="boolean($subsubgroup)">
@@ -650,8 +907,14 @@
<xsl:with-param name="members" select="$members"/>
<xsl:with-param name="typeId" select="$typeId"/>
</xsl:call-template>
- <xsl:copy-of select="containers" />
- </api>
+ <containers>
+ <xsl:for-each select="containers/library">
+ <xsl:call-template name="addLibraryAssemblyData"/>
+ </xsl:for-each>
+ <xsl:copy-of select="containers/namespace"/>
+ <xsl:copy-of select="containers/type"/>
+ </containers>
+ </api>
</xsl:if>
</xsl:template>
@@ -662,30 +925,99 @@
<elements>
<xsl:for-each select="$members">
- <xsl:variable name="name" select="apidata/@name" />
+ <xsl:variable name="apidataName" select="apidata/@name"/>
+ <xsl:variable name="templatesTotal" select="count(templates/*)"/>
+ <xsl:variable name="templateParams" select="count(templates/template)"/>
+ <xsl:variable name="templateArgs" select="count(templates/*[not(self::template)])"/>
+ <!-- strip off any parameters from the end of the id -->
+ <xsl:variable name="idWithoutParams">
+ <xsl:call-template name="RemoveParametersFromId"/>
+ </xsl:variable>
<xsl:variable name="subgroup" select="apidata/@subgroup" />
<xsl:variable name="subsubgroup" select="apidata/@subsubgroup" />
<xsl:variable name="memberId" select="@id | @api"/>
<xsl:choose>
- <!-- EII members are not treated as overloads -->
+ <!-- handle EII members -->
<xsl:when test="proceduredata/@eii='true'">
- <xsl:call-template name="WriteElementNode">
- <xsl:with-param name="typeId" select="$typeId"/>
- </xsl:call-template>
+ <xsl:variable name="eiiTypeId" select="implements/member/type/@api"/>
+ <!-- get the set of overloads: EII members with same name and subgroup -->
+ <xsl:variable name="overloadSet" select="
+ $members[
+ proceduredata/@eii='true' and implements/member/type/@api=$eiiTypeId and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]" />
+
+ <!-- are there any declared members in the overload set? -->
+ <xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
+
+ <xsl:variable name="signatureSet">
+ <xsl:call-template name="GetSignatureSet">
+ <xsl:with-param name="overloadSet" select="$overloadSet"/>
+ <xsl:with-param name="typeId" select="$typeId"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <!-- make sure we add to the list only once -->
+ <xsl:if test="$overloadSet[1][@id=$memberId or @api=$memberId]">
+ <!-- When merging multiple versions, an overload set may have multiple members with the same signature,
+ e.g. when one version inherits a member and another version overrides it.
+ We want an overload topic only when there are multiple signatures. -->
+ <!-- get the set of unique signatures for this overload set -->
+ <xsl:choose>
+ <!-- don't need an overload topic if only one signature -->
+ <xsl:when test="count(msxsl:node-set($signatureSet)/*) = 1">
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </xsl:when>
+ <!-- just copy the elements if all overloads are inherited and config'd to omit overload topics when all are inherited -->
+ <xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')">
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <element>
+ <xsl:attribute name="api">
+ <xsl:call-template name="eiiOverloadId">
+ <xsl:with-param name="typeId" select="$typeId" />
+ <xsl:with-param name="idWithoutParams" select="$idWithoutParams"/>
+ <xsl:with-param name="containingTypeName" select="substring(containers/type/@api,3)"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
+ </element>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
</xsl:when>
-
+
<!-- field members cannot be overloaded, so skip the overload logic and just write the element node -->
<xsl:when test="$subgroup='field'">
<xsl:call-template name="WriteElementNode">
<xsl:with-param name="typeId" select="$typeId"/>
</xsl:call-template>
</xsl:when>
-
- <!-- for non-EII members, handle overloads and signature sets -->
+
+ <!-- for other non-EII members, handle overloads and signature sets -->
<xsl:otherwise>
<!-- get the set of overloads: non-EII members with same name and subgroup -->
- <xsl:variable name="overloadSet" select="$members[not(proceduredata/@eii='true') and apidata[@name=$name and @subgroup=$subgroup and (@subsubgroup=$subsubgroup or (not(boolean($subsubgroup)) and not(@subsubgroup)))]]"/>
+ <xsl:variable name="overloadSet" select="
+ $members[
+ not(proceduredata/@eii='true') and
+ apidata[
+ @name=$apidataName and
+ @subgroup=$subgroup and
+ (@subsubgroup=$subsubgroup or (not(@subsubgroup) and normalize-space($subsubgroup)=''))
+ ] and
+ (count(templates/*) = $templatesTotal) and
+ (count(templates/template) = $templateParams) and
+ (count(templates/*[not(self::template)]) = $templateArgs)
+ ]"/>
<!-- are there any declared members in the overload set? -->
<xsl:variable name="declaredMembers" select="$overloadSet[starts-with(substring(@id,2),$declaredPrefix)]" />
@@ -703,8 +1035,6 @@
e.g. when one version inherits a member and another version overrides it.
We want an overload topic only when there are multiple signatures. -->
<!-- get the set of unique signatures for this overload set -->
- <!--
- -->
<xsl:choose>
<!-- don't need an overload topic if only one signature -->
<xsl:when test="count(msxsl:node-set($signatureSet)/*) = 1">
@@ -714,14 +1044,26 @@
<xsl:when test="(not(boolean($declaredMembers)) and $IncludeInheritedOverloadTopics='false')">
<xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
</xsl:when>
+ <!-- no overload topics for extension methods -->
+ <!-- but we need to mark the elements as overloaded (so the memberlist link shows parameters) -->
+ <xsl:when test="$subsubgroup='extension'">
+ <xsl:for-each select="msxsl:node-set($signatureSet)/*">
+ <element>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="overload">true</xsl:attribute>
+ <xsl:copy-of select="*"/>
+ </element>
+ </xsl:for-each>
+ </xsl:when>
<xsl:otherwise>
<element>
<xsl:attribute name="api">
<xsl:call-template name="overloadId">
<xsl:with-param name="typeId" select="$typeId"/>
- <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="name" select="$apidataName"/>
+ <xsl:with-param name="templatesTotal" select="$templatesTotal"/>
<xsl:with-param name="subgroup" select="$subgroup"/>
- <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
+ <xsl:with-param name="subsubgroup" select="$subsubgroup"/>
</xsl:call-template>
</xsl:attribute>
<xsl:copy-of select="msxsl:node-set($signatureSet)/*"/>
@@ -738,6 +1080,7 @@
<xsl:template name="overloadId">
<xsl:param name="typeId"/>
<xsl:param name="name"/>
+ <xsl:param name="templatesTotal"/>
<xsl:param name="subgroup"/>
<xsl:param name="subsubgroup"/>
<xsl:choose>
@@ -745,14 +1088,24 @@
<xsl:value-of select="concat('Overload:',substring($typeId,3),'.#ctor')"/>
</xsl:when>
<xsl:when test="$subsubgroup='operator'">
- <xsl:value-of select="concat('Overload:',substring($typeId,3),'.op_',$name)"/>
- </xsl:when>
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),'.op_',$name)"/>
+ </xsl:when>
+ <xsl:when test="$templatesTotal>0">
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),'.',$name,'``',string($templatesTotal))"/>
+ </xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('Overload:',substring($typeId,3),'.',$name)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
+ <xsl:template name="eiiOverloadId">
+ <xsl:param name="typeId" />
+ <xsl:param name="idWithoutParams" />
+ <xsl:param name="containingTypeName" />
+ <xsl:value-of select="concat('Overload:',substring($typeId,3),substring-after($idWithoutParams,$containingTypeName))"/>
+ </xsl:template>
+
<xsl:template name="projectTopic">
<api id="R:{$project}">
<topicdata group="root" />
@@ -763,5 +1116,5 @@
</elements>
</api>
</xsl:template>
-
+
</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/CreateHxt.xsl b/tools/Sandcastle/ProductionTransforms/CreateHxt.xsl
new file mode 100644
index 0000000..3a1c510
--- /dev/null
+++ b/tools/Sandcastle/ProductionTransforms/CreateHxt.xsl
@@ -0,0 +1,91 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
+ <!-- project name something like "fxref" -->
+ <xsl:param name="projectName" />
+
+ <!-- can be assembly or namespace for HXT generation -->
+ <xsl:param name="createBy" />
+
+ <!-- Maximum project length allowed. Below is the default provided by paorear, bug 230840 -->
+ <xsl:param name="maxProjectNameLength" select="49" />
+
+ <xsl:output indent="yes" encoding="UTF-8" doctype-system="MS-Help://Hx/Resources/HelpTOC.dtd" />
+
+ <xsl:variable name="leftLength" select="$maxProjectNameLength div 2 - 1" />
+
+ <xsl:variable name="rightLength" select="$maxProjectNameLength - $leftLength - 2" />
+
+ <xsl:variable name="projectPrefix">
+ <xsl:if test="boolean($projectName)">
+ <xsl:value-of select="concat($projectName,'_')"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:template match="/">
+ <HelpTOC DTDVersion="1.0">
+ <xsl:choose>
+ <xsl:when test="$createBy = 'assembly'">
+ <xsl:apply-templates select="/reflection/assemblies/assembly">
+ <xsl:sort select="@name" />
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="/reflection/apis/api[apidata/@group='namespace']">
+ <xsl:sort select="apidata/@name" />
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </HelpTOC>
+ </xsl:template>
+
+ <!-- Apply the template for assembly level -->
+ <xsl:template match="assembly">
+ <xsl:variable name="componentName">
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName" select="concat($projectPrefix, @name)" />
+ </xsl:call-template>
+ </xsl:variable>
+
+ <HelpTOCNode NodeType="TOC" Url="{$componentName}" />
+ </xsl:template>
+
+ <!-- Apply the template for namespace level -->
+ <xsl:template match="api[apidata/@group='namespace']">
+
+ <xsl:variable name="componentName">
+
+ <xsl:call-template name="GetComponentName">
+ <xsl:with-param name="initialName">
+ <xsl:choose>
+ <xsl:when test="apidata/@name = ''">
+ <xsl:value-of select="concat($projectPrefix, 'default_namespace')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat($projectPrefix, apidata/@name)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <HelpTOCNode NodeType="TOC" Url="{$componentName}" />
+
+ </xsl:template>
+
+ <!-- logic to shorten component names if needed -->
+ <xsl:template name="GetComponentName">
+ <xsl:param name="initialName" />
+ <xsl:variable name="componentNameLength" select="string-length($initialName)" />
+ <xsl:choose>
+ <xsl:when test="$componentNameLength >= $maxProjectNameLength">
+ <xsl:variable name="left" select="substring($initialName, 1, $leftLength)" />
+ <xsl:variable name="right" select="substring($initialName, $componentNameLength - $rightLength)" />
+ <xsl:value-of select="concat($left,'_',$right)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$initialName" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl b/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl
index 31842a4..abf3ef3 100644
--- a/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl
+++ b/tools/Sandcastle/ProductionTransforms/CreateVSToc.xsl
@@ -66,7 +66,7 @@
<xsl:param name="initialName" select="containers/library/@assembly" />
<xsl:variable name="componentNameLength" select="string-length($initialName)" />
<xsl:choose>
- <xsl:when test="$componentNameLength > $maxProjectNameLength">
+ <xsl:when test="$componentNameLength >= $maxProjectNameLength">
<xsl:variable name="left" select="substring($initialName, 1, $leftLength)" />
<xsl:variable name="right" select="substring($initialName, $componentNameLength - $rightLength)" />
<xsl:value-of select="concat($left,'_',$right)" />
@@ -135,6 +135,11 @@
<xsl:call-template name="AddMemberListTree"/>
</xsl:for-each>
+ <!-- insert the Operators topic, if present -->
+ <xsl:for-each select="key('index', concat('Operators.', $typeId))">
+ <xsl:call-template name="AddMemberListTree"/>
+ </xsl:for-each>
+
<!-- insert the Properties topic, if present -->
<xsl:for-each select="key('index', concat('Properties.', $typeId))">
<xsl:call-template name="AddMemberListTree"/>
@@ -169,7 +174,7 @@
<!-- recurse to get declared child element topics, if any -->
<xsl:for-each select="key('index', elements/*[starts-with(substring-after(@api,':'), $declaredPrefix)]/@api)">
<!-- sort the elements in a member list topic by name -->
- <xsl:sort select="apidata/@name" />
+ <xsl:sort select="topicdata/@eiiName | apidata/@name" />
<xsl:call-template name="AddMember">
<xsl:with-param name="declaredPrefix" select="$declaredPrefix"/>
</xsl:call-template>
diff --git a/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl b/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl
index 02d9b2e..8a4efee 100644
--- a/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl
+++ b/tools/Sandcastle/ProductionTransforms/DsManifestToManifest.xsl
@@ -9,7 +9,7 @@
</topics>
</xsl:template>
- <xsl:template match="fileAsset[@assetType='Topic']">
+ <xsl:template match="fileAsset[@assetType='Topic' and @assetParentName=@projectName]">
<topic>
<xsl:attribute name="id">
<xsl:value-of select="@fileAssetGuid" />
diff --git a/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl b/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl
index da721c7..18b7d95 100644
--- a/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl
+++ b/tools/Sandcastle/ProductionTransforms/MergeDuplicates.xsl
@@ -14,7 +14,7 @@
- gets rid of duplicate element nodes in a namespace's api node
- type api nodes: collapses duplicates into a single api node; saves library info for each duplicate
- member api nodes: collapses duplicates into a single api node; saves library info for each duplicate
- - enum api nodes: saves container info for each enum element, in case the element lists differ
+ - for element lists, add library info to elements that are not in all duplicates
-->
<xsl:key name="index" match="/*/apis/api" use="@id" />
@@ -58,16 +58,12 @@
<xsl:template match="api[apidata/@group='type']">
<xsl:variable name="ancestorId" select="family/ancestors/type[last()]/@api" />
- <xsl:variable name="subgroup" select="apidata/@subgroup" />
- <xsl:variable name="duplicates" select="key('index',@id)[apidata[@subgroup=$subgroup]]" />
- <!--
- (apidata[@subgroup!='class'] or family/ancestors/type[last()][@api=$ancestorId])]
- -->
+ <xsl:variable name="duplicates" select="key('index',@id)" />
<xsl:choose>
<!-- if dupes, merge them -->
<xsl:when test="count($duplicates)&gt;1">
<xsl:variable name="typeId" select="@id" />
- <xsl:if test="not(preceding-sibling::api[@id=$typeId][apidata[@subgroup=$subgroup]])">
+ <xsl:if test="not(preceding-sibling::api[@id=$typeId])">
<xsl:call-template name="mergeDuplicateTypes">
<xsl:with-param name="duplicates" select="$duplicates"/>
</xsl:call-template>
@@ -83,7 +79,6 @@
<xsl:template name="mergeDuplicateTypes">
<xsl:param name="duplicates"/>
<xsl:variable name="typeId" select="@id"/>
- <xsl:variable name="subgroup" select="apidata/@subgroup" />
<xsl:variable name="duplicatesCount" select="count($duplicates)"/>
<api>
<xsl:copy-of select="@*" />
@@ -99,7 +94,7 @@
<elements>
<xsl:for-each select="$duplicates/elements/element">
<xsl:variable name="elementId" select="@api"/>
- <xsl:if test="not(preceding::api[@id=$typeId][apidata[@subgroup=$subgroup]]/elements/element[@api=$elementId])">
+ <xsl:if test="not(preceding::api[@id=$typeId]/elements/element[@api=$elementId])">
<!-- need to add library info to elements that are not in all duplicates -->
<element>
<xsl:copy-of select="@*"/>
diff --git a/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl b/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl
index 3d13ab9..0e7e08a 100644
--- a/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl
+++ b/tools/Sandcastle/ProductionTransforms/ReflectionToManifest.xsl
@@ -1,21 +1,47 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.1">
- <xsl:output indent="yes" encoding="UTF-8" />
+ <xsl:output indent="yes" encoding="UTF-8" />
- <xsl:key name="index" match="/reflection/apis/api" use="@id" />
+ <xsl:param name="componentizeBy"/>
- <xsl:template match="/">
- <topics>
- <xsl:apply-templates select="/reflection/apis/api" />
- </topics>
- </xsl:template>
+ <xsl:key name="index" match="/reflection/apis/api" use="containers/namespace/@api" />
+ <xsl:key name="indexByAssembly" match="/reflection/apis/api[containers/library]" use="containers/library[1]/@assembly" />
- <!-- namespace and member topics -->
- <xsl:template match="api">
+ <xsl:template match="/">
+ <topics>
+ <!-- process the root node -->
+ <xsl:apply-templates select="/reflection/apis/api[topicdata[@group='root']]" />
+ <xsl:choose>
+
+ <!-- sort by assembly -->
+ <xsl:when test="$componentizeBy='assembly'">
+ <!-- loop through the assemblies and output the apis in each assembly -->
+ <xsl:for-each select="/reflection/assemblies/assembly">
+ <xsl:apply-templates select="key('indexByAssembly',@name)" />
+ </xsl:for-each>
+ <!-- process the namespace nodes, which may be associated with more than one assembly -->
+ <xsl:apply-templates select="/reflection/apis/api[apidata[@group='namespace']]" />
+ </xsl:when>
+
+ <!-- default is to sort by namespace -->
+ <xsl:otherwise>
+ <!-- process each namespace's api node, then process nodes for all the apis in the namespace -->
+ <xsl:for-each select="/reflection/apis/api[apidata[@group='namespace']]">
+ <xsl:apply-templates select="." />
+ <xsl:apply-templates select="key('index',@id)" />
+ </xsl:for-each>
+ </xsl:otherwise>
+
+ </xsl:choose>
+ </topics>
+ </xsl:template>
+
+ <!-- namespace and member topics -->
+ <xsl:template match="api">
<xsl:if test="not(topicdata/@notopic)">
- <topic id="{@id}" />
+ <topic id="{@id}"/>
</xsl:if>
- </xsl:template>
+ </xsl:template>
</xsl:stylesheet>
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssembler.csproj b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssembler.csproj
new file mode 100644
index 0000000..0ceafb8
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssembler.csproj
@@ -0,0 +1,93 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{5BA19924-5A65-46E0-97CD-948595932584}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>BuildAssembler</RootNamespace>
+ <AssemblyName>BuildAssembler</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BuildAssemblerConsole.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\BuildAssemblerLibrary\BuildAssemblerLibrary.csproj">
+ <Project>{399E78F8-4954-409E-991A-37DA9D0579CC}</Project>
+ <Name>BuildAssemblerLibrary</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssemblerConsole.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssemblerConsole.cs
new file mode 100644
index 0000000..e4f0528
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/BuildAssemblerConsole.cs
@@ -0,0 +1,110 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
+
+using Microsoft.Ddue.Tools.CommandLine;
+
+namespace Microsoft.Ddue.Tools
+{
+ class BuildAssemblerConsole
+ {
+ public static int Main(string[] args)
+ {
+ ConsoleApplication.WriteBanner();
+
+ #region read command line arguments, and setup config
+
+ // specify options
+ OptionCollection options = new OptionCollection();
+ options.Add(new SwitchOption("?", "Show this help page."));
+ options.Add(new StringOption("config", "Specify a configuration file.", "configFilePath"));
+
+ // process options
+ ParseArgumentsResult results = options.ParseArguments(args);
+
+ // process help option
+ if (results.Options["?"].IsPresent)
+ {
+ Console.WriteLine("TocBuilder [options] rootDirectory");
+ options.WriteOptionSummary(Console.Out);
+ return (0);
+ }
+
+ // check for invalid options
+ if (!results.Success)
+ {
+ results.WriteParseErrors(Console.Out);
+ return (1);
+ }
+
+ // check for manifest
+
+ if (results.UnusedArguments.Count != 1)
+ {
+ Console.WriteLine("You must supply exactly one manifest file.");
+ return (1);
+ }
+
+ string manifest = results.UnusedArguments[0];
+
+ // Load the configuration file
+ XPathDocument configuration;
+ try
+ {
+ if (results.Options["config"].IsPresent)
+ {
+ configuration = ConsoleApplication.GetConfigurationFile((string)results.Options["config"].Value);
+ }
+ else
+ {
+ configuration = ConsoleApplication.GetConfigurationFile();
+ }
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specified configuration file could not be loaded. The error message is: {0}", e.Message));
+ return (1);
+ }
+ catch (XmlException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specified configuration file is not well-formed. The error message is: {0}", e.Message));
+ return (1);
+ }
+
+ #endregion
+
+ // create a BuildAssembler to do the work
+ BuildAssembler buildAssembler = new BuildAssembler();
+
+ try {
+
+ // load the context
+ XPathNavigator contextNode = configuration.CreateNavigator().SelectSingleNode("/configuration/dduetools/builder/context");
+ if (contextNode != null) buildAssembler.Context.Load(contextNode);
+
+ // load the build components
+ XPathNavigator componentsNode = configuration.CreateNavigator().SelectSingleNode("/configuration/dduetools/builder/components");
+ if (componentsNode != null) buildAssembler.AddComponents(componentsNode);
+
+ // proceed thorugh the build manifest, processing all topics named there
+ int count = buildAssembler.Apply(manifest);
+
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Processed {0} topics", count));
+
+ } finally {
+ buildAssembler.Dispose();
+ }
+
+ return (0);
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/GlobalSuppressions.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/GlobalSuppressions.cs
new file mode 100644
index 0000000..88e273a
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/GlobalSuppressions.cs
@@ -0,0 +1,17 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssemblerConsole.#Main(System.String[])")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a5d12d9
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssembler/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BuildAssembler")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("BuildAssembler")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("381d8bb3-dbf9-4065-adbd-afebf844414b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssembler.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssembler.cs
new file mode 100644
index 0000000..ead3616
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssembler.cs
@@ -0,0 +1,320 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
+
+using Microsoft.Ddue.Tools.CommandLine;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class BuildAssembler : IDisposable {
+
+ // the built context
+ public BuildAssembler()
+ {
+ this.handler = BuildAssembler.ConsoleMessageHandler;
+
+ }
+
+ // the built context
+ public BuildAssembler(MessageHandler messageHandler)
+ {
+ if (messageHandler == null) throw new ArgumentNullException("messageHandler");
+ this.handler = messageHandler;
+
+ }
+
+ // private data
+
+ private BuildContext context = new BuildContext();
+
+ private List<BuildComponent> components = new List<BuildComponent>();
+
+ private MessageHandler handler;
+
+ // data accessors
+
+ public BuildContext Context {
+ get {
+ return (context);
+ }
+ }
+
+ public BuildComponent[] BuildComponents {
+ get {
+ return (components.ToArray());
+ }
+ }
+
+ public MessageHandler MessageHandler {
+ get {
+ return (handler);
+ }
+ }
+
+ // component communication mechanism
+
+ public event EventHandler ComponentEvent;
+
+ internal void OnComponentEvent (Object o, EventArgs e) {
+ if (ComponentEvent != null) ComponentEvent(o, e);
+ }
+
+ // operations
+
+ public int Apply(IEnumerable<string> topics)
+ {
+ int count = 0;
+
+ foreach (string topic in topics)
+ {
+
+ // create the document
+ XmlDocument document = new XmlDocument();
+ document.PreserveWhitespace = true;
+
+ // write a log message
+ WriteMessage(MessageLevel.Info, String.Format("Building topic {0}", topic));
+
+ // apply the component stack
+ foreach (BuildComponent component in components)
+ {
+
+ component.Apply(document, topic);
+ }
+
+ count++;
+ }
+
+ return (count);
+ }
+
+ public int Apply (string manifestFile) {
+ return (Apply(new TopicManifest(manifestFile)));
+ }
+
+ public void Dispose() {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (BuildComponent component in components) {
+ ((IDisposable) component).Dispose();
+ }
+ }
+ }
+
+ private class TopicManifest : IEnumerable<string> {
+
+ public TopicManifest (string manifest) {
+ this.manifest = manifest;
+ }
+
+ private string manifest;
+
+ public IEnumerator<string> GetEnumerator () {
+ return (new TopicEnumerator(manifest));
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () {
+ return (GetEnumerator());
+ }
+
+ }
+
+ private class TopicEnumerator : IEnumerator<string> {
+
+ public TopicEnumerator (string manifest) {
+ reader = XmlReader.Create(manifest);
+ reader.MoveToContent();
+ }
+
+ private XmlReader reader;
+
+ public bool MoveNext () {
+ while (reader.Read()) {
+ if ((reader.NodeType == XmlNodeType.Element) && (reader.LocalName == "topic")) return (true);
+ }
+ return (false);
+ }
+
+ public string Current {
+ get {
+ string id = reader.GetAttribute("id");
+ return(id);
+ }
+ }
+
+ Object System.Collections.IEnumerator.Current {
+ get {
+ return (Current);
+ }
+ }
+
+ public void Reset () {
+ throw new InvalidOperationException();
+ }
+
+ public void Dispose () {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing) {
+ if (disposing) {
+ reader.Close();
+ }
+ }
+
+ }
+
+ public IEnumerable<BuildContext> GetFileManifestBuildContextEnumerator(string manifestFilename)
+ {
+ using (XmlReader reader = XmlReader.Create(manifestFilename))
+ {
+ reader.MoveToContent();
+ while (reader.Read())
+ {
+ if ((reader.NodeType == XmlNodeType.Element) && (reader.LocalName == "topic"))
+ {
+ BuildContext thisContext = new BuildContext();
+
+ try
+ {
+ string id = reader.GetAttribute("id");
+
+ while (reader.MoveToNextAttribute())
+ {
+ string name = reader.Name;
+ string value = reader.Value;
+ thisContext.AddVariable(name, value);
+ }
+ }
+ catch (XmlException e)
+ {
+ throw new XmlException(String.Format("The manifest file: '{0}' is not well-formed. The error message is: {1}", manifestFilename, e.Message), e);
+ }
+
+ yield return thisContext;
+ }
+ }
+ }
+ }
+
+ public BuildComponent LoadComponent (XPathNavigator configuration) {
+
+ if (configuration == null) throw new ArgumentNullException("configuration");
+
+ // get the component infomation
+ string assemblyName = configuration.GetAttribute("assembly", String.Empty);
+ if (String.IsNullOrEmpty(assemblyName)) {
+ WriteMessage(MessageLevel.Error, "Each component element must have an assembly attribute that specifys a path to the component assembly.");
+ }
+
+ string typeName = configuration.GetAttribute("type", String.Empty);
+ if (String.IsNullOrEmpty(typeName)) {
+ WriteMessage(MessageLevel.Error, "Each component element must have a type attribute that specifys the fully qualified name of a component type.");
+ }
+
+ // expand environmet variables in path of assembly name
+ assemblyName = Environment.ExpandEnvironmentVariables(assemblyName);
+
+ // load and instantiate the component
+ BuildComponent component = null;
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyName);
+ component = (BuildComponent) assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { this, configuration }, null, null);
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A file access error occured while attempting to load the build component assembly '{0}'. The error message is: {1}", assemblyName, e.Message));
+ } catch (BadImageFormatException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The build component assembly '{0}' is not a valid managed assembly. The error message is: {1}", assemblyName, e.Message));
+ } catch (TypeLoadException) {
+ WriteMessage(MessageLevel.Error, String.Format("The build component '{0}' was not found in the assembly '{1}'.", typeName, assemblyName));
+ } catch (MissingMethodException e) {
+ WriteMessage(MessageLevel.Error, String.Format("No appropriate constructor exists for the build component '{0}' in the component assembly '{1}'. The error message is: {1}", typeName, assemblyName, e.Message));
+ } catch (TargetInvocationException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An error occured while initializing the build component '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyName, e.InnerException.ToString()));
+ } catch (InvalidCastException) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a build component.", typeName, assemblyName));
+ }
+
+ if (component == null) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyName));
+ }
+
+ return (component);
+
+
+ }
+
+ public BuildComponent[] LoadComponents (XPathNavigator configuration) {
+
+ XPathNodeIterator componentNodes = configuration.Select("component");
+
+ List<BuildComponent> components = new List<BuildComponent>();
+
+ foreach (XPathNavigator componentNode in componentNodes) {
+ components.Add(LoadComponent(componentNode));
+ }
+
+ return(components.ToArray());
+
+ }
+
+ // routines to add and remove components from the
+
+ public void AddComponents (XPathNavigator configuration) {
+ BuildComponent[] componentsToAdd = LoadComponents(configuration);
+ foreach (BuildComponent componentToAdd in componentsToAdd) {
+ components.Add(componentToAdd);
+ }
+ }
+
+ public void ClearComponents () {
+ components.Clear();
+ }
+ private void WriteMessage(MessageLevel level, string message)
+ {
+ handler(this.GetType(), level, message);
+ }
+
+ // the default message handler
+
+ public static MessageHandler ConsoleMessageHandler {
+ get {
+ return (new MessageHandler(WriteComponentMessageToConsole));
+ }
+ }
+
+ private static void WriteComponentMessageToConsole(Type type, MessageLevel level, string message)
+ {
+ string text = String.Format("{0}: {1}", type.Name, message);
+ switch (level)
+ {
+ case MessageLevel.Info:
+ ConsoleApplication.WriteMessage(LogLevel.Info, text);
+ break;
+ case MessageLevel.Warn:
+ ConsoleApplication.WriteMessage(LogLevel.Warn, text);
+ break;
+ case MessageLevel.Error:
+ ConsoleApplication.WriteMessage(LogLevel.Error, text);
+ Environment.Exit(1);
+ break;
+ }
+ }
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssemblerLibrary.csproj b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssemblerLibrary.csproj
new file mode 100644
index 0000000..c7acabd
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildAssemblerLibrary.csproj
@@ -0,0 +1,94 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{399E78F8-4954-409E-991A-37DA9D0579CC}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>BuildAssemblerLibrary</RootNamespace>
+ <AssemblyName>BuildAssemblerLibrary</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <RunCodeAnalysis>false</RunCodeAnalysis>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BuildAssembler.cs" />
+ <Compile Include="BuildComponent.cs" />
+ <Compile Include="BuildComponentUtilities.cs" />
+ <Compile Include="BuildContext.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponent.cs
new file mode 100644
index 0000000..04a68ea
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponent.cs
@@ -0,0 +1,82 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public abstract class BuildComponent : IDisposable {
+
+ protected BuildComponent (BuildAssembler assembler, XPathNavigator configuration) {
+ this.assembler = assembler;
+ WriteMessage(MessageLevel.Info, "Instantiating component.");
+ }
+
+ public abstract void Apply (XmlDocument document, string key);
+
+ public virtual void Apply (XmlDocument document) {
+ Apply(document, null);
+ }
+
+ public void Dispose() {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose (bool disposing) {
+ }
+
+ // shared data
+
+ private BuildAssembler assembler;
+
+ public BuildAssembler BuildAssembler {
+ get {
+ return(assembler);
+ }
+ }
+
+ //private MessageHandler handler;
+
+ private static Dictionary<string,object> data = new Dictionary<string,object>();
+
+ protected static Dictionary<string,object> Data {
+ get {
+ return(data);
+ }
+ }
+
+ // component messaging facility
+
+ protected void OnComponentEvent (EventArgs e) {
+ assembler.OnComponentEvent(this.GetType(), e);
+ }
+
+ protected void WriteMessage (MessageLevel level, string message) {
+ if (level == MessageLevel.Ignore) return;
+ MessageHandler handler = assembler.MessageHandler;
+ if (handler != null) handler(this.GetType(), level, message);
+ }
+
+ }
+
+ public enum MessageLevel {
+ Ignore, // don't show at all
+ Info, // informational message
+ Warn, // a minor problem occured
+ Error // a major problem occured
+ }
+
+
+ public delegate void MessageHandler (Type component, MessageLevel level, string message);
+
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponentUtilities.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponentUtilities.cs
new file mode 100644
index 0000000..0ab709a
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildComponentUtilities.cs
@@ -0,0 +1,146 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Text;
+using System.Xml;
+using System.Xml.Xsl;
+using System.Xml.XPath;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools {
+
+ public static class BuildComponentUtilities {
+
+ // get the message strings from an exception
+
+ public static string GetExceptionMessage (Exception e) {
+ if (e == null) throw new ArgumentNullException("e");
+
+ string message = e.Message;
+
+ XmlException xmlE = e as XmlException;
+ if (xmlE != null) {
+ message = String.Format("{0} (LineNumber: {1}; LinePosition: {2}; SourceUri: '{3}')", message, xmlE.LineNumber, xmlE.LinePosition, xmlE.SourceUri);
+ }
+
+ XsltException xslE = e as XsltException;
+ if (xslE != null) {
+ message = String.Format("{0} (LineNumber: {1}; LinePosition: {2}; SourceUri: '{3}')", message, xslE.LineNumber, xslE.LinePosition, xslE.SourceUri);
+ }
+
+ if (e.InnerException != null) message = String.Format("{0} {1}", message, GetExceptionMessage(e.InnerException));
+
+ return (message);
+ }
+
+ // get InnerXml without changing the spacing
+
+ public static string GetInnerXml (XPathNavigator node) {
+
+ // check for null argument, and clone so we don't change input
+ if (node == null) throw new ArgumentNullException("node");
+ XPathNavigator current = node.Clone();
+
+ // create appropriate settings for the output writer
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.ConformanceLevel = ConformanceLevel.Fragment;
+ settings.OmitXmlDeclaration = true;
+
+ // construct a writer for our output
+ StringBuilder builder = new StringBuilder();
+ XmlWriter writer = XmlWriter.Create(builder, settings);
+
+ // write the output
+ bool writing = current.MoveToFirstChild();
+ while (writing) {
+ current.WriteSubtree(writer);
+ writing = current.MoveToNext();
+ }
+
+ // finish up and return the result
+ writer.Close();
+ return(builder.ToString());
+
+ }
+
+ // get an array of nodes matching an XPath expression
+
+ public static XPathNavigator[] ConvertNodeIteratorToArray (XPathNodeIterator iterator) {
+ XPathNavigator[] result = new XPathNavigator[iterator.Count];
+ for (int i = 0; i < result.Length; i++) {
+ iterator.MoveNext();
+ result[i] = iterator.Current.Clone();
+ // clone is required or all entries will equal Current!
+ }
+ return(result);
+ }
+
+
+ /// <summary>
+ /// Returns the string result from evaluating an xpath expression against the given document and context.
+ /// </summary>
+ public static string EvalXPathExpr(IXPathNavigable doc, XPathExpression xpe, CustomContext c) {
+ XPathExpression t = xpe.Clone();
+ t.SetContext(c);
+ return doc.CreateNavigator().Evaluate(t).ToString();
+ }
+
+
+ /// <summary>
+ /// Returns the string result from evaluating an xpath expression against the given document and
+ /// context created from key/value pairs.
+ /// </summary>
+ /// <example>
+ /// string result = BuildComponentUtilities.EvalXPathExpr(doc, "concat($key, '.htm')", "key", "file");
+ /// </example>
+ public static string EvalXPathExpr(IXPathNavigable doc, XPathExpression xpe, params string[] keyValuePairs) {
+ Debug.Assert(keyValuePairs.Length % 2 == 0);
+ CustomContext cc = new CustomContext();
+ for (int i = 0; i < keyValuePairs.Length; i += 2)
+ cc[keyValuePairs[i]] = keyValuePairs[i + 1];
+ return EvalXPathExpr(doc, xpe, cc);
+ }
+
+ /// <summary>
+ /// Returns the path argument adjusted to be relative to the base path. Absolute path names will
+ /// be returned unchanged.
+ /// </summary>
+ /// <example>
+ /// path: "xxx/aaa/target.html"
+ /// basePath: "xxx/bbb/source.html"
+ /// result: "../aaa/target.html"
+ /// </example>
+ public static string GetRelativePath(string path, string basePath) {
+ // ignore absolute path names and an empty basePath
+ if (!string.IsNullOrEmpty(path) && path[0] != '/' && !string.IsNullOrEmpty(basePath)) {
+
+ List<string> pathParts = new List<string>(path.Split('/'));
+ List<string> basePathParts = new List<string>(basePath.Split('/'));
+
+ // remove the base path file name
+ if (basePathParts.Count > 0)
+ basePathParts.RemoveAt(basePathParts.Count - 1);
+
+ // strip common base path bits
+ while (pathParts.Count > 0 && basePathParts.Count > 0 &&
+ string.Equals(pathParts[0], basePathParts[0], StringComparison.CurrentCultureIgnoreCase)) {
+ pathParts.RemoveAt(0);
+ basePathParts.RemoveAt(0);
+ }
+
+ // move up one level for each remaining base path part
+ foreach (string s in basePathParts)
+ pathParts.Insert(0, "..");
+
+ path = string.Join("/", pathParts.ToArray());
+ }
+
+ return path;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildContext.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildContext.cs
new file mode 100644
index 0000000..8a21675
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/BuildContext.cs
@@ -0,0 +1,176 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class BuildContext {
+
+ private CustomContext context = new CustomContext();
+
+ // Namespace control
+
+ public void AddNamespace (string prefix, string uri) {
+ context.AddNamespace(prefix, uri);
+ }
+
+ public string LookupNamespace (string prefix) {
+ return( context.LookupNamespace(prefix) );
+ }
+
+ public bool RemoveNamespace (string prefix) {
+ string uri = LookupNamespace(prefix);
+ if (uri == null) {
+ return(false);
+ } else {
+ context.RemoveNamespace(prefix, uri);
+ return(true);
+ }
+ }
+
+ public void ClearNamespaces () {
+ }
+
+ // Variable control
+
+ public void AddVariable (string name, string value) {
+ context[name] = value;
+ }
+
+ public string LookupVariable (string name) {
+ return( context[name] );
+ }
+
+ public bool RemoveVariable (string name) {
+ return( context.ClearVariable(name) );
+ }
+
+ public void ClearVariables () {
+ context.ClearVariables();
+ }
+
+ public string this [string name] {
+ get {
+ return(context[name]);
+ }
+ set {
+ context[name] = value;
+ }
+ }
+
+ // Function control
+
+ // The context for use in XPath queries
+
+ public XsltContext XsltContext {
+ get {
+ return(context);
+ }
+ }
+
+ // Load data from config
+
+ public void Load (XPathNavigator configuration) {
+ XPathNodeIterator namespaceNodes = configuration.Select("namespace");
+ foreach (XPathNavigator namespaceNode in namespaceNodes) {
+ string prefixValue = namespaceNode.GetAttribute("prefix", String.Empty);
+ string uriValue = namespaceNode.GetAttribute("uri", String.Empty);
+ AddNamespace(prefixValue, uriValue);
+ }
+ }
+
+ }
+
+ public class CustomContext : XsltContext {
+
+ public CustomContext() : base() {}
+
+ // variable control
+
+ private Dictionary<string, IXsltContextVariable> variables = new Dictionary<string,IXsltContextVariable>();
+
+ public string this [string variable] {
+ get {
+ return(variables[variable].Evaluate(this).ToString());
+ }
+ set {
+ variables[variable] = new CustomVariable(value);
+ }
+ }
+
+ public bool ClearVariable (string name) {
+ return( variables.Remove(name) );
+ }
+
+ public void ClearVariables () {
+ variables.Clear();
+ }
+
+ // Implementation of XsltContext methods
+
+ public override IXsltContextVariable ResolveVariable (string prefix, string name) {
+ return( variables[name] );
+ }
+
+ public override IXsltContextFunction ResolveFunction (string prefix, string name, XPathResultType[] argumentTypes) {
+ throw new NotImplementedException();
+ }
+
+ public override int CompareDocument (string baseUri, string nextBaseUri) {
+ return(0);
+ }
+
+ public override bool Whitespace {
+ get {
+ return(true);
+ }
+ }
+
+ public override bool PreserveWhitespace (XPathNavigator node) {
+ return(true);
+ }
+
+ }
+
+
+ internal struct CustomVariable : IXsltContextVariable {
+
+ public CustomVariable (string value) {
+ this.value = value;
+ }
+
+ private string value;
+
+ public bool IsLocal {
+ get {
+ return(false);
+ }
+ }
+
+ public bool IsParam {
+ get {
+ return(false);
+ }
+ }
+
+ public XPathResultType VariableType {
+ get {
+ return(XPathResultType.String);
+ }
+ }
+
+ public Object Evaluate (XsltContext context) {
+ return(value);
+ }
+
+ }
+
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/GlobalSuppressions.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/GlobalSuppressions.cs
new file mode 100644
index 0000000..710997a
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/GlobalSuppressions.cs
@@ -0,0 +1,45 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#Apply(System.Collections.Generic.IEnumerable`1<System.String>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#BuildComponents")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Filename", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#GetFileManifestBuildContextEnumerator(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#LoadComponent(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#LoadComponent(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#LoadComponent(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "components", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#LoadComponents(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildAssembler.#WriteComponentMessageToConsole(System.Type,Microsoft.Ddue.Tools.MessageLevel,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "configuration", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XmlNode", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponent.#Apply(System.Xml.XmlDocument)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XmlNode", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "e", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#GetExceptionMessage(System.Exception)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#GetExceptionMessage(System.Exception)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#GetExceptionMessage(System.Exception)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "s", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#GetRelativePath(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildContext.#AddNamespace(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildContext.#ClearNamespaces()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1010:CollectionsShouldImplementGenericInterface", Scope = "type", Target = "Microsoft.Ddue.Tools.CustomContext")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.CustomContext")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.CustomContext.#CompareDocument(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "2#", Scope = "member", Target = "Microsoft.Ddue.Tools.CustomContext.#ResolveFunction(System.String,System.String,System.Xml.XPath.XPathResultType[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Expr", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "c", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "xpe", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Expr", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "xpe", Scope = "member", Target = "Microsoft.Ddue.Tools.BuildComponentUtilities.#EvalXPathExpr(System.Xml.XPath.IXPathNavigable,System.Xml.XPath.XPathExpression,System.String[])")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e87d8d5
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildAssemblerLibrary/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BuildAssemblerLibrary")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("BuildAssemblerLibrary")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8dc79b50-d46d-4e02-b2e6-43abc681e189")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/BuildComponents.csproj b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/BuildComponents.csproj
new file mode 100644
index 0000000..9e3932f
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/BuildComponents.csproj
@@ -0,0 +1,155 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>BuildComponents</RootNamespace>
+ <AssemblyName>BuildComponents</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="HxfGeneratorComponent.cs" />
+ <Compile Include="IntellisenseComponent2.cs" />
+ <Compile Include="MsdnResolver.cs" />
+ <Compile Include="References.cs" />
+ <Compile Include="ResolveReferenceLinksComponent2.cs" />
+ <Compile Include="CloneComponent.cs" />
+ <Compile Include="CodeReference.cs" />
+ <Compile Include="CopyFromFileComponent.cs" />
+ <Compile Include="CopyFromFiles.cs" />
+ <Compile Include="CopyFromIndexComponent.cs" />
+ <Compile Include="DisplayComponent.cs" />
+ <Compile Include="ExampleComponent.cs" />
+ <Compile Include="ForEachComponent.cs" />
+ <Compile Include="IfThenComponent.cs" />
+ <Compile Include="IndexedFileCache.cs" />
+ <Compile Include="IntellisenseComponent.cs" />
+ <Compile Include="LiveExampleComponent.cs" />
+ <Compile Include="MsdnService.cs" />
+ <Compile Include="PlatformsComponent.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ResolveArtLinksComponent.cs" />
+ <Compile Include="ResolveConceptualLinksComponent.cs" />
+ <Compile Include="SaveComponent.cs" />
+ <Compile Include="SharedContentComponent.cs" />
+ <Compile Include="SnippetComponent.cs" />
+ <Compile Include="SwitchComponent.cs" />
+ <Compile Include="SyntaxComponent.cs" />
+ <Compile Include="TargetCollection.cs" />
+ <Compile Include="Targets.cs" />
+ <Compile Include="TaskGrabberComponent.cs" />
+ <Compile Include="TransformComponent.cs" />
+ <Compile Include="ValidateComponent.cs" />
+ <Compile Include="WdxResolveConceptualLinksComponent.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BuildAssemblerLibrary\BuildAssemblerLibrary.csproj">
+ <Project>{399E78F8-4954-409E-991A-37DA9D0579CC}</Project>
+ <Name>BuildAssemblerLibrary</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CloneComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CloneComponent.cs
new file mode 100644
index 0000000..d22ccf5
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CloneComponent.cs
@@ -0,0 +1,44 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+using System.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class CloneComponent : BuildComponent {
+
+ private List<IEnumerable<BuildComponent>> branches = new List<IEnumerable<BuildComponent>>();
+
+ public CloneComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNodeIterator branch_nodes = configuration.Select("branch");
+ foreach (XPathNavigator branch_node in branch_nodes) {
+ BuildComponent[] branch = BuildAssembler.LoadComponents(branch_node);
+ branches.Add(branch);
+ }
+
+ }
+
+ public override void Apply (XmlDocument document, string key) {
+
+ foreach (IEnumerable<BuildComponent> branch in branches) {
+ XmlDocument subdocument = document.Clone() as XmlDocument;
+ foreach(BuildComponent component in branch) {
+ component.Apply(subdocument, key);
+ }
+ }
+
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CodeReference.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CodeReference.cs
new file mode 100644
index 0000000..c0cbd11
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CodeReference.cs
@@ -0,0 +1,117 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ public enum CodeReferenceType {
+ Invalid, // not initialized, invalid reference string
+ Snippet, // MSDN style snippet for all build targets
+ Msdn, // MSDN style snippet for MSDN build only
+ Run, // runnable code sample with pop-up source browser for WebDocs build
+ View // code sample shown in pop-up source browser for WebDocs build
+ }
+
+ /// <summary>
+ /// The CodeReference class encapsulates DDUE code reference elements and provides easy access
+ /// to individual code reference parts, such as the type, name, title, etc..
+ /// </summary>
+ /// <remarks>
+ /// Examples of valid code reference strings include:
+ /// - SampleName#SnippetNumber
+ /// - SampleName#SnippetNumber1,SnippetNumber2,SnippetNumber3
+ /// - msdn:SampleName#SnippetNumber
+ /// - run:SampleName
+ /// - run:SampleName;title text
+ /// - run:SampleName#startPage.aspx
+ /// - run:SampleName/path/to/startPage.aspx
+ /// - run:SampleName#startPage.aspx;title text
+ /// - run:SampleName/path/to/startPage.aspx;title text
+ /// - view:SampleName
+ /// - view:SampleName#defaultFile
+ /// - view:SampleName/path/to/defaultFile
+ /// - view:SampleName#defaultFile;title text
+ /// - view:SampleName/path/to/defaultFile;title text
+ /// </remarks>
+ public class CodeReference {
+
+ string _ddueCodeReference;
+ public string DdueCodeReference {
+ get { return _ddueCodeReference; }
+ }
+
+ CodeReferenceType _type;
+ public CodeReferenceType Type {
+ get { return _type; }
+ }
+
+ string _exampleName;
+ public string ExampleName {
+ get { return _exampleName; }
+ }
+
+ string _examplePath;
+ public string ExamplePath {
+ get { return _examplePath; }
+ }
+
+ string _snippetId;
+ public string SnippetId {
+ get { return _snippetId; }
+ }
+
+ string _title;
+ public string Title {
+ get { return _title; }
+ }
+
+ public CodeReference(string ddueCodeReference) {
+ _ddueCodeReference = ddueCodeReference;
+ Parse();
+ }
+
+ static Regex codeReferenceRx = new Regex(
+ @"^\s*(" +
+ @"((?<type>msdn|run|view):)?" +
+ @"(?<examplePath>(" +
+ @"(?<exampleName>[\w\.,\-]+)" +
+ @"((#(?<snippetId>[\w,]+))|(([/\\#,\.\w\-]+)?))" +
+ @"))" +
+ @"(;(?<title>.*))?" +
+ @")\s*$",
+ RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ void Parse() {
+ Match m = codeReferenceRx.Match(DdueCodeReference);
+ if (m.Success) {
+ _exampleName = m.Groups["exampleName"].Value;
+ _snippetId = m.Groups["snippetId"].Value;
+ _examplePath = m.Groups["examplePath"].Value;
+ _title = m.Groups["title"].Value;
+ // The default value of _type is CodeReferenceType.Invalid, if it isn't set in the following
+ // block.
+ if (m.Groups["type"].Length > 0) {
+ try {
+ _type = (CodeReferenceType)Enum.Parse(typeof(CodeReferenceType), m.Groups["type"].Value, true);
+ }
+ catch (ArgumentException) {
+ // _type = CodeReferenceType.Invalid
+ }
+ }
+ else if (m.Groups["exampleName"].Length > 0 && m.Groups["snippetId"].Length > 0) {
+ _type = CodeReferenceType.Snippet;
+ }
+ }
+ }
+
+ public override string ToString() {
+ return DdueCodeReference;
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ComputeHashComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ComputeHashComponent.cs
new file mode 100644
index 0000000..37755ab
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ComputeHashComponent.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ internal class HashComputation {
+
+ public HashComputation (string input, string output) {
+ Input = XPathExpression.Compile(input);
+ Output = XPathExpression.Compile(output);
+ }
+
+ public XPathExpression Input;
+ public XPathExpression Output;
+
+ }
+
+ public class ComputeHashComponent : BuildComponent {
+
+ public ComputeHashComponent (XPathNavigator configuration) : base(configuration) {
+
+ if (configuration == null) throw new ArgumentNullException("configuraton");
+
+ XPathNodeIterator hash_nodes = configuration.Select("hash");
+ foreach (XPathNavigator hash_node in hash_nodes) {
+ string input_xpath = hash_node.GetAttribute("input", String.Empty);
+ string output_xpath = hash_node.GetAttribute("output", String.Empty);
+ computations.Add( new HashComputation(input_xpath, output_xpath) );
+ }
+
+ }
+
+ // A list of the hash computations to do
+
+ private List<HashComputation> computations = new List<HashComputation>();
+
+ // Logic to compute a unique hash of a comment id string
+
+ private static Guid ComputeHash (string key) {
+ byte[] input = Encoding.UTF8.GetBytes(key);
+ byte[] output = md5.ComputeHash(input);
+ return( new Guid(output) );
+ }
+
+ private static HashAlgorithm md5 = new MD5CryptoServiceProvider();
+
+ // The actual action of the component
+
+ public override void Apply (XmlDocument document, string key) {
+
+ Guid id = ComputeHash(key);
+
+ foreach (HashComputation computation in computations) {
+ XPathNavigator output = document.CreateNavigator().SelectSingleNode(computation.Output);
+ if (output == null) continue;
+ output.SetValue(id.ToString());
+ }
+
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs
new file mode 100644
index 0000000..2c4eedb
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFileComponent.cs
@@ -0,0 +1,146 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class CopyFromFileComponent : BuildComponent {
+
+ public CopyFromFileComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ if (configuration == null) throw new ArgumentNullException("configuration");
+
+ string data_name = null;
+
+ // get information about the data file
+ XPathNodeIterator data_nodes = configuration.Select("data");
+ foreach (XPathNavigator data_node in data_nodes) {
+ string data_file = data_node.GetAttribute("file", String.Empty);
+ if (String.IsNullOrEmpty(data_file)) WriteMessage(MessageLevel.Error, "Data elements must have a file attribute specifying a file from which to load data.");
+ data_file = Environment.ExpandEnvironmentVariables(data_file);
+
+ data_name = data_node.GetAttribute("name", String.Empty);
+ if (String.IsNullOrEmpty(data_name)) data_name = Guid.NewGuid().ToString();
+
+ // load a schema, if one is specified
+ string schema_file = data_node.GetAttribute("schema", String.Empty);
+ XmlReaderSettings settings = new XmlReaderSettings();
+ if (!String.IsNullOrEmpty(schema_file)) {
+ settings.Schemas.Add(null, schema_file);
+ }
+
+ // load the document
+ WriteMessage(MessageLevel.Info, String.Format("Loading data file '{0}'.", data_file) );
+ using (XmlReader reader = XmlReader.Create(data_file, settings)) {
+ XPathDocument data_document = new XPathDocument(reader);
+ Data.Add(data_name, data_document);
+ }
+ }
+
+
+ // get the source and target expressions for each copy command
+ XPathNodeIterator copy_nodes = configuration.Select("copy");
+ foreach (XPathNavigator copy_node in copy_nodes) {
+ string source_name = copy_node.GetAttribute("name", String.Empty);
+ if (String.IsNullOrEmpty(source_name)) source_name = data_name;
+
+ XPathDocument source_document = (XPathDocument) Data[source_name];
+
+ string source_xpath = copy_node.GetAttribute("source", String.Empty);
+ if (String.IsNullOrEmpty(source_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromFile component, you must specify a source xpath format using the source attribute.");
+ string target_xpath = copy_node.GetAttribute("target", String.Empty);
+ if (String.IsNullOrEmpty(target_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromFile component, you must specify a target xpath format using the target attribute.");
+ copy_commands.Add( new CopyFromFileCommand(source_document, source_xpath, target_xpath) );
+ }
+
+ }
+
+ // private XPathDocument data_document;
+
+ private List<CopyFromFileCommand> copy_commands = new List<CopyFromFileCommand>();
+
+ private CustomContext context = new CustomContext();
+
+ // the work of the component
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // set the key in the XPath context
+ context["key"] = key;
+
+ // iterate over the copy commands
+ foreach (CopyFromFileCommand copy_command in copy_commands) {
+
+ // extract the target node
+ XPathExpression target_xpath = copy_command.Target.Clone();
+ target_xpath.SetContext(context);
+ XPathNavigator target = document.CreateNavigator().SelectSingleNode(target_xpath);
+
+ // warn if target not found?
+ if (target == null) {
+ continue;
+ }
+
+ // extract the source nodes
+ XPathExpression source_xpath = copy_command.Source.Clone();
+ source_xpath.SetContext(context);
+ XPathNodeIterator sources = copy_command.SourceDocument.CreateNavigator().Select(source_xpath);
+
+ // warn if source not found?
+
+ // append the source nodes to the target node
+ foreach (XPathNavigator source in sources) {
+ target.AppendChild(source);
+ }
+
+ }
+
+ }
+
+ }
+
+
+ // a representation of a copying operation
+
+ internal class CopyFromFileCommand {
+
+ public CopyFromFileCommand (XPathDocument source_document, string source_xpath, string target_xpath) {
+ this.source_document = source_document;
+ source = XPathExpression.Compile(source_xpath);
+ target = XPathExpression.Compile(target_xpath);
+ }
+
+ private XPathDocument source_document;
+
+ private XPathExpression source;
+
+ private XPathExpression target;
+
+ public XPathDocument SourceDocument {
+ get {
+ return(source_document);
+ }
+ }
+
+ public XPathExpression Source {
+ get {
+ return(source);
+ }
+ }
+
+ public XPathExpression Target {
+ get {
+ return(target);
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFiles.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFiles.cs
new file mode 100644
index 0000000..b05903d
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromFiles.cs
@@ -0,0 +1,95 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class CopyFromFilesComponent : BuildComponent {
+
+ public CopyFromFilesComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+ XPathNodeIterator copy_nodes = configuration.Select("copy");
+ foreach (XPathNavigator copy_node in copy_nodes) {
+
+ string root_value = copy_node.GetAttribute("base", String.Empty);
+ if (String.IsNullOrEmpty(root_value)) root_value = Environment.CurrentDirectory;
+ root_value = Environment.ExpandEnvironmentVariables(root_value);
+ if (!Directory.Exists(root_value)) WriteMessage(MessageLevel.Error, String.Format("The base directory '{0}' does not exist.", root_value));
+
+ string file_value = copy_node.GetAttribute("file", String.Empty);
+ if (String.IsNullOrEmpty(file_value)) WriteMessage(MessageLevel.Error, "Each copy element must have a file attribute specifying the file to copy from.");
+
+ string source_value = copy_node.GetAttribute("source", String.Empty);
+ string target_value = copy_node.GetAttribute("target", String.Empty);
+
+ CopyFromFilesCommand copy_command = new CopyFromFilesCommand(root_value, file_value, source_value, target_value);
+ copy_commands.Add(copy_command);
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} copy commands.", copy_commands.Count));
+ }
+
+ List<CopyFromFilesCommand> copy_commands = new List<CopyFromFilesCommand>();
+
+ private CustomContext context = new CustomContext();
+
+ public override void Apply (XmlDocument document, string key) {
+ context["key"] = key;
+ foreach (CopyFromFilesCommand copy_command in copy_commands) {
+ copy_command.Apply(document, context);
+ }
+ }
+
+ }
+
+ internal class CopyFromFilesCommand {
+
+ public CopyFromFilesCommand (string root, string file, string source, string target) {
+ root_directory = root;
+ file_expression = XPathExpression.Compile(file);
+ source_expression = XPathExpression.Compile(source);
+ target_expression = XPathExpression.Compile(target);
+ }
+
+ private string root_directory;
+
+ private XPathExpression file_expression;
+
+ private XPathExpression source_expression;
+
+ private XPathExpression target_expression;
+
+ public void Apply (XmlDocument targetDocument, IXmlNamespaceResolver context) {
+
+ XPathExpression local_file_expression = file_expression.Clone();
+ local_file_expression.SetContext(context);
+
+ XPathExpression local_source_expression = source_expression.Clone();
+ local_source_expression.SetContext(context);
+
+ XPathExpression local_target_expression = target_expression.Clone();
+ local_target_expression.SetContext(context);
+
+ string file_name = (string) targetDocument.CreateNavigator().Evaluate(local_file_expression);
+ string file_path = Path.Combine(root_directory, file_name);
+
+ if (!File.Exists(file_path)) return;
+ XPathDocument sourceDocument = new XPathDocument(file_path);
+
+ XPathNavigator target_node = targetDocument.CreateNavigator().SelectSingleNode(local_target_expression);
+ if (target_node == null) return;
+
+ XPathNodeIterator source_nodes = sourceDocument.CreateNavigator().Select(local_source_expression);
+ foreach (XPathNavigator source_node in source_nodes) {
+ target_node.AppendChild(source_node);
+ }
+
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromIndexComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromIndexComponent.cs
new file mode 100644
index 0000000..bf19dc8
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/CopyFromIndexComponent.cs
@@ -0,0 +1,677 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+using System.Reflection;
+using System.Xml.Xsl; /* for custom context stuff */
+
+namespace Microsoft.Ddue.Tools {
+
+ public class CopyFromIndexComponent : BuildComponent {
+
+ // XPath search patterns
+
+ // List of copy components
+ private List<CopyComponent> components = new List<CopyComponent>();
+
+ // what to copy
+ private List<CopyCommand> copy_commands = new List<CopyCommand>();
+
+ // a context in which to evaluate XPath expressions
+ private CustomContext context = new CustomContext();
+
+ public CopyFromIndexComponent(BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration) {
+
+ // set up the context
+ XPathNodeIterator context_nodes = configuration.Select("context");
+ foreach (XPathNavigator context_node in context_nodes) {
+ string prefix = context_node.GetAttribute("prefix", String.Empty);
+ string name = context_node.GetAttribute("name", String.Empty);
+ context.AddNamespace(prefix, name);
+ }
+
+ // set up the indices
+ XPathNodeIterator index_nodes = configuration.Select("index");
+ foreach (XPathNavigator index_node in index_nodes) {
+
+ // get the name of the index
+ string name = index_node.GetAttribute("name", String.Empty);
+ if (String.IsNullOrEmpty(name)) throw new ConfigurationErrorsException("Each index must have a unique name.");
+
+ // get the xpath for value nodes
+ string value_xpath = index_node.GetAttribute("value", String.Empty);
+ if (String.IsNullOrEmpty(value_xpath)) WriteMessage(MessageLevel.Error, "Each index element must have a value attribute containing an XPath that describes index entries.");
+
+ // get the xpath for keys (relative to value nodes)
+ string key_xpath = index_node.GetAttribute("key", String.Empty);
+ if (String.IsNullOrEmpty(key_xpath)) WriteMessage(MessageLevel.Error, "Each index element must have a key attribute containing an XPath (relative to the value XPath) that evaluates to the entry key.");
+
+ // get the cache size
+ int cache = 10;
+ string cache_value = index_node.GetAttribute("cache", String.Empty);
+ if (!String.IsNullOrEmpty(cache_value)) cache = Convert.ToInt32(cache_value);
+
+ // create the index
+ IndexedDocumentCache index = new IndexedDocumentCache(this, key_xpath, value_xpath, context, cache);
+
+ // search the data directories for entries
+ XPathNodeIterator data_nodes = index_node.Select("data");
+ foreach (XPathNavigator data_node in data_nodes) {
+
+ string base_value = data_node.GetAttribute("base", String.Empty);
+ if (!String.IsNullOrEmpty(base_value)) base_value = Environment.ExpandEnvironmentVariables(base_value);
+
+ bool recurse = false;
+ string recurse_value = data_node.GetAttribute("recurse", String.Empty);
+ if (!String.IsNullOrEmpty(recurse_value)) recurse = (bool)Convert.ToBoolean(recurse_value);
+
+ // get the files
+ string files = data_node.GetAttribute("files", String.Empty);
+ if (String.IsNullOrEmpty(files)) WriteMessage(MessageLevel.Error, "Each data element must have a files attribute specifying which files to index.");
+ // if ((files == null) || (files.Length == 0)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a directory path using the files attribute.");
+ files = Environment.ExpandEnvironmentVariables(files);
+
+ WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", files));
+ index.AddDocuments(base_value, files, recurse);
+
+ }
+ WriteMessage(MessageLevel.Info, String.Format("Indexed {0} elements in {1} files.", index.Count, index.DocumentCount));
+
+ Data.Add(name, index);
+
+ }
+
+ // get the copy commands
+ XPathNodeIterator copy_nodes = configuration.Select("copy");
+ foreach (XPathNavigator copy_node in copy_nodes) {
+
+ string source_name = copy_node.GetAttribute("name", String.Empty);
+ if (String.IsNullOrEmpty(source_name)) throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
+
+ string key_xpath = copy_node.GetAttribute("key", String.Empty);
+
+ string source_xpath = copy_node.GetAttribute("source", String.Empty);
+ if (String.IsNullOrEmpty(source_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a source xpath format using the source attribute.");
+
+ string target_xpath = copy_node.GetAttribute("target", String.Empty);
+ if (String.IsNullOrEmpty(target_xpath)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a target xpath format using the target attribute.");
+
+ string attribute_value = copy_node.GetAttribute("attribute", String.Empty);
+
+ string ignoreCase_value = copy_node.GetAttribute("ignoreCase", String.Empty);
+
+ string missingEntryValue = copy_node.GetAttribute("missing-entry", String.Empty);
+ string missingSourceValue = copy_node.GetAttribute("missing-source", String.Empty);
+ string missingTargetValue = copy_node.GetAttribute("missing-target", String.Empty);
+
+ IndexedDocumentCache index = (IndexedDocumentCache)Data[source_name];
+
+ CopyCommand copyCommand = new CopyCommand(index, key_xpath, source_xpath, target_xpath, attribute_value, ignoreCase_value);
+ if (!String.IsNullOrEmpty(missingEntryValue)) {
+ try {
+ copyCommand.MissingEntry = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingEntryValue, true);
+ } catch (ArgumentException) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingEntryValue));
+ }
+ }
+ if (!String.IsNullOrEmpty(missingSourceValue)) {
+ try {
+ copyCommand.MissingSource = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingSourceValue, true);
+ } catch (ArgumentException) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingSourceValue));
+ }
+ }
+ if (!String.IsNullOrEmpty(missingTargetValue)) {
+ try {
+ copyCommand.MissingTarget = (MessageLevel)Enum.Parse(typeof(MessageLevel), missingTargetValue, true);
+ } catch (ArgumentException) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a message level.", missingTargetValue));
+ }
+ }
+
+ copy_commands.Add(copyCommand);
+
+ }
+
+ XPathNodeIterator component_nodes = configuration.Select("components/component");
+ foreach (XPathNavigator component_node in component_nodes) {
+
+ // get the data to load the component
+ string assembly_path = component_node.GetAttribute("assembly", String.Empty);
+ if (String.IsNullOrEmpty(assembly_path)) WriteMessage(MessageLevel.Error, "Each component element must have an assembly attribute.");
+ string type_name = component_node.GetAttribute("type", String.Empty);
+ if (String.IsNullOrEmpty(type_name)) WriteMessage(MessageLevel.Error, "Each component element must have a type attribute.");
+
+ // expand environment variables in the path
+ assembly_path = Environment.ExpandEnvironmentVariables(assembly_path);
+
+ //Console.WriteLine("loading {0} from {1}", type_name, assembly_path);
+ try
+ {
+ Assembly assembly = Assembly.LoadFrom(assembly_path);
+ CopyComponent component = (CopyComponent)assembly.CreateInstance(type_name, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { component_node.Clone(), Data }, null, null);
+
+ if (component == null)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'.", type_name, assembly_path));
+ }
+ else
+ {
+ components.Add(component);
+ }
+
+ }
+ catch (IOException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("A file access error occured while attempting to load the build component '{0}'. The error message is: {1}", assembly_path, e.Message));
+ }
+ catch (BadImageFormatException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("A syntax generator assembly '{0}' is invalid. The error message is: {1}.", assembly_path, e.Message));
+ }
+ catch (TypeLoadException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.Message));
+ }
+ catch (MissingMethodException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' does not have an appropriate constructor. The error message is: {2}", type_name, assembly_path, e.Message));
+ }
+ catch (TargetInvocationException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to instantiate the type '{0}' in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.InnerException.Message));
+ }
+ catch (InvalidCastException)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' is not a SyntaxGenerator.", type_name, assembly_path));
+ }
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} copy components.", components.Count));
+
+ }
+
+ // the actual work of the component
+
+ public override void Apply(XmlDocument document, string key) {
+
+ // set the key in the XPath context
+ context["key"] = key;
+
+ // perform each copy action
+ foreach (CopyCommand copy_command in copy_commands) {
+
+ // get the source comment
+ XPathExpression key_expression = copy_command.Key.Clone();
+ key_expression.SetContext(context);
+ // Console.WriteLine(key_expression.Expression);
+ string key_value = (string)document.CreateNavigator().Evaluate(key_expression);
+ // Console.WriteLine("got key '{0}'", key_value);
+ XPathNavigator data = copy_command.Index.GetContent(key_value);
+
+ if (data == null && copy_command.IgnoreCase == "true") data = copy_command.Index.GetContent(key_value.ToLower());
+
+ // notify if no entry
+ if (data == null) {
+ WriteMessage(copy_command.MissingEntry, String.Format("No index entry found for key '{0}'.", key_value));
+ continue;
+ }
+
+ // get the target node
+ String target_xpath = copy_command.Target.Clone().ToString();
+ XPathExpression target_expression = XPathExpression.Compile(string.Format(target_xpath, key_value));
+ target_expression.SetContext(context);
+
+ XPathNavigator target = document.CreateNavigator().SelectSingleNode(target_expression);
+
+ // notify if no target found
+ if (target == null) {
+ WriteMessage(copy_command.MissingTarget, String.Format("Target node '{0}' not found.", target_expression.Expression));
+ continue;
+ }
+
+ // get the source nodes
+ XPathExpression source_expression = copy_command.Source.Clone();
+ source_expression.SetContext(context);
+ XPathNodeIterator sources = data.CreateNavigator().Select(source_expression);
+
+ // append the source nodes to the target node
+ int source_count = 0;
+ foreach (XPathNavigator source in sources) {
+ source_count++;
+
+ // If attribute=true, add the source attributes to current target.
+ // Otherwise append source as a child element to target
+ if (copy_command.Attribute == "true" && source.HasAttributes) {
+ string source_name = source.LocalName;
+ XmlWriter attributes = target.CreateAttributes();
+
+ source.MoveToFirstAttribute();
+ string attrFirst = target.GetAttribute(string.Format("{0}_{1}", source_name, source.Name), string.Empty);
+ if (string.IsNullOrEmpty(attrFirst)) attributes.WriteAttributeString(string.Format("{0}_{1}", source_name, source.Name), source.Value);
+
+ while (source.MoveToNextAttribute()) {
+ string attrNext = target.GetAttribute(string.Format("{0}_{1}", source_name, source.Name), string.Empty);
+ if (string.IsNullOrEmpty(attrNext)) attributes.WriteAttributeString(string.Format("{0}_{1}", source_name, source.Name), source.Value);
+ }
+ attributes.Close();
+ }
+ else target.AppendChild(source);
+ }
+
+ // notify if no source found
+ if (source_count == 0) {
+ WriteMessage(copy_command.MissingSource, String.Format("Source node '{0}' not found.", source_expression.Expression));
+ }
+
+ foreach (CopyComponent component in components)
+ {
+ component.Apply(document, key);
+ }
+ }
+ }
+
+ internal void WriteHelperMessage(MessageLevel level, string message) {
+ WriteMessage(level, message);
+ }
+
+ }
+
+ // the storage system
+
+ public class IndexedDocumentCache {
+
+ public IndexedDocumentCache(CopyFromIndexComponent component, string keyXPath, string valueXPath, XmlNamespaceManager context, int cacheSize) {
+
+ if (component == null) throw new ArgumentNullException("component");
+ if (cacheSize < 0) throw new ArgumentOutOfRangeException("cacheSize");
+
+ this.component = component;
+
+ try {
+ keyExpression = XPathExpression.Compile(keyXPath);
+ } catch (XPathException) {
+ component.WriteHelperMessage(MessageLevel.Error, String.Format("The key expression '{0}' is not a valid XPath expression.", keyXPath));
+ }
+ keyExpression.SetContext(context);
+
+ try {
+ valueExpression = XPathExpression.Compile(valueXPath);
+ } catch (XPathException) {
+ component.WriteHelperMessage(MessageLevel.Error, String.Format("The value expression '{0}' is not a valid XPath expression.", valueXPath));
+ }
+ valueExpression.SetContext(context);
+
+ this.cacheSize = cacheSize;
+
+ // set up the cache
+ cache = new Dictionary<string, IndexedDocument>(cacheSize);
+ queue = new Queue<string>(cacheSize);
+ }
+
+ // index component to which the cache belongs
+ private CopyFromIndexComponent component;
+
+ public CopyFromIndexComponent Component {
+ get {
+ return (component);
+ }
+ }
+
+ // search pattern for index values
+ private XPathExpression valueExpression;
+
+ public XPathExpression ValueExpression {
+ get {
+ return (valueExpression);
+ }
+ }
+
+ // search pattern for the index keys (relative to the index value node)
+ private XPathExpression keyExpression;
+
+ public XPathExpression KeyExpression {
+ get {
+ return (keyExpression);
+ }
+ }
+
+ // a index mapping keys to the files that contain them
+ private Dictionary<string, string> index = new Dictionary<string, string>();
+
+ public void AddDocument(string file) {
+
+ // load the document
+ IndexedDocument document = new IndexedDocument(this, file);
+
+ // record the keys
+ string[] keys = document.GetKeys();
+ foreach (string key in keys) {
+ if (index.ContainsKey(key)) {
+ component.WriteHelperMessage(MessageLevel.Warn, String.Format("Entries for the key '{0}' occur in both '{1}' and '{2}'. The last entry will be used.", key, index[key], file));
+ }
+ index[key] = file;
+
+ }
+
+ }
+
+ public void AddDocuments(string wildcardPath) {
+ string directory_part = Path.GetDirectoryName(wildcardPath);
+ if (String.IsNullOrEmpty(directory_part)) directory_part = Environment.CurrentDirectory;
+ directory_part = Path.GetFullPath(directory_part);
+ string file_part = Path.GetFileName(wildcardPath);
+ //Console.WriteLine("{0}::{1}", directory_part, file_part);
+ string[] files = Directory.GetFiles(directory_part, file_part);
+ foreach (string file in files) {
+ AddDocument(file);
+ }
+
+ //Console.WriteLine(files.Length);
+ documentCount += files.Length;
+ }
+
+ public void AddDocuments(string baseDirectory, string wildcardPath, bool recurse) {
+
+ string path;
+ if (String.IsNullOrEmpty(baseDirectory)) {
+ path = wildcardPath;
+ } else {
+ path = Path.Combine(baseDirectory, wildcardPath);
+ }
+
+ AddDocuments(path);
+
+ if (recurse) {
+ string[] subDirectories = Directory.GetDirectories(baseDirectory);
+ foreach (string subDirectory in subDirectories) AddDocuments(subDirectory, wildcardPath, recurse);
+ }
+ }
+
+ private int documentCount;
+
+ public int DocumentCount {
+ get {
+ return (documentCount);
+ }
+ }
+
+ // a simple caching mechanism
+
+ int cacheSize;
+
+ // an improved cache
+
+ // this cache keeps track of the order that files are loaded in, and always unloads the oldest one
+ // this is better, but a document that is often accessed gets no "points", so it will eventualy be
+ // thrown out even if it is used regularly
+
+ private Dictionary<string, IndexedDocument> cache;
+
+ private Queue<string> queue;
+
+ public IndexedDocument GetDocument(string key) {
+
+ // look up the file corresponding to the key
+ string file;
+ if (index.TryGetValue(key, out file)) {
+
+ // now look for that file in the cache
+ IndexedDocument document;
+ if (!cache.TryGetValue(file, out document)) {
+
+ // not in the cache, so load it
+ document = new IndexedDocument(this, file);
+
+ // if the cache is full, remove a document
+ if (cache.Count >= cacheSize) {
+ string fileToUnload = queue.Dequeue();
+ cache.Remove(fileToUnload);
+ }
+
+ // add it to the cache
+ cache.Add(file, document);
+ queue.Enqueue(file);
+
+ }
+
+ // XPathNavigator content = document.GetContent(key);
+ return (document);
+
+ } else {
+ // there is no such key
+ return (null);
+ }
+
+ }
+
+
+ public XPathNavigator GetContent(string key) {
+
+ IndexedDocument document = GetDocument(key);
+ if (document == null) {
+ return (null);
+ } else {
+ return (document.GetContent(key));
+ }
+
+ }
+
+ public int Count {
+ get {
+ return (index.Count);
+ }
+ }
+
+ }
+
+ // a file that we have indexed
+
+ public class IndexedDocument {
+
+ public IndexedDocument(IndexedDocumentCache cache, string file) {
+
+ if (cache == null) throw new ArgumentNullException("cache");
+ if (file == null) throw new ArgumentNullException("file");
+
+ // remember the file
+ this.file = file;
+
+ // load the document
+ try {
+ //XPathDocument document = new XPathDocument(file, XmlSpace.Preserve);
+ XPathDocument document = new XPathDocument(file);
+
+ // search for value nodes
+ XPathNodeIterator valueNodes = document.CreateNavigator().Select(cache.ValueExpression);
+ // Console.WriteLine("found {0} instances of '{1}' (key xpath is '{2}')", valueNodes.Count, valueExpression.Expression, keyExpression.Expression);
+
+ // get the key string for each value node and record it in the index
+ foreach (XPathNavigator valueNode in valueNodes) {
+
+ XPathNavigator keyNode = valueNode.SelectSingleNode(cache.KeyExpression);
+ if (keyNode == null) {
+ // Console.WriteLine("null key");
+ continue;
+ }
+
+ string key = keyNode.Value;
+ index[key] = valueNode;
+ if (!index.ContainsKey(key)) {
+ //index.Add(key, valueNode);
+ } else {
+ // Console.WriteLine("Repeat key '{0}'", key);
+ }
+ }
+
+ } catch (IOException e) {
+ cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("An access error occured while attempting to load the file '{0}'. The error message is: {1}", file, e.Message));
+ } catch (XmlException e) {
+ cache.Component.WriteHelperMessage(MessageLevel.Error, String.Format("The indexed document '{0}' is not a valid XML document. The error message is: {1}", file, e.Message));
+ }
+ // Console.WriteLine("indexed {0} keys", index.Count);
+
+
+ }
+
+ // the indexed file
+
+ private string file;
+
+ // the index that maps keys to positions in the file
+
+ Dictionary<string, XPathNavigator> index = new Dictionary<string, XPathNavigator>();
+
+ // public methods
+
+ public string File {
+ get {
+ return (file);
+ }
+ }
+
+ public XPathNavigator GetContent(string key) {
+ XPathNavigator value = index[key];
+ if (value == null) {
+ return (null);
+ } else {
+ return (value.Clone());
+ }
+ }
+
+ public string[] GetKeys() {
+ string[] keys = new string[Count];
+ index.Keys.CopyTo(keys, 0);
+ return (keys);
+ }
+
+ public int Count {
+ get {
+ return (index.Count);
+ }
+ }
+
+ }
+
+ internal class CopyCommand {
+
+ public CopyCommand(IndexedDocumentCache source_index, string key_xpath, string source_xpath, string target_xpath, string attribute_value, string ignoreCase_value) {
+ this.cache = source_index;
+ if (String.IsNullOrEmpty(key_xpath)) {
+ // Console.WriteLine("null key xpath");
+ key = XPathExpression.Compile("string($key)");
+ } else {
+ // Console.WriteLine("compiling key xpath '{0}'", key_xpath);
+ key = XPathExpression.Compile(key_xpath);
+ }
+ source = XPathExpression.Compile(source_xpath);
+ target = target_xpath;
+ attribute = attribute_value;
+ ignoreCase = ignoreCase_value;
+ }
+
+ private IndexedDocumentCache cache;
+
+ private XPathExpression key;
+
+ private XPathExpression source;
+
+ private String target;
+
+ private String attribute;
+
+ private String ignoreCase;
+
+ private MessageLevel missingEntry = MessageLevel.Ignore;
+
+ private MessageLevel missingSource = MessageLevel.Ignore;
+
+ private MessageLevel missingTarget = MessageLevel.Ignore;
+
+ public IndexedDocumentCache Index {
+ get {
+ return (cache);
+ }
+ }
+
+ public XPathExpression Key {
+ get {
+ return (key);
+ }
+ }
+
+ public XPathExpression Source {
+ get {
+ return (source);
+ }
+ }
+
+ public String Target {
+ get {
+ return (target);
+ }
+ }
+
+ public String Attribute
+ {
+ get
+ {
+ return (attribute);
+ }
+ }
+
+ public String IgnoreCase
+ {
+ get
+ {
+ return (ignoreCase);
+ }
+ }
+
+ public MessageLevel MissingEntry {
+ get {
+ return (missingEntry);
+ }
+ set {
+ missingEntry = value;
+ }
+ }
+
+ public MessageLevel MissingSource {
+ get {
+ return (missingSource);
+ }
+ set {
+ missingSource = value;
+ }
+ }
+
+ public MessageLevel MissingTarget {
+ get {
+ return (missingTarget);
+ }
+ set {
+ missingTarget = value;
+ }
+ }
+
+ }
+
+ // the abstract CopyComponent
+ public abstract class CopyComponent
+ {
+
+ public CopyComponent(XPathNavigator configuration, Dictionary<string, object> data) { }
+
+ public abstract void Apply(XmlDocument document, string key);
+
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/DisplayComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/DisplayComponent.cs
new file mode 100644
index 0000000..33f0934
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/DisplayComponent.cs
@@ -0,0 +1,46 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class DisplayComponent : BuildComponent {
+
+ private string xpath_format = "/";
+
+ public DisplayComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+ XPathNavigator xpath_format_node = configuration.SelectSingleNode("xpath");
+ if (xpath_format_node != null) xpath_format = xpath_format_node.Value;
+ }
+
+ public override void Apply (XmlDocument document, string key) {
+ string xpath = String.Format(xpath_format, key);
+
+ Object result = document.CreateNavigator().Evaluate(xpath);
+
+ if (result == null) {
+ Console.WriteLine("null result");
+ return;
+ }
+
+ XPathNodeIterator nodes = result as XPathNodeIterator;
+ if (nodes != null) {
+ foreach (XPathNavigator node in nodes) {
+ Console.WriteLine(node.OuterXml);
+ }
+ return;
+ }
+
+ Console.WriteLine(result.ToString());
+
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ExampleComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ExampleComponent.cs
new file mode 100644
index 0000000..9ab0be7
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ExampleComponent.cs
@@ -0,0 +1,543 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Configuration;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ // a component to replace code references with snippets from a file
+
+ public class ExampleComponent : BuildComponent {
+
+ // instantiation logic
+
+ public ExampleComponent(BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNodeIterator contentNodes = configuration.Select("examples");
+ foreach (XPathNavigator contentNode in contentNodes) {
+ string file = contentNode.GetAttribute("file", String.Empty);
+ file = Environment.ExpandEnvironmentVariables(file);
+ if (String.IsNullOrEmpty(file)) WriteMessage(MessageLevel.Error, String.Format("Each examples element must contain a file attribute."));
+ LoadContent(file);
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} code snippets", snippets.Count));
+
+ XPathNodeIterator colorsNodes = configuration.Select("colors");
+ foreach (XPathNavigator colorsNode in colorsNodes) {
+ string language = colorsNode.GetAttribute("language", String.Empty);
+ List<ColorizationRule> rules = new List<ColorizationRule>();
+
+ XPathNodeIterator colorNodes = colorsNode.Select("color");
+ foreach (XPathNavigator colorNode in colorNodes) {
+ string pattern = colorNode.GetAttribute("pattern", String.Empty);
+ string region = colorNode.GetAttribute("region", String.Empty);
+ string name = colorNode.GetAttribute("class", String.Empty);
+ if (String.IsNullOrEmpty(region)) {
+ rules.Add( new ColorizationRule(pattern, name) );
+ } else {
+ rules.Add( new ColorizationRule(pattern, region, name) );
+ }
+ }
+
+ colorization[language] = rules;
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} colorization rules for the language '{1}'.", rules.Count, language));
+ }
+
+ context.AddNamespace("ddue", "http://ddue.schemas.microsoft.com/authoring/2003/5");
+
+ selector = XPathExpression.Compile("//ddue:codeReference");
+ selector.SetContext(context);
+ }
+
+ // snippet loading logic
+
+ private void LoadContent(string file) {
+
+ SnippetIdentifier key = new SnippetIdentifier();
+ string language;
+
+ WriteMessage(MessageLevel.Info, String.Format("Loading code snippet file '{0}'.", file));
+ try {
+ XmlReaderSettings settings = new XmlReaderSettings();
+ settings.CheckCharacters = false;
+ XmlReader reader = XmlReader.Create(file, settings);
+
+ try {
+ reader.MoveToContent();
+ while (!reader.EOF) {
+ if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "item")) {
+ key = new SnippetIdentifier(reader.GetAttribute("id"));
+ reader.Read();
+ } else if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "sampleCode")) {
+ language = reader.GetAttribute("language");
+
+ string content = reader.ReadString();
+
+ // If the element is empty, ReadString does not advance the reader, so we must do it manually
+ if (String.IsNullOrEmpty(content)) reader.Read();
+
+ if (!IsLegalXmlText(content)) {
+ Console.WriteLine("Snippet '{0}' language '{1}' contains illegal characters.", key, language);
+ throw new InvalidOperationException();
+ }
+
+ content = StripLeadingSpaces(content);
+
+ StoredSnippet snippet = new StoredSnippet(content, language);
+ List<StoredSnippet> values;
+ if (!snippets.TryGetValue(key, out values)) {
+ values = new List<StoredSnippet>();
+ snippets.Add(key, values);
+ }
+ values.Add(snippet);
+ } else {
+ reader.Read();
+ }
+ }
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Warn, String.Format("The contents of the snippet file '{0}' are not well-formed XML. The error message is: {1}. Some snippets may be lost.", file, e.Message));
+ } finally {
+ reader.Close();
+ }
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to read the snippet file '{0}'. The error message is: {1}", file, e.Message));
+ }
+
+ }
+
+ // logic for checking XML
+
+ private bool IsLegalXmlCharacter (char c) {
+ if (c < 0x20) {
+ return ( (c == 0x09) || (c == 0x0A) || (c == 0x0D) );
+ } else {
+ if (c < 0xD800) {
+ return(true);
+ } else {
+ return( (c >= 0xE000) && (c <= 0xFFFD) );
+ }
+ }
+ }
+
+ private bool IsLegalXmlText (string text) {
+ foreach (char c in text) {
+ if (!IsLegalXmlCharacter(c)) return (false);
+ }
+ return (true);
+ }
+
+ // the snippet store
+
+ private Dictionary<SnippetIdentifier,List<StoredSnippet>> snippets = new Dictionary<SnippetIdentifier,List<StoredSnippet>>();
+
+ // the actual work of the component
+
+ public override void Apply(XmlDocument document, string key) {
+ XPathNodeIterator nodesIterator = document.CreateNavigator().Select(selector);
+ XPathNavigator[] nodes = BuildComponentUtilities.ConvertNodeIteratorToArray(nodesIterator);
+ foreach (XPathNavigator node in nodes) {
+
+ string reference = node.Value;
+
+ // check for validity of reference
+ if (validSnippetReference.IsMatch(reference)) {
+
+
+ SnippetIdentifier[] identifiers = SnippetIdentifier.ParseReference(reference);
+
+ if (identifiers.Length == 1) {
+ // one snippet referenced
+
+ SnippetIdentifier identifier = identifiers[0];
+ List<StoredSnippet> values;
+ if (snippets.TryGetValue(identifier, out values)) {
+
+ XmlWriter writer = node.InsertAfter();
+ writer.WriteStartElement("snippets");
+ writer.WriteAttributeString("reference", reference);
+
+ foreach (StoredSnippet value in values) {
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", value.Language);
+
+ if (colorization.ContainsKey(value.Language)) {
+ WriteColorizedSnippet(ColorizeSnippet(value.Text, colorization[value.Language]), writer);
+
+ } else {
+ writer.WriteString(value.Text);
+ //writer.WriteString(System.Web.HttpUtility.HtmlDecode(value.Text));
+ }
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ writer.Close();
+
+ } else {
+ WriteMessage(MessageLevel.Warn, String.Format("No snippet with identifier '{0}' was found.", identifier));
+ }
+ } else {
+ // multiple snippets referenced
+
+ // create structure that maps language -> snippets
+ Dictionary<string,List<StoredSnippet>> map = new Dictionary<string,List<StoredSnippet>>();
+ foreach (SnippetIdentifier identifier in identifiers) {
+ List<StoredSnippet> values;
+ if (snippets.TryGetValue(identifier, out values)) {
+ foreach (StoredSnippet value in values) {
+ List<StoredSnippet> pieces;
+ if (!map.TryGetValue(value.Language, out pieces)) {
+ pieces = new List<StoredSnippet>();
+ map.Add(value.Language, pieces);
+ }
+ pieces.Add(value);
+ }
+ }
+ }
+
+ XmlWriter writer = node.InsertAfter();
+ writer.WriteStartElement("snippets");
+ writer.WriteAttributeString("reference", reference);
+
+ foreach (KeyValuePair<string,List<StoredSnippet>> entry in map) {
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", entry.Key);
+
+ List<StoredSnippet> values = entry.Value;
+ for (int i=0; i<values.Count; i++) {
+ if (i>0) writer.WriteString("\n...\n\n\n");
+ writer.WriteString(values[i].Text);
+ // writer.WriteString(System.Web.HttpUtility.HtmlDecode(values[i].Text));
+ }
+
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ writer.Close();
+
+ }
+
+ } else {
+ WriteMessage(MessageLevel.Warn, String.Format("The code reference '{0}' is not well-formed", reference));
+ }
+
+ node.DeleteSelf();
+
+ }
+ }
+
+ private XPathExpression selector;
+
+ private XmlNamespaceManager context = new CustomContext();
+
+ private static Regex validSnippetReference = new Regex(@"^[^#\a\b\f\n\r\t\v]+#(\w+,)*\w+$", RegexOptions.Compiled);
+
+ // colorization logic
+
+ private Dictionary<string,List<ColorizationRule>> colorization = new Dictionary<string,List<ColorizationRule>>();
+
+ private static ICollection<Region> ColorizeSnippet (string text, List<ColorizationRule> rules) {
+
+ // Console.WriteLine("colorizing: '{0}'", text);
+
+ // create a linked list consiting entirely of one uncolored region
+ LinkedList<Region> regions = new LinkedList<Region>();
+ regions.AddFirst( new Region(text) );
+
+ // loop over colorization rules
+ foreach (ColorizationRule rule in rules) {
+
+ // loop over regions
+
+ LinkedListNode<Region> node = regions.First;
+ while(node != null) {
+
+ // only try to colorize uncolored regions
+ if (node.Value.ClassName != null) {
+ node = node.Next;
+ continue;
+ }
+
+ // find matches in the region
+ string regionText = node.Value.Text;
+ Capture[] matches = rule.Apply(regionText);
+
+ // if no matches were found, continue to the next region
+ if (matches.Length == 0) {
+ node = node.Next;
+ continue;
+ }
+
+ // we found matches; break the region into colored and uncolered subregions
+
+ // index is where we are looking from; index-1 is the end of the last match
+ int index = 0;
+
+ LinkedListNode<Region> referenceNode = node;
+
+ foreach (Capture match in matches) {
+
+ // create a leading uncolored region
+ if (match.Index > index) {
+ //Console.WriteLine("uncolored: {0} '{1}' -> {2} '{3}'", index, regionText[index], match.Index - 1, regionText[match.Index - 1]);
+ Region uncoloredRegion = new Region(regionText.Substring(index, match.Index-index));
+ referenceNode = regions.AddAfter(referenceNode, uncoloredRegion);
+ }
+
+ // create a colored region
+ // Console.WriteLine("name = {0}", rule.ClassName);
+ //Console.WriteLine("colored: {0} '{1}' -> {2} '{3}'", match.Index, regionText[match.Index], match.Index + match.Length - 1, regionText[match.Index + match.Length - 1]);
+ Region coloredRegion = new Region(rule.ClassName, regionText.Substring(match.Index, match.Length));
+ referenceNode = regions.AddAfter(referenceNode, coloredRegion);
+
+ index = match.Index + match.Length;
+
+ }
+
+ // create a trailing uncolored region
+ if (index < regionText.Length) {
+ Region uncoloredRegion = new Region(regionText.Substring(index));
+ referenceNode = regions.AddAfter(referenceNode, uncoloredRegion);
+ }
+
+ // remove the original node
+ regions.Remove(node);
+
+ node = referenceNode.Next;
+ }
+
+
+ }
+ return(regions);
+
+ }
+
+ private static void WriteColorizedSnippet (ICollection<Region> regions, XmlWriter writer) {
+ foreach (Region region in regions) {
+ // Console.WriteLine("writing {0}", region.ClassName);
+ if (region.ClassName == null) {
+ writer.WriteString(region.Text);
+ } else {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", region.ClassName);
+ writer.WriteString(region.Text);
+ writer.WriteEndElement();
+ }
+ }
+ }
+
+ private static string StripLeadingSpaces (string text) {
+
+ if (text == null) throw new ArgumentNullException("text");
+
+ // Console.WriteLine("BEFORE:");
+ // Console.WriteLine(text);
+
+ // split the text into lines
+ string[] lines = text.Split('\n');
+
+ // no need to do this if there is only one line
+ if (lines.Length == 1) return(lines[0]);
+
+ // figure out how many leading spaces to delete
+ int spaces = Int32.MaxValue;
+ for (int i=0; i<lines.Length; i++) {
+
+ string line = lines[i];
+
+ // skip empty lines
+ if (line.Length == 0) continue;
+
+ // determine the number of leading spaces
+ int index = 0;
+ while (index < line.Length) {
+ if (line[index] != ' ') break;
+ index++;
+ }
+
+ if (index == line.Length) {
+ // lines that are all spaces should just be treated as empty
+ lines[i] = String.Empty;
+ } else {
+ // otherwise, keep track of the minimum number of leading spaces
+ if (index < spaces) spaces = index;
+ }
+
+ }
+
+ // Console.WriteLine("SPACES = {0}", spaces);
+
+ // re-form the string with leading spaces deleted
+ StringBuilder result = new StringBuilder();
+ foreach (string line in lines) {
+ if (line.Length == 0) {
+ result.AppendLine();
+ } else {
+ result.AppendLine(line.Substring(spaces));
+ }
+ }
+ // Console.WriteLine("AFTER:");
+ // Console.WriteLine(result.ToString());
+ return(result.ToString());
+
+ }
+
+ }
+
+ internal struct SnippetIdentifier {
+
+ public SnippetIdentifier (string exampleId, string snippetId) {
+ this.exampleId = exampleId.ToLower();
+ this.snippetId = snippetId.ToLower();
+ }
+
+ public SnippetIdentifier (string identifier) {
+ int index = identifier.LastIndexOf('#');
+ exampleId = identifier.Substring(0,index).ToLower();
+ snippetId = identifier.Substring(index+1).ToLower();
+ }
+
+ private string exampleId;
+
+ private string snippetId;
+
+ public string Example {
+ get {
+ return(exampleId);
+ }
+ }
+
+ public string Snippet {
+ get {
+ return(snippetId);
+ }
+ }
+
+ public override string ToString() {
+ return(String.Format("{0}#{1}", exampleId, snippetId));
+ }
+
+ public static SnippetIdentifier[] ParseReference (string reference) {
+
+ int index = reference.IndexOf('#');
+ if (index < 0) return(new SnippetIdentifier[0]);
+
+ string example = reference.Substring(0,index);
+ string[] snippets = reference.Substring(index+1).Split(',');
+
+ SnippetIdentifier[] identifiers = new SnippetIdentifier[snippets.Length];
+ for (int i=0; i<snippets.Length; i++) {
+ identifiers[i] = new SnippetIdentifier(example, snippets[i]);
+ }
+ return(identifiers);
+
+ }
+
+ }
+
+ internal class StoredSnippet {
+
+ public StoredSnippet (string text, string language) {
+ this.text = text;
+ this.language = language;
+ }
+
+ private string text;
+
+ private string language;
+
+ public string Text {
+ get {
+ return(text);
+ }
+ }
+
+ public string Language {
+ get {
+ return(language);
+ }
+ }
+ }
+
+ internal class ColorizationRule {
+
+ public ColorizationRule (string pattern, string className) : this(pattern, null, className) {}
+
+ public ColorizationRule (string pattern, string region, string className) {
+ this.pattern = new Regex(pattern, RegexOptions.Compiled|RegexOptions.Multiline);
+ this.region = region;
+ this.className = className;
+ }
+
+ private Regex pattern;
+
+ private string region;
+
+ private string className;
+
+ public string ClassName {
+ get {
+ return(className);
+ }
+ }
+
+ public Capture[] Apply (string text) {
+
+ MatchCollection matches = pattern.Matches(text);
+ Capture[] captures = new Capture[matches.Count];
+
+ if (region == null) {
+ matches.CopyTo(captures, 0);
+ return(captures);
+ } else {
+ for (int i=0; i<captures.Length; i++) {
+ captures[i] = matches[i].Groups[region];
+ }
+ return(captures);
+ }
+
+ }
+
+ }
+
+ internal struct Region {
+
+ public Region (string text) : this(null, text) {}
+
+ public Region (string className, string text) {
+ this.className = className;
+ this.text = text;
+ }
+
+ private string className;
+
+ private string text;
+
+
+ public string ClassName {
+ get {
+ return(className);
+ }
+ }
+
+ public string Text {
+ get {
+ return(text);
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ForEachComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ForEachComponent.cs
new file mode 100644
index 0000000..06705e8
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ForEachComponent.cs
@@ -0,0 +1,105 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class ForEachComponent : BuildComponent {
+
+ public ForEachComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // set up the context
+ XPathNodeIterator context_nodes = configuration.Select("context");
+ foreach (XPathNavigator context_node in context_nodes)
+ {
+ string prefix = context_node.GetAttribute("prefix", String.Empty);
+ string name = context_node.GetAttribute("name", String.Empty);
+ context.AddNamespace(prefix, name);
+ }
+
+ // load the expression format
+ XPathNavigator variable_node = configuration.SelectSingleNode("variable");
+ if (variable_node == null) throw new ConfigurationErrorsException("When instantiating a ForEach component, you must specify a variable using the <variable> element.");
+ string xpath_format = variable_node.GetAttribute("expression", String.Empty);
+ if ((xpath_format == null) || (xpath_format.Length == 0)) throw new ConfigurationErrorsException("When instantiating a ForEach component, you must specify a variable expression using the expression attribute");
+ xpath = XPathExpression.Compile(xpath_format);
+
+ // load the subcomponents
+ WriteMessage(MessageLevel.Info, "Loading subcomponents.");
+ XPathNavigator components_node = configuration.SelectSingleNode("components");
+ if (components_node == null) throw new ConfigurationErrorsException("When instantiating a ForEach component, you must specify subcomponents using the <components> element.");
+
+ components = BuildAssembler.LoadComponents(components_node);
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} subcomponents.", components.Count));
+
+ }
+
+ // the format string for the variable expression
+ private XPathExpression xpath;
+
+ // the xpath context
+ private CustomContext context = new CustomContext();
+
+ // the subcomponents
+ private ICollection<BuildComponent> components;
+
+ // the work of the component
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // adjust the context
+ context["key"] = key;
+
+ // evaluate the condition
+ XPathExpression xpath_local = xpath.Clone();
+ xpath_local.SetContext(context);
+
+ Object result = document.CreateNavigator().Evaluate(xpath_local);
+
+ // try to intrepret the result as a node set
+ XPathNodeIterator result_node_iterator = result as XPathNodeIterator;
+
+ if (result_node_iterator != null) {
+ XPathNavigator[] result_nodes = BuildComponentUtilities.ConvertNodeIteratorToArray(result_node_iterator);
+ //Console.WriteLine("{0} node-set result", result_nodes.Length);
+ // if it is, apply the child components to each node value
+ foreach (XPathNavigator result_node in result_nodes) {
+ // Console.WriteLine(result_node.Value);
+ ApplyComponents(document, result_node.Value);
+ }
+ } else {
+ //Console.WriteLine("non-node-set result");
+ // if it isn't, apply the child components to the string value of the result
+ ApplyComponents(document, result.ToString());
+
+ }
+
+
+ }
+
+ private void ApplyComponents (XmlDocument document, string key) {
+ foreach (BuildComponent component in components) {
+ component.Apply(document, key);
+ }
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (BuildComponent component in components) {
+ component.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/GlobalSuppressions.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/GlobalSuppressions.cs
new file mode 100644
index 0000000..3fd693e
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/GlobalSuppressions.cs
@@ -0,0 +1,319 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "BuildComponents.ArrayTypeReference.#Create(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "apidata", Scope = "member", Target = "BuildComponents.NamespaceTarget.#Create(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "BuildComponents.Reference.#referenceApiExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Refered", Scope = "member", Target = "BuildComponents.ReferenceTypeReference.#ReferedToType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "BuildComponents.SimpleMemberReference.#.ctor(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "BuildComponents.Target.#apiNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "BuildComponents.TemplateTypeReference.#.ctor(BuildComponents.ISimpleReference,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "BuildComponents.TemplateTypeReference.#.ctor(System.String,System.Int32)")]
+
+// TODO: revisit
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "BuildComponents.TemplateTypeReference.#.ctor(System.String,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "templateId", Scope = "member", Target = "BuildComponents.TemplateTypeReference.#.ctor(System.String,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "BuildComponents.TemplateTypeReference.#position")]
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "BuildComponents.TypeReference.#Create(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "BuildComponents.TypeReference.#Create(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "BuildComponents.TypeTarget.#containingAssembly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "BuildComponents.TypeTarget.#containingNamespace")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "BuildComponents.TypeTarget.#containingType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "BuildComponents.TypeTarget.#subgroup")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ArtTarget.#Id")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "ddue", Scope = "member", Target = "Microsoft.Ddue.Tools.CodeReference.#.ctor(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "member", Target = "Microsoft.Ddue.Tools.CodeReference.#DdueCodeReference")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.Ddue.Tools.CodeReference.#Type")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ConceptualLinkInfo.#.ctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.ConceptualLinkInfo.#ShowText")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ConstructorTarget.#Parameters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.CopyComponent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "configuration", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyComponent.#.ctor(System.Xml.XPath.XPathNavigator,System.Collections.Generic.Dictionary`2<System.String,System.Object>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "data", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyComponent.#.ctor(System.Xml.XPath.XPathNavigator,System.Collections.Generic.Dictionary`2<System.String,System.Object>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XmlNode", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromFileComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromFilesComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopyFromIndexComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.CopySet.#.ctor(Microsoft.Ddue.Tools.IndexedFileCache,System.String,System.String,System.Xml.XmlNamespaceManager)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.CopySet.#FileCache")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.CopySet.#GetTargetExpression(System.Xml.XPath.XPathNavigator,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.DisplayComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#IsLegalXmlCharacter(System.Char)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#LoadContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ExampleComponent.#LoadContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "hxf", Scope = "member", Target = "Microsoft.Ddue.Tools.FileCreatedEventArgs.#.ctor(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hxf", Scope = "member", Target = "Microsoft.Ddue.Tools.FileCreatedEventArgs.#HxfPath")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ForEachComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hxf", Scope = "type", Target = "Microsoft.Ddue.Tools.HxfGeneratorComponent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.HxfGeneratorComponent.#WriteFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.InclusionFilter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#apiNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#apiParameterNodesExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#apiParameterTemplateNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#apiParameterTypeNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#sourceFiles")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.InclusionFilter.#sourceFiles")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedDocument.#.ctor(Microsoft.Ddue.Tools.IndexedDocumentCache,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedDocumentCache.#.ctor(Microsoft.Ddue.Tools.CopyFromIndexComponent,System.String,System.String,System.Xml.XmlNamespaceManager,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedDocumentCache.#AddDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedFile.#.ctor(System.String,System.Xml.XPath.XPathExpression,System.Xml.XPath.XPathExpression)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedFile.#GetContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedFile.#ListNode")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedFile.#ListNode")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Scope = "type", Target = "Microsoft.Ddue.Tools.IndexedFileCache")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ReferenceLinkInfo2.#Create(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#AddTargets(System.String,System.String,System.String,System.Xml.XPath.XPathExpression,System.String,System.Xml.XPath.XPathExpression,System.Xml.XPath.XPathExpression)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#ResolveConceptualLinks(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#LoadContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#ResolveContent(System.Xml.XmlDocument,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetIdentifier.#.ctor(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetIdentifier.#.ctor(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberFilter.#AddMemberNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberFilter.#.ctor(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.NamespaceFilter.#AddNamespaceNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.NamespaceFilter.#.ctor(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.OverloadFilter.#.ctor(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.SaveComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TransformComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TypeFilter.#AddTypeNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TypeFilter.#.ctor(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.VersionFilter.#AddPlatformNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#CreateTypeReference(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#CreateTypeReference(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteArrayType(Microsoft.Ddue.Tools.ArrayTypeReference,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter,System.Collections.Generic.Dictionary`2<Microsoft.Ddue.Tools.IndexedTemplateTypeReference,Microsoft.Ddue.Tools.TypeReference>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#ReadInputFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#ReadInputFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#GetTypeTemplateName(Microsoft.Ddue.Tools.SimpleTypeReference,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#LoadApprovedFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.PlatformsComponent.#ParseDocuments(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#BrokenLinkDisplayText(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#ResolveConceptualLinks(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#LoadContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#ParseDocuments(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#CreateSpecializedTypeReference(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#FindMatchingEndBracket(System.String,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ValidateComponent.#LogValidationError(System.Object,System.Xml.Schema.ValidationEventArgs)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent+TargetSet.#Lookup(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#CreateEnumerationTarget(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.LinkType2)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#CreateTarget(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.LinkType2)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#CreateTypeReference(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#ReadInputFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#ReadInputFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#LoadApprovedFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MsdnResolver.#GetMsdnUrl(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.PlatformsComponent.#ParseDocuments(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#AddTargets(System.String,System.String,System.String,System.Xml.XPath.XPathExpression,System.String,System.Xml.XPath.XPathExpression,System.Xml.XPath.XPathExpression)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#CompileXPathExpression(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#AddTargets(System.String,Microsoft.Ddue.Tools.LinkType2)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SaveComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#GetContent(System.String,System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#LoadContent(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#ParseDocuments(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#ResolveContent(System.Xml.XmlDocument,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetIdentifier.#ToString()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#FindMatchingEndBracket(System.String,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TransformComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#CompileXPathExpression(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#ParseDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#CreateMemberReference(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#GetContent(System.String,System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.TransformComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.IndexOf(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#CopyContent(System.Xml.XmlReader,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#CopyContent(System.Xml.XmlReader,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ReferenceLinkInfo2.#Create(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String,System.Boolean)", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#CreateTypeReference(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.IndexOf(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param", Scope = "member", Target = "Microsoft.Ddue.Tools.OverloadFilter.#ParamNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param", Scope = "member", Target = "Microsoft.Ddue.Tools.OverloadFilter.#ParamTypes")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Refered", Scope = "member", Target = "Microsoft.Ddue.Tools.ReferenceTypeReference.#ReferedToType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Wdx", Scope = "type", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "dict", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#AddValueToListDictionary`2(System.Collections.Generic.Dictionary`2<!!0,System.Collections.Generic.List`1<!!1>>,!!0,!!1)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "cer", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#SetGenericContext(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "xpath", Scope = "member", Target = "Microsoft.Ddue.Tools.WdxResolveConceptualLinksComponent.#CompileXPathExpression(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "K", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#AddValueToListDictionary`2(System.Collections.Generic.Dictionary`2<!!0,System.Collections.Generic.List`1<!!1>>,!!0,!!1)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "V", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#AddValueToListDictionary`2(System.Collections.Generic.Dictionary`2<!!0,System.Collections.Generic.List`1<!!1>>,!!0,!!1)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.TargetCollection")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1715:IdentifiersShouldHaveCorrectPrefix", MessageId = "T", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#AddValueToListDictionary`2(System.Collections.Generic.Dictionary`2<!!0,System.Collections.Generic.List`1<!!1>>,!!0,!!1)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberTarget.#Type")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.Ddue.Tools.Parameter.#Type")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveArtLinksComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "configuration", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGenerator.#.ctor(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "key", Scope = "member", Target = "Microsoft.Ddue.Tools.NamespaceFilter.#IsIncludedType(System.Xml.XPath.XPathNavigator,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "location", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxWriter.#.ctor(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "options", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteInvalid(Microsoft.Ddue.Tools.InvalidReference,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "options", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteNamespaceTarget(Microsoft.Ddue.Tools.NamespaceTarget,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "options", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteProcedureName(Microsoft.Ddue.Tools.ProcedureTarget,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "options", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#WriteNamespaceReference(Microsoft.Ddue.Tools.NamespaceReference,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "key", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#ResolveConceptualLinks(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetIdentifier.#Example")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetIdentifier.#Snippet")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#CopyContent(System.Xml.XmlReader,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent.#namespaceAssemblyExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.IntellisenseComponent2.#CopyContent(System.Xml.XmlReader,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.LiveExampleComponent.#LoadApprovedFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings", Scope = "member", Target = "Microsoft.Ddue.Tools.MsdnResolver.#GetMsdnUrl(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.PlatformsComponent.#AddPlatformVersionFilter(System.String,System.String,System.Xml.XPath.XPathNavigator,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.PlatformsComponent.#ParseDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteNamespaceTarget(Microsoft.Ddue.Tools.NamespaceTarget,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteTemplateType(Microsoft.Ddue.Tools.TemplateTypeReference,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedSyntaxWriter.#.ctor(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.MethodTarget.#Parameters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.MethodTarget.#Templates")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.MethodTemplateTypeReference.#.ctor(Microsoft.Ddue.Tools.MemberReference,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Scope = "type", Target = "Microsoft.Ddue.Tools.MsdnResolver")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ProcedureTarget.#.ctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.PropertyTarget.#Parameters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ReferenceLinkInfo2.#.ctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "filesValue", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveConceptualLinksComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.ResolveReferenceLinksComponent2.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.SaveComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "doctype", Scope = "member", Target = "Microsoft.Ddue.Tools.SaveComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "item_expression", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "path_expresion", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#DetectLoops()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#DetectLoops()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "content", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentComponent.#ResolveContent(System.Xml.XmlDocument,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentElement.#.ctor(System.String,System.String,System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.SharedContentElement.#IsAttribute")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.Specialization.#Arguments")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.SpecializedMemberWithParametersReference.#ParameterTypes")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope = "member", Target = "Microsoft.Ddue.Tools.SpecializedTypeReference.#GetSpecializationDictionary()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.SpecializedTypeReference.#Specializations")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#.ctor(System.String,Microsoft.Ddue.Tools.LinkType)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#Directory")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#GetTargetInfo(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#LinkType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#TextExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectory.#UrlExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TargetDirectoryCollection.#GetTargetInfo(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.CustomContext)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#AddValueToListDictionary`2(System.Collections.Generic.Dictionary`2<!!0,System.Collections.Generic.List`1<!!1>>,!!0,!!1)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#GetDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#ParseDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.TaskGrabberComponent.#xpathFromConfig")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.Test")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "baseTypePattern", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#CreateReference(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#genericMemberContext")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#tr")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.TextReferenceUtilities.#ValidTest")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.TypeTarget.#Templates")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.TypeTemplateTypeReference.#.ctor(Microsoft.Ddue.Tools.SimpleTypeReference,System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#apiSubsubgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#topicGroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.MethodTarget.#returnType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.PropertyTarget.#returnType")]
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodReference.#Parameters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodReference.#TemplateArgs")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.HxfGeneratorComponent.#FileCreatedHandler(System.Object,System.EventArgs)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedExample.#isApprovedUnit(System.IO.DirectoryInfo)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedExample.#IsLegalXmlCharacter(System.Char)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedExample.#ParseFile(System.IO.FileInfo,System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.IndexedExample.#ParseUnit(System.IO.DirectoryInfo)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Language.#Extension")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "extension", Scope = "member", Target = "Microsoft.Ddue.Tools.Language.#IsMatch(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "languageId", Scope = "member", Target = "Microsoft.Ddue.Tools.Language.#IsMatch(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "parameters", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteExtensionMethod(Microsoft.Ddue.Tools.ExtensionMethodReference,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteMemberTarget(Microsoft.Ddue.Tools.MemberTarget,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter,System.Collections.Generic.Dictionary`2<Microsoft.Ddue.Tools.IndexedTemplateTypeReference,Microsoft.Ddue.Tools.TypeReference>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteNamespaceTarget(Microsoft.Ddue.Tools.NamespaceTarget,Microsoft.Ddue.Tools.DisplayOptions,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "overloadId", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberFilter.#AddMemberNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "paramNames", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberFilter.#AddMemberNode(System.Xml.XmlReader,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "key", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberFilter.#IsIncludedMember(System.Xml.XPath.XPathNavigator,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.MethodTarget.#TemplateArgs")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#.ctor(Microsoft.Ddue.Tools.BuildAssembler,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#Apply(System.Xml.XmlDocument,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#loadExamples(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#loadExamples(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#parseApprovalLogFiles(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#parseApprovalLogFiles(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#parseApprovalLogFiles(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "identifier", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#writeSnippetContent(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SnippetIdentifier,System.Collections.Generic.List`1<Microsoft.Ddue.Tools.Snippet>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#writeSnippetContent(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SnippetIdentifier,System.Collections.Generic.List`1<Microsoft.Ddue.Tools.Snippet>)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.SnippetComponent.#WriteSnippetText(Microsoft.Ddue.Tools.Snippet,System.Xml.XmlWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1708:IdentifiersShouldDifferByMoreThanCase", Scope = "type", Target = "Microsoft.Ddue.Tools.Specialization")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.Specialization.#arguments")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Microsoft.Ddue.Tools.XmlTargetCollectionUtilities.#CreateTypeReference(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.LinkTextResolver.#WriteConversionOperator(Microsoft.Ddue.Tools.ProcedureTarget,System.Xml.XmlWriter)")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/HxfGeneratorComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/HxfGeneratorComponent.cs
new file mode 100644
index 0000000..176ce97
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/HxfGeneratorComponent.cs
@@ -0,0 +1,132 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class FileCreatedEventArgs : EventArgs {
+
+ private string filePath;
+ private string hxfPath;
+
+ public FileCreatedEventArgs(string filePath, string hxfPath) {
+ this.filePath = filePath;
+ this.hxfPath = hxfPath;
+ }
+
+ public string FilePath {
+ get {
+ return(filePath);
+ }
+ }
+
+ public string HxfPath {
+ get {
+ return (hxfPath);
+ }
+ }
+
+ }
+
+ public class HxfGeneratorComponent : BuildComponent {
+
+ public HxfGeneratorComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // get configuration data
+ inputValue = configuration.GetAttribute("input", String.Empty);
+ if (!String.IsNullOrEmpty(inputValue)) inputValue = Environment.ExpandEnvironmentVariables(inputValue);
+ outputValue = configuration.GetAttribute("output", String.Empty);
+ if (!String.IsNullOrEmpty(outputValue)) outputValue = Environment.ExpandEnvironmentVariables(outputValue);
+
+ // subscribe to component events
+ assembler.ComponentEvent += new EventHandler(FileCreatedHandler);
+ }
+
+ private string inputValue;
+
+ private string outputValue;
+
+ private XmlWriter writer;
+
+ private Dictionary<string, XmlWriter> writers = new Dictionary<string, XmlWriter>();
+
+ private void FileCreatedHandler (Object o, EventArgs e) {
+ FileCreatedEventArgs fe = e as FileCreatedEventArgs;
+ if (fe == null) return;
+
+ string path = Path.Combine(fe.HxfPath, outputValue).ToLower();
+
+ XmlWriter tempWriter;
+ if (!writers.TryGetValue(path, out tempWriter)) {
+ if (writer != null) {
+ writer.WriteEndDocument();
+ writer.Close();
+ }
+ WriteFile(path);
+ }
+
+ WriteFileElement(fe.FilePath);
+
+ }
+
+ private void WriteFileElement (string url) {
+ writer.WriteStartElement("File");
+ writer.WriteAttributeString("Url", url);
+ writer.WriteEndElement();
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ writer.WriteEndDocument();
+ writer.Close();
+ }
+ base.Dispose(disposing);
+ }
+
+ public void WriteFile(string path) {
+ XmlWriterSettings writerSettings = new XmlWriterSettings();
+ writerSettings.Indent = true;
+ writer = XmlWriter.Create(path);
+ writer.WriteStartDocument();
+ writer.WriteStartElement("HelpFileList");
+ writer.WriteAttributeString("DTDVersion", "1.0");
+
+ // use the input to seed the output
+ if (!String.IsNullOrEmpty(inputValue)) {
+
+ try {
+ TextReader reader = File.OpenText(inputValue);
+
+ try {
+ while (true) {
+ string line = reader.ReadLine();
+ if (line == null) break;
+ WriteFileElement(line);
+ }
+ }
+ finally {
+ reader.Close();
+ }
+ }
+ catch (IOException ex) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to copy the input HxF data. The error message is:", ex.Message));
+ }
+ }
+
+ writers.Add(path, writer);
+ }
+
+ // don't do anything for individual files
+ public override void Apply (XmlDocument document, string key) {}
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IfThenComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IfThenComponent.cs
new file mode 100644
index 0000000..e44c0f2
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IfThenComponent.cs
@@ -0,0 +1,87 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+using System.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class IfThenComponent : BuildComponent {
+
+ private XPathExpression condition;
+
+ private IEnumerable<BuildComponent> true_branch = new List<BuildComponent>();
+
+ private IEnumerable<BuildComponent> false_branch = new List<BuildComponent>();
+
+ public IfThenComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // get the condition
+ XPathNavigator if_node = configuration.SelectSingleNode("if");
+ if (if_node == null) throw new ConfigurationErrorsException("You must specify a condition using the <if> element.");
+ string condition_xpath = if_node.GetAttribute("condition", String.Empty);
+ if (String.IsNullOrEmpty(condition_xpath)) throw new ConfigurationErrorsException();
+ condition = XPathExpression.Compile(condition_xpath);
+
+ // construct the true branch
+ XPathNavigator then_node = configuration.SelectSingleNode("then");
+ if (then_node != null) true_branch = BuildAssembler.LoadComponents(then_node);
+
+ // construct the false branch
+ XPathNavigator else_node = configuration.SelectSingleNode("else");
+ if (else_node != null) false_branch = BuildAssembler.LoadComponents(else_node);
+
+ // keep a pointer to the context for future use
+ context = assembler.Context;
+
+ }
+
+ private BuildContext context;
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // set up the test
+ context["key"] = key;
+ XPathExpression test = condition.Clone();
+ test.SetContext(context.XsltContext);
+
+ // evaluate the condition
+ bool result = (bool) document.CreateNavigator().Evaluate(test);
+
+ // on the basis of the condition, execute either the true or the false branch
+ if (result) {
+ foreach (BuildComponent component in true_branch) {
+ component.Apply(document, key);
+ }
+ } else {
+ foreach (BuildComponent component in false_branch) {
+ component.Apply(document, key);
+ }
+ }
+
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (BuildComponent component in true_branch) {
+ component.Dispose();
+ }
+ foreach (BuildComponent component in false_branch) {
+ component.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ }
+
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IndexedFileCache.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IndexedFileCache.cs
new file mode 100644
index 0000000..3fadba3
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IndexedFileCache.cs
@@ -0,0 +1,192 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools
+{
+ // the storage system
+
+ internal class IndexedFileCache
+ {
+
+ public IndexedFileCache(string keyXPath, string valueXPath, int cacheSize)
+ {
+ valueExpression = XPathExpression.Compile(valueXPath);
+
+ keyExpression = XPathExpression.Compile(keyXPath);
+
+ _cacheSize = cacheSize;
+
+ cache = new Dictionary<string, IndexedFile>(_cacheSize);
+
+ lruLinkedList = new LinkedList<string>();
+ }
+
+ // search pattern for value nodes to be mapped
+ private XPathExpression valueExpression;
+
+ // search pattern for the key identifier (relative to the value node)
+ private XPathExpression keyExpression;
+
+ // an index mapping topic IDs to files
+ private Dictionary<string, string> idToFileMap = new Dictionary<string, string>();
+
+ public int ParseDocuments(string wildcardPath)
+ {
+ string directoryPart = Path.GetDirectoryName(wildcardPath);
+ if (String.IsNullOrEmpty(directoryPart)) directoryPart = Environment.CurrentDirectory;
+ directoryPart = Path.GetFullPath(directoryPart);
+ string filePart = Path.GetFileName(wildcardPath);
+ string[] files = Directory.GetFiles(directoryPart, filePart);
+ // WriteMessage(MessageLevel.Info, String.Format("Found {0} files.", files.Length) );
+ foreach (string file in files)
+ {
+ ParseDocument(file);
+ }
+ return (files.Length);
+ }
+
+ private void ParseDocument(string file)
+ {
+ try
+ {
+ XPathDocument document = new XPathDocument(file);
+ XPathNodeIterator valueNodes = document.CreateNavigator().Select(valueExpression);
+ foreach (XPathNavigator valueNode in valueNodes)
+ {
+ XPathNavigator keyNode = valueNode.SelectSingleNode(keyExpression);
+ if (keyNode == null) continue;
+ string key = keyNode.Value;
+
+ // log multiple occurences of a single id
+ if (idToFileMap.ContainsKey(key))
+ {
+ // WriteMessage(MessageLevel.Warn, String.Format("Entries for the key '{0}' occur in both '{1}' and '{2}'. The first entry will be used.", key, idToFileMap[key], file));
+ }
+ else
+ {
+ idToFileMap[key] = file;
+ }
+ }
+ }
+ catch (XmlException)
+ {
+ // WriteMessage(MessageLevel.Error, e.Message);
+ }
+ }
+
+ // a simple document caching mechanism
+
+ private int _cacheSize = 10;
+
+ private LinkedList<String> lruLinkedList;
+
+ private Dictionary<string, IndexedFile> cache;
+
+
+ private IndexedFile GetCachedDocument(string identifier)
+ {
+ string file;
+ if (idToFileMap.TryGetValue(identifier, out file))
+ {
+ IndexedFile document;
+ if (cache.TryGetValue(file, out document))
+ {
+ // move the file from its current position to the head of the lru linked list
+ lruLinkedList.Remove(document.ListNode);
+ lruLinkedList.AddFirst(document.ListNode);
+ }
+ else
+ {
+ // not in the cache, so load and index a new source file
+ document = new IndexedFile(file, valueExpression, keyExpression);
+ if (cache.Count >= _cacheSize)
+ {
+ // the cache is full
+ // the last node in the linked list has the path of the next file to remove from the cache
+ if (lruLinkedList.Last != null)
+ {
+ cache.Remove(lruLinkedList.Last.Value);
+ lruLinkedList.RemoveLast();
+ }
+ }
+ // add the new file to the cache and to the head of the lru linked list
+ cache.Add(file, document);
+ document.ListNode = lruLinkedList.AddFirst(file);
+ }
+ return (document);
+ }
+ else
+ {
+ return (null);
+ }
+ }
+
+ public XPathNavigator GetContent(string identifier)
+ {
+
+ // get the document containing the identifier
+ IndexedFile document = GetCachedDocument(identifier);
+ if (document == null) return (null);
+
+ // select the comment part of the document
+ return document.GetContent(identifier);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return (idToFileMap.Count);
+ }
+ }
+
+ }
+
+ internal class IndexedFile
+ {
+ Dictionary<string, XPathNavigator> valueIndex = new Dictionary<string, XPathNavigator>();
+
+ public IndexedFile(string filepath, XPathExpression valueExpression, XPathExpression keyExpression)
+ {
+ XPathDocument xpDoc = new XPathDocument(filepath);
+ XPathNodeIterator valueNodes = xpDoc.CreateNavigator().Select(valueExpression);
+ foreach (XPathNavigator valueNode in valueNodes)
+ {
+ XPathNavigator keyNode = valueNode.SelectSingleNode(keyExpression);
+ if (keyNode == null)
+ continue;
+ string key = keyNode.Value;
+ if (!valueIndex.ContainsKey(key))
+ valueIndex.Add(key, valueNode);
+ }
+ }
+
+ public XPathNavigator GetContent(string key)
+ {
+ return valueIndex[key];
+ }
+
+ private LinkedListNode<string> listNode;
+ public LinkedListNode<string> ListNode
+ {
+ get
+ {
+ return (listNode);
+ }
+ set
+ {
+ listNode = value;
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent.cs
new file mode 100644
index 0000000..1fd72a8
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent.cs
@@ -0,0 +1,338 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class IntellisenseComponent : BuildComponent {
+
+ public IntellisenseComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNavigator output_node = configuration.SelectSingleNode("output");
+ if (output_node != null) {
+
+ string directory_value = output_node.GetAttribute("directory", String.Empty);
+ if (!String.IsNullOrEmpty(directory_value)) {
+ directory = Environment.ExpandEnvironmentVariables(directory_value);
+ if (!Directory.Exists(directory)) WriteMessage(MessageLevel.Error, String.Format("The output directory '{0}' does not exist.", directory));
+ }
+ }
+
+ // a way to get additional information into the intellisense file
+ XPathNodeIterator input_nodes = configuration.Select("input");
+ foreach (XPathNavigator input_node in input_nodes) {
+ string file_value = input_node.GetAttribute("file", String.Empty);
+ if (!String.IsNullOrEmpty(file_value)) {
+ string file = Environment.ExpandEnvironmentVariables(file_value);
+ ReadInputFile(file);
+ }
+ }
+
+ context.AddNamespace("ddue", "http://ddue.schemas.microsoft.com/authoring/2003/5");
+
+ summaryExpression.SetContext(context);
+ memberSummaryExpression.SetContext(context);
+ returnsExpression.SetContext(context);
+ parametersExpression.SetContext(context);
+ parameterNameExpression.SetContext(context);
+ templatesExpression.SetContext(context);
+ templateNameExpression.SetContext(context);
+ exceptionExpression.SetContext(context);
+ exceptionCrefExpression.SetContext(context);
+ }
+
+ // input content store
+
+ private void ReadInputFile (string file) {
+ try {
+ XPathDocument document = new XPathDocument(file);
+
+ XPathNodeIterator member_nodes = document.CreateNavigator().Select("/metadata/topic[@id]");
+ foreach (XPathNavigator member_node in member_nodes) {
+ string id = member_node.GetAttribute("id", String.Empty);
+ content[id] = member_node.Clone();
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Read {0} input content nodes.", member_nodes.Count));
+
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The input file '{0}' is not a well-formed XML file. The error message is: {1}", file, e.Message));
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to access the fileThe input file '{0}'. The error message is: {1}", file, e.Message));
+ }
+
+
+ }
+ private Dictionary<string, XPathNavigator> content = new Dictionary<string, XPathNavigator>();
+
+ // the action of the component
+
+ public override void Apply (XmlDocument document, string id) {
+
+ // only generate intellisense if id corresponds to an allowed intellisense ID
+ if (id.Length < 2) return;
+ if (id[1] != ':') return;
+ if (!((id[0] == 'T') || (id[0] == 'M') || (id[0] == 'P') || (id[0] == 'F') || (id[0] == 'E') || (id[0] == 'N'))) return;
+
+ XPathNavigator root = document.CreateNavigator().SelectSingleNode("/document/comments");
+
+ string assembly;
+
+ if ((string)root.Evaluate(groupExpression) == "namespace") {
+ // get the assembly for the namespace
+ //assembly = (string) root.Evaluate(namespaceAssemblyExpression);
+ // Assign general name for namespace assemblies since they do not belong to any specific assembly
+ assembly = "namespaces";
+ } else {
+ // get the assembly for the API
+ assembly = (string) root.Evaluate(assemblyExpression);
+ }
+
+ if (String.IsNullOrEmpty(assembly)) return;
+
+ // try/catch block for capturing errors
+ try {
+
+ // get the writer for the assembly
+ XmlWriter writer;
+ if (!writers.TryGetValue(assembly, out writer)) {
+
+ // create a writer for the assembly
+ string name = Path.Combine(directory, assembly + ".xml");
+ // Console.WriteLine("creating {0}", name);
+
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+
+ try {
+ writer = XmlWriter.Create(name, settings);
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to create the intellisense output file '{0}'. The error message is: {1}", name, e.Message));
+ }
+
+
+ writers.Add(assembly, writer);
+
+ // write out the initial data
+ writer.WriteStartDocument();
+ writer.WriteStartElement("doc");
+ //do not generate assembly nodes for namespace topics
+ if ((string)root.Evaluate(groupExpression) != "namespace")
+ {
+ writer.WriteStartElement("assembly");
+ writer.WriteElementString("name", assembly);
+ writer.WriteEndElement();
+ }
+ writer.WriteStartElement("members");
+ }
+
+ writer.WriteStartElement("member");
+ writer.WriteAttributeString("name", id);
+
+ // summary
+ WriteSummary(root, summaryExpression, writer);
+
+ // return value
+ XPathNavigator returns = root.SelectSingleNode(returnsExpression);
+ if (returns != null) {
+ writer.WriteStartElement("returns");
+
+ XmlReader reader = returns.ReadSubtree();
+ CopyContent(reader, writer);
+ reader.Close();
+
+ writer.WriteEndElement();
+ }
+
+ // parameters
+ XPathNodeIterator parameters = root.Select(parametersExpression);
+ foreach (XPathNavigator parameter in parameters) {
+
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+
+ XmlReader reader = parameter.ReadSubtree();
+
+ writer.WriteStartElement("param");
+ writer.WriteAttributeString("name", name);
+ CopyContent(reader, writer);
+ writer.WriteEndElement();
+
+ reader.Close();
+ }
+
+ // templates
+ XPathNodeIterator templates = root.Select(templatesExpression);
+ foreach (XPathNavigator template in templates) {
+
+ string name = (string)template.Evaluate(templateNameExpression);
+
+ XmlReader reader = template.ReadSubtree();
+
+ writer.WriteStartElement("typeparam");
+ writer.WriteAttributeString("name", name);
+ CopyContent(reader, writer);
+ writer.WriteEndElement();
+
+ reader.Close();
+ }
+
+ // exceptions
+ XPathNodeIterator exceptions = root.Select(exceptionExpression);
+ foreach (XPathNavigator exception in exceptions) {
+
+ string exceptionCref = (string)exception.Evaluate(exceptionCrefExpression);
+
+ XmlReader reader = exception.ReadSubtree();
+
+ writer.WriteStartElement("exception");
+ writer.WriteAttributeString("cref", exceptionCref);
+ CopyContent(reader, writer);
+ writer.WriteEndElement();
+
+ reader.Close();
+ }
+
+ // stored contents
+ XPathNavigator input;
+ if (content.TryGetValue(id, out input)) {
+ XPathNodeIterator input_nodes = input.SelectChildren(XPathNodeType.Element);
+ foreach (XPathNavigator input_node in input_nodes) {
+ input_node.WriteSubtree(writer);
+ }
+ }
+
+ writer.WriteFullEndElement();
+
+ // enumeration members
+ string subgroup = (string)root.Evaluate(subgroupExpression);
+ if (subgroup == "enumeration") {
+
+ XPathNodeIterator elements = (XPathNodeIterator)root.Evaluate(elementsExpression);
+ foreach (XPathNavigator element in elements) {
+
+ string api = (string)element.GetAttribute("api", string.Empty);
+ writer.WriteStartElement("member");
+ writer.WriteAttributeString("name", api);
+
+ //summary
+ WriteSummary(element, memberSummaryExpression, writer);
+
+ writer.WriteFullEndElement();
+ }
+ }
+
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to write intellisense data. The error message is: {0}", e.Message));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("Intellisense data was not valid XML. The error message is: {0}", e.Message));
+ }
+
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (XmlWriter writer in writers.Values) {
+ writer.WriteEndDocument();
+ writer.Close();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ private void WriteSummary(XPathNavigator node, XPathExpression expression, XmlWriter writer) {
+ XPathNavigator summary = node.SelectSingleNode(expression);
+ if (summary != null) {
+ writer.WriteStartElement("summary");
+
+ XmlReader reader = summary.ReadSubtree();
+ CopyContent(reader, writer);
+ reader.Close();
+
+ writer.WriteEndElement();
+ }
+ else {
+ // Console.WriteLine("no summary");
+ }
+ }
+
+ private void CopyContent (XmlReader reader, XmlWriter writer) {
+ reader.MoveToContent();
+ while (true) {
+
+ //Console.WriteLine("{0} {1}", reader.ReadState, reader.NodeType);
+
+ if (reader.NodeType == XmlNodeType.Text) {
+ writer.WriteString(reader.ReadString());
+ } else if (reader.NodeType == XmlNodeType.Element) {
+ //Console.WriteLine(reader.LocalName);
+ if (reader.LocalName == "codeEntityReference") {
+ writer.WriteStartElement("see");
+ writer.WriteAttributeString("cref", reader.ReadElementString());
+ writer.WriteEndElement();
+ } else if (reader.LocalName == "parameterReference") {
+ writer.WriteStartElement("paramref");
+ writer.WriteAttributeString("name", reader.ReadElementString());
+ writer.WriteEndElement();
+ } else if (reader.LocalName == "link") {
+ string displayText = reader.ReadElementString();
+ if (displayText.StartsWith("GTMT#")) {
+ writer.WriteString(displayText.Substring(displayText.IndexOf("#") + 1));
+ } else {
+ writer.WriteString(displayText);
+ }
+ } else {
+ reader.Read();
+ }
+ } else {
+ if (!reader.Read()) break;
+ }
+
+ }
+
+ }
+
+ private string directory = String.Empty;
+
+ private Dictionary<string,XmlWriter> writers = new Dictionary<string,XmlWriter>();
+
+ private XPathExpression assemblyExpression = XPathExpression.Compile("string(/document/reference/containers/library/@assembly)");
+
+ private XPathExpression namespaceAssemblyExpression = XPathExpression.Compile("string(/document/reference/elements/element/containers/library/@assembly)");
+
+ private XPathExpression summaryExpression = XPathExpression.Compile("ddue:dduexml/ddue:summary");
+
+ private XPathExpression returnsExpression = XPathExpression.Compile("ddue:dduexml/ddue:returnValue");
+
+ private XPathExpression parametersExpression = XPathExpression.Compile("ddue:dduexml/ddue:parameters/ddue:parameter/ddue:content");
+
+ private XPathExpression parameterNameExpression = XPathExpression.Compile("string(../ddue:parameterReference)");
+
+ private XPathExpression templatesExpression = XPathExpression.Compile("ddue:dduexml/ddue:genericParameters/ddue:genericParameter/ddue:content");
+
+ private XPathExpression templateNameExpression = XPathExpression.Compile("string(../ddue:parameterReference)");
+
+ private XPathExpression exceptionExpression = XPathExpression.Compile("ddue:dduexml/ddue:exceptions/ddue:exception/ddue:content");
+
+ private XPathExpression exceptionCrefExpression = XPathExpression.Compile("string(../ddue:codeEntityReference)");
+
+ private XPathExpression subgroupExpression = XPathExpression.Compile("string(/document/reference/apidata/@subgroup)");
+
+ private XPathExpression groupExpression = XPathExpression.Compile("string(/document/reference/apidata/@group)");
+
+ private XPathExpression elementsExpression = XPathExpression.Compile("/document/reference/elements/element");
+
+ private XPathExpression memberSummaryExpression = XPathExpression.Compile("ddue:summary");
+
+ private XmlNamespaceManager context = new CustomContext();
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent2.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent2.cs
new file mode 100644
index 0000000..3405ddb
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/IntellisenseComponent2.cs
@@ -0,0 +1,424 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class IntellisenseComponent2 : BuildComponent {
+
+ public IntellisenseComponent2 (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNavigator output_node = configuration.SelectSingleNode("output");
+ if (output_node != null) {
+
+ string directory_value = output_node.GetAttribute("directory", String.Empty);
+ if (!String.IsNullOrEmpty(directory_value)) {
+ directory = Environment.ExpandEnvironmentVariables(directory_value);
+ if (!Directory.Exists(directory)) WriteMessage(MessageLevel.Error, String.Format("The output directory '{0}' does not exist.", directory));
+ }
+ }
+
+ XPathNavigator expression_node = configuration.SelectSingleNode("expressions");
+ if (expression_node != null) {
+
+ string root = expression_node.GetAttribute("root", string.Empty);
+ try {
+ rootExpression = XPathExpression.Compile(root);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", root));
+ }
+
+ string assembly = expression_node.GetAttribute("assembly", string.Empty);
+ try {
+ assemblyExpression = XPathExpression.Compile(assembly);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", assembly));
+ }
+
+ string summary = expression_node.GetAttribute("summary", string.Empty);
+ try {
+ summaryExpression = XPathExpression.Compile(summary);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", summary));
+ }
+
+ string parameters = expression_node.GetAttribute("parameters", string.Empty);
+ try {
+ parametersExpression = XPathExpression.Compile(parameters);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", parameters));
+ }
+
+ string parameterContent = expression_node.GetAttribute("parameterContent", string.Empty);
+ try {
+ parameterContentExpression = XPathExpression.Compile(parameterContent);
+ } catch (XPathException ) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", parameterContent));
+ }
+
+ string templates = expression_node.GetAttribute("templates", string.Empty);
+ try {
+ templatesExpression = XPathExpression.Compile(templates);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", templates));
+ }
+
+ string templateContent = expression_node.GetAttribute("templateContent", string.Empty);
+ try {
+ templateContentExpression = XPathExpression.Compile(templateContent);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", templateContent));
+ }
+
+ string returns = expression_node.GetAttribute("returns", string.Empty);
+ try {
+ returnsExpression = XPathExpression.Compile(returns);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", returns));
+ }
+
+ string exception = expression_node.GetAttribute("exception", string.Empty);
+ try {
+ exceptionExpression = XPathExpression.Compile(exception);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", exception));
+ }
+
+ string exceptionCref = expression_node.GetAttribute("exceptionCref", string.Empty);
+ try {
+ exceptionCrefExpression = XPathExpression.Compile(exceptionCref);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", exceptionCref));
+ }
+
+ string enumeration = expression_node.GetAttribute("enumeration", string.Empty);
+ try {
+ enumerationExpression = XPathExpression.Compile(enumeration);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", enumeration));
+ }
+
+ string enumerationApi = expression_node.GetAttribute("enumerationApi", string.Empty);
+ try {
+ enumerationApiExpression = XPathExpression.Compile(enumerationApi);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", enumerationApi));
+ }
+
+ string memberSummary = expression_node.GetAttribute("memberSummary", string.Empty);
+ try {
+ memberSummaryExpression = XPathExpression.Compile(memberSummary);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The expression '{0}' is not a valid XPath expression.", memberSummary));
+ }
+
+ }
+
+ // a way to get additional information into the intellisense file
+ XPathNodeIterator input_nodes = configuration.Select("input");
+ foreach (XPathNavigator input_node in input_nodes) {
+ string file_value = input_node.GetAttribute("file", String.Empty);
+ if (!String.IsNullOrEmpty(file_value)) {
+ string file = Environment.ExpandEnvironmentVariables(file_value);
+ ReadInputFile(file);
+ }
+ }
+ }
+
+ // input content store
+
+ private void ReadInputFile (string file) {
+ try {
+ XPathDocument document = new XPathDocument(file);
+
+ XPathNodeIterator member_nodes = document.CreateNavigator().Select("/metadata/topic[@id]");
+ foreach (XPathNavigator member_node in member_nodes) {
+ string id = member_node.GetAttribute("id", String.Empty);
+ content[id] = member_node.Clone();
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Read {0} input content nodes.", member_nodes.Count));
+
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The input file '{0}' is not a well-formed XML file. The error message is: {1}", file, e.Message));
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to access the fileThe input file '{0}'. The error message is: {1}", file, e.Message));
+ }
+
+
+ }
+ private Dictionary<string, XPathNavigator> content = new Dictionary<string, XPathNavigator>();
+
+ // the action of the component
+
+ public override void Apply (XmlDocument document, string id) {
+
+ // only generate intellisense if id corresponds to an allowed intellisense ID
+ if (id.Length < 2) return;
+ if (id[1] != ':') return;
+ if (!((id[0] == 'T') || (id[0] == 'M') || (id[0] == 'P') || (id[0] == 'F') || (id[0] == 'E') || (id[0] == 'N'))) return;
+
+ XPathNavigator root = document.CreateNavigator().SelectSingleNode(rootExpression);
+
+ // get the assembly information
+ string assembly = (string) root.Evaluate(assemblyExpression);
+
+ if (String.IsNullOrEmpty(assembly)) {
+ assembly = "namespaces";
+ }
+
+ // try/catch block for capturing errors
+ try {
+
+ // get the writer for the assembly
+ XmlWriter writer;
+ if (!writers.TryGetValue(assembly, out writer)) {
+
+ // create a writer for the assembly
+ string name = Path.Combine(directory, assembly + ".xml");
+ // Console.WriteLine("creating {0}", name);
+
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+
+ try {
+ writer = XmlWriter.Create(name, settings);
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to create the intellisense output file '{0}'. The error message is: {1}", name, e.Message));
+ }
+
+ writers.Add(assembly, writer);
+
+ // write out the initial data
+ writer.WriteStartDocument();
+ writer.WriteStartElement("doc");
+ //do not generate assembly nodes for namespace topics
+ if (assembly != "namespaces")
+ {
+ writer.WriteStartElement("assembly");
+ writer.WriteElementString("name", assembly);
+ writer.WriteEndElement();
+ }
+ writer.WriteStartElement("members");
+ }
+
+ writer.WriteStartElement("member");
+ writer.WriteAttributeString("name", id);
+
+ // summary
+ WriteSummary(root, summaryExpression, writer);
+
+ // return value
+ XPathNavigator returns = root.SelectSingleNode(returnsExpression);
+ if (returns != null) {
+ writer.WriteStartElement("returns");
+ XmlReader reader = returns.ReadSubtree();
+
+ CopyContent(reader, writer);
+ reader.Close();
+
+ writer.WriteEndElement();
+ }
+
+ // parameters
+ XPathNodeIterator parameters = root.Select(parametersExpression);
+ foreach (XPathNavigator parameter in parameters) {
+
+ string name = (string)parameter.GetAttribute("paramName", string.Empty);
+
+ XPathNavigator parameterContent = parameter.SelectSingleNode(parameterContentExpression);
+
+ if (parameterContent == null) continue;
+
+ XmlReader reader = parameterContent.ReadSubtree();
+
+ writer.WriteStartElement("param");
+ writer.WriteAttributeString("name", name);
+ CopyContent(reader, writer);
+ writer.WriteFullEndElement();
+
+ reader.Close();
+ }
+
+ // templates
+ XPathNodeIterator templates = root.Select(templatesExpression);
+ foreach (XPathNavigator template in templates) {
+
+ string name = (string)template.GetAttribute("paramName", string.Empty);
+
+ XPathNavigator templateContent = template.SelectSingleNode(templateContentExpression);
+
+ if (templateContent == null) continue;
+
+ XmlReader reader = templateContent.ReadSubtree();
+
+ writer.WriteStartElement("typeparam");
+ writer.WriteAttributeString("name", name);
+ CopyContent(reader, writer);
+ writer.WriteFullEndElement();
+
+ reader.Close();
+ }
+
+ // exceptions
+ XPathNodeIterator exceptions = root.Select(exceptionExpression);
+ foreach (XPathNavigator exception in exceptions) {
+
+ XPathNavigator exceptionCref = exception.SelectSingleNode(exceptionCrefExpression);
+
+ if (exceptionCref == null) continue;
+
+ string cref = exceptionCref.GetAttribute("target", string.Empty);
+ XmlReader reader = exception.ReadSubtree();
+
+ writer.WriteStartElement("exception");
+ writer.WriteAttributeString("cref", cref);
+ CopyContent(reader, writer);
+ writer.WriteFullEndElement();
+
+ reader.Close();
+ }
+
+ // stored contents
+ XPathNavigator input;
+ if (content.TryGetValue(id, out input)) {
+ XPathNodeIterator input_nodes = input.SelectChildren(XPathNodeType.Element);
+ foreach (XPathNavigator input_node in input_nodes) {
+ input_node.WriteSubtree(writer);
+ }
+ }
+
+ writer.WriteFullEndElement();
+
+ // enumeration members
+ XPathNodeIterator enumerationIterator = root.Select(enumerationExpression);
+
+ foreach (XPathNavigator enumeration in enumerationIterator) {
+
+ XPathNavigator enumApi = enumeration.SelectSingleNode(enumerationApiExpression);
+
+ if (enumApi == null) continue;
+
+ string api = (string)enumApi.GetAttribute("target", string.Empty);
+ writer.WriteStartElement("member");
+ writer.WriteAttributeString("name", api);
+
+ //summary
+ WriteSummary(enumeration, memberSummaryExpression, writer);
+
+ writer.WriteFullEndElement();
+ }
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to write intellisense data. The error message is: {0}", e.Message));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("Intellisense data was not valid XML. The error message is: {0}", e.Message));
+ }
+
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (XmlWriter writer in writers.Values) {
+ writer.WriteEndDocument();
+ writer.Close();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ private void WriteSummary(XPathNavigator node, XPathExpression expression, XmlWriter writer) {
+
+ XPathNavigator summary = node.SelectSingleNode(expression);
+ if (summary != null) {
+ writer.WriteStartElement("summary");
+
+ XmlReader reader = summary.ReadSubtree();
+
+ CopyContent(reader, writer);
+ reader.Close();
+
+ writer.WriteEndElement();
+ } else {
+ // Console.WriteLine("no summary");
+ }
+ }
+
+ private void CopyContent (XmlReader reader, XmlWriter writer) {
+ reader.MoveToContent();
+ while (true) {
+
+ if (reader.NodeType == XmlNodeType.Text) {
+ writer.WriteString(reader.ReadString());
+ } else if (reader.NodeType == XmlNodeType.Element) {
+ if (reader.LocalName == "span" && (reader.GetAttribute("sdata",string.Empty) == "cer")) {
+ writer.WriteStartElement("see");
+ writer.WriteAttributeString("cref", reader.GetAttribute("target", string.Empty));
+ writer.WriteEndElement();
+ reader.Skip();
+ }
+ else if (reader.LocalName == "span" && (reader.GetAttribute("sdata", string.Empty) == "paramReference"))
+ {
+ writer.WriteStartElement("paramref");
+ writer.WriteAttributeString("name", reader.ReadElementString());
+ writer.WriteEndElement();
+ } else if (reader.LocalName == "span" && (reader.GetAttribute("sdata",string.Empty) == "link")) {
+ writer.WriteString(reader.ReadElementString());
+ }
+ else if (reader.LocalName == "span" && (reader.GetAttribute("sdata", string.Empty) == "langKeyword"))
+ {
+ string keyword = reader.GetAttribute("value", string.Empty);
+ writer.WriteString(keyword);
+ reader.Skip();
+ }
+ else {
+ reader.Read();
+ }
+ } else {
+ if (!reader.Read()) break;
+ }
+
+ }
+
+ }
+
+ private string directory = String.Empty;
+
+ private Dictionary<string,XmlWriter> writers = new Dictionary<string,XmlWriter>();
+
+ private XPathExpression rootExpression;
+
+ private XPathExpression assemblyExpression;
+
+ private XPathExpression summaryExpression;
+
+ private XPathExpression parametersExpression;
+
+ private XPathExpression parameterContentExpression;
+
+ private XPathExpression templatesExpression;
+
+ private XPathExpression templateContentExpression;
+
+ private XPathExpression returnsExpression;
+
+ private XPathExpression exceptionExpression;
+
+ private XPathExpression exceptionCrefExpression;
+
+ private XPathExpression enumerationExpression;
+
+ private XPathExpression enumerationApiExpression;
+
+ private XPathExpression memberSummaryExpression;
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/LiveExampleComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/LiveExampleComponent.cs
new file mode 100644
index 0000000..43d76ba
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/LiveExampleComponent.cs
@@ -0,0 +1,195 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Xml;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ /// <summary>
+ /// The LiveExampleComponent replaces ddue:CodeReference elements with links to runnable code samples,
+ /// if the type is "run" or "view". All other kinds of code samples are passed through to the
+ /// standard example component, except that the type prefix is removed. A Parsnip "approval" file can
+ /// be used to omit code samples that did not pass validation, or to replace broken samples with a message
+ /// to that effect.
+ /// </summary>
+ public class LiveExampleComponent : BuildComponent {
+
+ readonly string wdxNamespace = "http://temp.uri/wdx";
+ readonly string wdxPrefix = "wdx";
+
+ XPathExpression selector;
+ XmlNamespaceManager context;
+
+ bool omitBadExamples;
+ //bool runBadExamples;
+
+ Dictionary<string, SampleInfo> sampleInfoTable;
+
+ public LiveExampleComponent(BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration) {
+
+ XPathNavigator parsnip_node = configuration.SelectSingleNode("parsnip");
+ string approvedFile = null;
+ if (parsnip_node != null) {
+ approvedFile = parsnip_node.GetAttribute("approved-file", String.Empty);
+
+ string omitBadExamplesValue = parsnip_node.GetAttribute("omit-bad-examples", String.Empty);
+ if (!string.IsNullOrEmpty(omitBadExamplesValue))
+ omitBadExamples = Boolean.Parse(omitBadExamplesValue);
+
+ //string runBadExamplesValue = parsnip_node.GetAttribute("run-bad-examples", String.Empty);
+ //if (!string.IsNullOrEmpty(runBadExamplesValue))
+ // runBadExamples = Boolean.Parse(runBadExamplesValue);
+ }
+
+ if (string.IsNullOrEmpty(approvedFile))
+ WriteMessage(MessageLevel.Warn, "No approved samples file specified; all available samples will be included.");
+ else
+ LoadApprovedFile(approvedFile);
+
+ context = new CustomContext();
+ context.AddNamespace("ddue", "http://ddue.schemas.microsoft.com/authoring/2003/5");
+
+ selector = XPathExpression.Compile("//ddue:codeReference");
+ selector.SetContext(context);
+ }
+
+ static XPathNavigator[] ConvertIteratorToArray(XPathNodeIterator iterator) {
+ XPathNavigator[] result = new XPathNavigator[iterator.Count];
+ for (int i = 0; i < result.Length; i++) {
+ iterator.MoveNext();
+ result[i] = iterator.Current.Clone();
+ }
+ return (result);
+ }
+
+ public override void Apply(XmlDocument document, string key) {
+ XPathNodeIterator nodesIterator = document.CreateNavigator().Select(selector);
+ XPathNavigator[] nodes = ConvertIteratorToArray(nodesIterator);
+
+ foreach (XPathNavigator node in nodes) {
+ CodeReference cref = new CodeReference(node.Value);
+
+ SampleInfo si = null;
+ if (sampleInfoTable != null && cref.ExampleName != null)
+ sampleInfoTable.TryGetValue(cref.ExampleName, out si);
+
+ WriteMessage(MessageLevel.Info, string.Format("*** codeReference={0}; approved={1}; type={2}",
+ node.Value, (si == null) ? false : si.IsApproved("CS"), cref.Type));
+
+
+ switch (cref.Type) {
+ case CodeReferenceType.Msdn:
+ // TODO: remove "msdn:" from code reference and let ExampleComponent handle the snippet.
+ // We'll either pass this through to the regular ExampleComponent or delete the node.
+ WriteMessage(MessageLevel.Warn, "MSDN-only links not implemented yet.");
+ break;
+
+ case CodeReferenceType.Run:
+ case CodeReferenceType.View:
+ if (si != null || !omitBadExamples) {
+ WriteMessage(MessageLevel.Info, string.Format("+ LiveCode: Kind={0}, SampleName={1}", cref.Type.ToString(), cref.ExamplePath));
+ XmlWriter writer = node.InsertAfter();
+ writer.WriteStartElement(wdxPrefix, "LiveCode", wdxNamespace);
+ writer.WriteAttributeString("Kind", cref.Type.ToString());
+ writer.WriteAttributeString("SampleName", cref.ExamplePath);
+ writer.WriteAttributeString("runat", "server");
+ writer.WriteEndElement();
+ writer.Close();
+ node.DeleteSelf();
+ }
+ break;
+
+ case CodeReferenceType.Snippet:
+ // Ignore; let ExampleComponent handle the snippet.
+ break;
+
+ default:
+ WriteMessage(MessageLevel.Warn, string.Format("Invalid code example reference ignored: '{0}'", node.Value));
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// LoadApprovedFile reads the Parsnip approval file into a memory structure for easy lookup. We're assuming that the
+ /// content of this file is well formed and valid. Semantic errors will be silently ignored. Only samples with
+ /// approved units will be added to the lookup table.
+ /// </summary>
+ void LoadApprovedFile(string pathName) {
+ WriteMessage(MessageLevel.Info, string.Format("Loading Parsnip 'Approved' file: {0}", pathName));
+ sampleInfoTable = new Dictionary<string, SampleInfo>();
+ using (XmlReader reader = XmlReader.Create(pathName)) {
+ SampleInfo si = null;
+ string sample_name = null;
+ while (reader.Read()) {
+ switch (reader.NodeType) {
+ case XmlNodeType.Element:
+ if (reader.Name == "Sample") {
+ sample_name = reader.GetAttribute("name");
+ if (!string.IsNullOrEmpty(sample_name))
+ si = new SampleInfo(sample_name);
+ }
+ else if (si != null && reader.Name == "Unit") {
+ if (reader.GetAttribute("include") == "true")
+ si.AddApprovedUnit(reader.GetAttribute("name"));
+ }
+ break;
+ case XmlNodeType.EndElement:
+ if (reader.Name == "Sample") {
+ if (si != null) {
+ try {
+ if (si.ApprovedUnitsCount > 0)
+ sampleInfoTable.Add(si.Name, si);
+ }
+ catch (Exception x) {
+ WriteMessage(MessageLevel.Warn, string.Format("Sample {0} cannot be loaded {1}", si.Name, x.Message));
+ }
+ }
+ si = null;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ internal class SampleInfo {
+ string _name;
+ internal string Name {
+ get { return _name; }
+ }
+
+ List<string> _approvedUnits;
+
+ internal SampleInfo(string name) {
+ _name = name;
+ }
+
+ internal void AddApprovedUnit(string unit_name) {
+ if (_approvedUnits == null)
+ _approvedUnits = new List<string>();
+ _approvedUnits.Add(unit_name);
+ }
+
+ internal bool IsApproved(string unit_name) {
+ return (_approvedUnits == null) ? false : _approvedUnits.Contains(unit_name);
+ }
+
+ internal int ApprovedUnitsCount {
+ get { return (_approvedUnits == null) ? 0 : _approvedUnits.Count; }
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnResolver.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnResolver.cs
new file mode 100644
index 0000000..84a43f1
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnResolver.cs
@@ -0,0 +1,76 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Web.Services.Protocols;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MsdnResolver {
+
+ public MsdnResolver () {
+ msdnService = new ContentService();
+ msdnService.appIdValue = new appId();
+ msdnService.appIdValue.value = "Sandcastle";
+ msdnService.SoapVersion = SoapProtocolVersion.Soap11;
+ }
+
+ public bool IsDisabled {
+ get {
+ return ((msdnService == null));
+ }
+ }
+
+ public string Locale {
+ get {
+ return (locale);
+ }
+ set {
+ locale = value;
+ }
+ }
+
+ public string GetMsdnUrl (string id) {
+
+ if (cachedMsdnUrls.ContainsKey(id)) return (String.Format(urlFormat, locale, cachedMsdnUrls[id]));
+
+ if (msdnService == null) return(null);
+
+ getContentRequest msdnRequest = new getContentRequest();
+ msdnRequest.contentIdentifier = "AssetId:" + id;
+ msdnRequest.locale = locale;
+
+ string endpoint = null;
+ try {
+ getContentResponse msdnResponse = msdnService.GetContent(msdnRequest);
+ endpoint = msdnResponse.contentId;
+ } catch (WebException) {
+ msdnService = null;
+ } catch (SoapException) {
+ // lookup failed
+ }
+
+ cachedMsdnUrls[id] = endpoint;
+
+ if (String.IsNullOrEmpty(endpoint)) {
+ return (null);
+ } else {
+ return (String.Format(urlFormat, locale, endpoint));
+ }
+ }
+
+ private ContentService msdnService;
+
+ private string locale = "en-us";
+
+ private static string urlFormat = "http://msdn2.microsoft.com/{0}/library/{1}";
+
+ private Dictionary<string, string> cachedMsdnUrls = new Dictionary<string, string>();
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnService.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnService.cs
new file mode 100644
index 0000000..e935faf
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/MsdnService.cs
@@ -0,0 +1,913 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.832
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.Xml.Serialization;
+
+//
+// This source code was auto-generated by wsdl, Version=2.0.50727.42.
+//
+
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Web.Services.WebServiceBindingAttribute(Name="ContentServiceBinding", Namespace="urn:msdn-com:public-content-syndication")]
+[System.Xml.Serialization.XmlIncludeAttribute(typeof(requestedDocument[]))]
+[System.Xml.Serialization.XmlIncludeAttribute(typeof(primary[]))]
+[System.Xml.Serialization.XmlIncludeAttribute(typeof(image[]))]
+[System.Xml.Serialization.XmlIncludeAttribute(typeof(common[]))]
+[System.Xml.Serialization.XmlIncludeAttribute(typeof(feature[]))]
+public partial class ContentService : System.Web.Services.Protocols.SoapHttpClientProtocol {
+
+ private appId appIdValueField;
+
+ private System.Threading.SendOrPostCallback GetContentOperationCompleted;
+
+ private System.Threading.SendOrPostCallback GetNavigationPathsOperationCompleted;
+
+ /// <remarks/>
+ public ContentService() {
+ this.Url = "http://services.msdn.microsoft.com/ContentServices/ContentService.asmx";
+ }
+
+ public appId appIdValue {
+ get {
+ return this.appIdValueField;
+ }
+ set {
+ this.appIdValueField = value;
+ }
+ }
+
+ /// <remarks/>
+ public event GetContentCompletedEventHandler GetContentCompleted;
+
+ /// <remarks/>
+ public event GetNavigationPathsCompletedEventHandler GetNavigationPathsCompleted;
+
+ /// <remarks/>
+ [System.Web.Services.Protocols.SoapHeaderAttribute("appIdValue")]
+ [System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:msdn-com:public-content-syndication/GetContent", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
+ [return: System.Xml.Serialization.XmlElementAttribute("getContentResponse", Namespace="urn:msdn-com:public-content-syndication")]
+ public getContentResponse GetContent([System.Xml.Serialization.XmlElementAttribute(Namespace="urn:msdn-com:public-content-syndication")] getContentRequest getContentRequest) {
+ object[] results = this.Invoke("GetContent", new object[] {
+ getContentRequest});
+ return ((getContentResponse)(results[0]));
+ }
+
+ /// <remarks/>
+ public System.IAsyncResult BeginGetContent(getContentRequest getContentRequest, System.AsyncCallback callback, object asyncState) {
+ return this.BeginInvoke("GetContent", new object[] {
+ getContentRequest}, callback, asyncState);
+ }
+
+ /// <remarks/>
+ public getContentResponse EndGetContent(System.IAsyncResult asyncResult) {
+ object[] results = this.EndInvoke(asyncResult);
+ return ((getContentResponse)(results[0]));
+ }
+
+ /// <remarks/>
+ public void GetContentAsync(getContentRequest getContentRequest) {
+ this.GetContentAsync(getContentRequest, null);
+ }
+
+ /// <remarks/>
+ public void GetContentAsync(getContentRequest getContentRequest, object userState) {
+ if ((this.GetContentOperationCompleted == null)) {
+ this.GetContentOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetContentOperationCompleted);
+ }
+ this.InvokeAsync("GetContent", new object[] {
+ getContentRequest}, this.GetContentOperationCompleted, userState);
+ }
+
+ private void OnGetContentOperationCompleted(object arg) {
+ if ((this.GetContentCompleted != null)) {
+ System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
+ this.GetContentCompleted(this, new GetContentCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
+ }
+ }
+
+ /// <remarks/>
+ [System.Web.Services.Protocols.SoapHeaderAttribute("appIdValue")]
+ [System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:msdn-com:public-content-syndication/GetNavigationPaths", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)]
+ [return: System.Xml.Serialization.XmlElementAttribute("getNavigationPathsResponse", Namespace="urn:msdn-com:public-content-syndication")]
+ public getNavigationPathsResponse GetNavigationPaths([System.Xml.Serialization.XmlElementAttribute(Namespace="urn:msdn-com:public-content-syndication")] getNavigationPathsRequest getNavigationPathsRequest) {
+ object[] results = this.Invoke("GetNavigationPaths", new object[] {
+ getNavigationPathsRequest});
+ return ((getNavigationPathsResponse)(results[0]));
+ }
+
+ /// <remarks/>
+ public System.IAsyncResult BeginGetNavigationPaths(getNavigationPathsRequest getNavigationPathsRequest, System.AsyncCallback callback, object asyncState) {
+ return this.BeginInvoke("GetNavigationPaths", new object[] {
+ getNavigationPathsRequest}, callback, asyncState);
+ }
+
+ /// <remarks/>
+ public getNavigationPathsResponse EndGetNavigationPaths(System.IAsyncResult asyncResult) {
+ object[] results = this.EndInvoke(asyncResult);
+ return ((getNavigationPathsResponse)(results[0]));
+ }
+
+ /// <remarks/>
+ public void GetNavigationPathsAsync(getNavigationPathsRequest getNavigationPathsRequest) {
+ this.GetNavigationPathsAsync(getNavigationPathsRequest, null);
+ }
+
+ /// <remarks/>
+ public void GetNavigationPathsAsync(getNavigationPathsRequest getNavigationPathsRequest, object userState) {
+ if ((this.GetNavigationPathsOperationCompleted == null)) {
+ this.GetNavigationPathsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetNavigationPathsOperationCompleted);
+ }
+ this.InvokeAsync("GetNavigationPaths", new object[] {
+ getNavigationPathsRequest}, this.GetNavigationPathsOperationCompleted, userState);
+ }
+
+ private void OnGetNavigationPathsOperationCompleted(object arg) {
+ if ((this.GetNavigationPathsCompleted != null)) {
+ System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
+ this.GetNavigationPathsCompleted(this, new GetNavigationPathsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
+ }
+ }
+
+ /// <remarks/>
+ public new void CancelAsync(object userState) {
+ base.CancelAsync(userState);
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication/2006/09/common")]
+[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:msdn-com:public-content-syndication/2006/09/common", IsNullable=false)]
+public partial class appId : System.Web.Services.Protocols.SoapHeader {
+
+ private string valueField;
+
+ /// <remarks/>
+ public string value {
+ get {
+ return this.valueField;
+ }
+ set {
+ this.valueField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public partial class navigationPathNode {
+
+ private string titleField;
+
+ private bool isPhantomField;
+
+ private bool isPhantomFieldSpecified;
+
+ private navigationKey navigationNodeKeyField;
+
+ private navigationKey contentNodeKeyField;
+
+ /// <remarks/>
+ public string title {
+ get {
+ return this.titleField;
+ }
+ set {
+ this.titleField = value;
+ }
+ }
+
+ /// <remarks/>
+ public bool isPhantom {
+ get {
+ return this.isPhantomField;
+ }
+ set {
+ this.isPhantomField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlIgnoreAttribute()]
+ public bool isPhantomSpecified {
+ get {
+ return this.isPhantomFieldSpecified;
+ }
+ set {
+ this.isPhantomFieldSpecified = value;
+ }
+ }
+
+ /// <remarks/>
+ public navigationKey navigationNodeKey {
+ get {
+ return this.navigationNodeKeyField;
+ }
+ set {
+ this.navigationNodeKeyField = value;
+ }
+ }
+
+ /// <remarks/>
+ public navigationKey contentNodeKey {
+ get {
+ return this.contentNodeKeyField;
+ }
+ set {
+ this.contentNodeKeyField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public partial class navigationKey {
+
+ private string contentIdField;
+
+ private string localeField;
+
+ private string versionField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string contentId {
+ get {
+ return this.contentIdField;
+ }
+ set {
+ this.contentIdField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string locale {
+ get {
+ return this.localeField;
+ }
+ set {
+ this.localeField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string version {
+ get {
+ return this.versionField;
+ }
+ set {
+ this.versionField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public partial class navigationPath {
+
+ private navigationPathNode[] navigationPathNodesField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable=false)]
+ public navigationPathNode[] navigationPathNodes {
+ get {
+ return this.navigationPathNodesField;
+ }
+ set {
+ this.navigationPathNodesField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public partial class availableVersionAndLocale {
+
+ private string localeField;
+
+ private string versionField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string locale {
+ get {
+ return this.localeField;
+ }
+ set {
+ this.localeField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string version {
+ get {
+ return this.versionField;
+ }
+ set {
+ this.versionField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public partial class requestedDocument {
+
+ private string selectorField;
+
+ private documentTypes typeField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string selector {
+ get {
+ return this.selectorField;
+ }
+ set {
+ this.selectorField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public documentTypes type {
+ get {
+ return this.typeField;
+ }
+ set {
+ this.typeField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:msdn-com:public-content-syndication")]
+public enum documentTypes {
+
+ /// <remarks/>
+ primary,
+
+ /// <remarks/>
+ common,
+
+ /// <remarks/>
+ image,
+
+ /// <remarks/>
+ feature,
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:mtpg-com:mtps/2004/1/primary")]
+public partial class primary {
+
+ private System.Xml.XmlElement anyField;
+
+ private string primaryFormatField;
+
+ private string locationField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAnyElementAttribute()]
+ public System.Xml.XmlElement Any {
+ get {
+ return this.anyField;
+ }
+ set {
+ this.anyField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified, Namespace="urn:mtpg-com:mtps/2004/1/primary/category")]
+ public string primaryFormat {
+ get {
+ return this.primaryFormatField;
+ }
+ set {
+ this.primaryFormatField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string location {
+ get {
+ return this.locationField;
+ }
+ set {
+ this.locationField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:mtpg-com:mtps/2004/1/image")]
+public partial class image {
+
+ private string nameField;
+
+ private string imageFormatField;
+
+ private string locationField;
+
+ private byte[] valueField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string name {
+ get {
+ return this.nameField;
+ }
+ set {
+ this.nameField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified, Namespace="urn:mtpg-com:mtps/2004/1/image/category")]
+ public string imageFormat {
+ get {
+ return this.imageFormatField;
+ }
+ set {
+ this.imageFormatField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string location {
+ get {
+ return this.locationField;
+ }
+ set {
+ this.locationField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlTextAttribute(DataType="base64Binary")]
+ public byte[] Value {
+ get {
+ return this.valueField;
+ }
+ set {
+ this.valueField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:mtpg-com:mtps/2004/1/common")]
+public partial class common {
+
+ private System.Xml.XmlElement[] anyField;
+
+ private string commonFormatField;
+
+ private string locationField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAnyElementAttribute()]
+ public System.Xml.XmlElement[] Any {
+ get {
+ return this.anyField;
+ }
+ set {
+ this.anyField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified, Namespace="urn:mtpg-com:mtps/2004/1/common/category")]
+ public string commonFormat {
+ get {
+ return this.commonFormatField;
+ }
+ set {
+ this.commonFormatField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string location {
+ get {
+ return this.locationField;
+ }
+ set {
+ this.locationField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:mtpg-com:mtps/2004/1/feature")]
+public partial class feature {
+
+ private System.Xml.XmlElement[] anyField;
+
+ private string featureFormatField;
+
+ private string locationField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAnyElementAttribute()]
+ public System.Xml.XmlElement[] Any {
+ get {
+ return this.anyField;
+ }
+ set {
+ this.anyField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified, Namespace="urn:mtpg-com:mtps/2004/1/feature/category")]
+ public string featureFormat {
+ get {
+ return this.featureFormatField;
+ }
+ set {
+ this.featureFormatField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlAttributeAttribute()]
+ public string location {
+ get {
+ return this.locationField;
+ }
+ set {
+ this.locationField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:msdn-com:public-content-syndication")]
+public partial class getContentRequest {
+
+ private string contentIdentifierField;
+
+ private string localeField;
+
+ private string versionField;
+
+ private requestedDocument[] requestedDocumentsField;
+
+ /// <remarks/>
+ public string contentIdentifier {
+ get {
+ return this.contentIdentifierField;
+ }
+ set {
+ this.contentIdentifierField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string locale {
+ get {
+ return this.localeField;
+ }
+ set {
+ this.localeField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string version {
+ get {
+ return this.versionField;
+ }
+ set {
+ this.versionField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable=false)]
+ public requestedDocument[] requestedDocuments {
+ get {
+ return this.requestedDocumentsField;
+ }
+ set {
+ this.requestedDocumentsField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:msdn-com:public-content-syndication")]
+public partial class getContentResponse {
+
+ private string contentIdField;
+
+ private string contentGuidField;
+
+ private string contentAliasField;
+
+ private string localeField;
+
+ private string versionField;
+
+ private availableVersionAndLocale[] availableVersionsAndLocalesField;
+
+ private primary[] primaryDocumentsField;
+
+ private image[] imageDocumentsField;
+
+ private common[] commonDocumentsField;
+
+ private feature[] featureDocumentsField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string contentId {
+ get {
+ return this.contentIdField;
+ }
+ set {
+ this.contentIdField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string contentGuid {
+ get {
+ return this.contentGuidField;
+ }
+ set {
+ this.contentGuidField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string contentAlias {
+ get {
+ return this.contentAliasField;
+ }
+ set {
+ this.contentAliasField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string locale {
+ get {
+ return this.localeField;
+ }
+ set {
+ this.localeField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlElementAttribute(Namespace="urn:mtpg-com:mtps/2004/1/key")]
+ public string version {
+ get {
+ return this.versionField;
+ }
+ set {
+ this.versionField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable=false)]
+ public availableVersionAndLocale[] availableVersionsAndLocales {
+ get {
+ return this.availableVersionsAndLocalesField;
+ }
+ set {
+ this.availableVersionsAndLocalesField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute("primary", Namespace="urn:mtpg-com:mtps/2004/1/primary", IsNullable=false)]
+ public primary[] primaryDocuments {
+ get {
+ return this.primaryDocumentsField;
+ }
+ set {
+ this.primaryDocumentsField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute("image", Namespace="urn:mtpg-com:mtps/2004/1/image", IsNullable=false)]
+ public image[] imageDocuments {
+ get {
+ return this.imageDocumentsField;
+ }
+ set {
+ this.imageDocumentsField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute("common", Namespace="urn:mtpg-com:mtps/2004/1/common", IsNullable=false)]
+ public common[] commonDocuments {
+ get {
+ return this.commonDocumentsField;
+ }
+ set {
+ this.commonDocumentsField = value;
+ }
+ }
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute("feature", Namespace="urn:mtpg-com:mtps/2004/1/feature", IsNullable=false)]
+ public feature[] featureDocuments {
+ get {
+ return this.featureDocumentsField;
+ }
+ set {
+ this.featureDocumentsField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:msdn-com:public-content-syndication")]
+public partial class getNavigationPathsRequest {
+
+ private navigationKey rootField;
+
+ private navigationKey targetField;
+
+ /// <remarks/>
+ public navigationKey root {
+ get {
+ return this.rootField;
+ }
+ set {
+ this.rootField = value;
+ }
+ }
+
+ /// <remarks/>
+ public navigationKey target {
+ get {
+ return this.targetField;
+ }
+ set {
+ this.targetField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.SerializableAttribute()]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:msdn-com:public-content-syndication")]
+public partial class getNavigationPathsResponse {
+
+ private navigationPath[] navigationPathsField;
+
+ /// <remarks/>
+ [System.Xml.Serialization.XmlArrayItemAttribute(IsNullable=false)]
+ public navigationPath[] navigationPaths {
+ get {
+ return this.navigationPathsField;
+ }
+ set {
+ this.navigationPathsField = value;
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+public delegate void GetContentCompletedEventHandler(object sender, GetContentCompletedEventArgs e);
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+public partial class GetContentCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
+
+ private object[] results;
+
+ internal GetContentCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
+ base(exception, cancelled, userState) {
+ this.results = results;
+ }
+
+ /// <remarks/>
+ public getContentResponse Result {
+ get {
+ this.RaiseExceptionIfNecessary();
+ return ((getContentResponse)(this.results[0]));
+ }
+ }
+}
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+public delegate void GetNavigationPathsCompletedEventHandler(object sender, GetNavigationPathsCompletedEventArgs e);
+
+/// <remarks/>
+[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")]
+[System.Diagnostics.DebuggerStepThroughAttribute()]
+[System.ComponentModel.DesignerCategoryAttribute("code")]
+public partial class GetNavigationPathsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs {
+
+ private object[] results;
+
+ internal GetNavigationPathsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
+ base(exception, cancelled, userState) {
+ this.results = results;
+ }
+
+ /// <remarks/>
+ public getNavigationPathsResponse Result {
+ get {
+ this.RaiseExceptionIfNecessary();
+ return ((getNavigationPathsResponse)(this.results[0]));
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/PlatformsComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/PlatformsComponent.cs
new file mode 100644
index 0000000..cd3f2cc
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/PlatformsComponent.cs
@@ -0,0 +1,674 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+using System.IO;
+using System.Text;
+
+// still have problems with spaces
+
+namespace Microsoft.Ddue.Tools
+{
+
+ public class PlatformsComponent : BuildComponent
+ {
+
+ private Dictionary<string, Dictionary<string, VersionFilter>> versionFilters = new Dictionary<string, Dictionary<string, VersionFilter>>();
+
+ private XPathExpression platformQuery = XPathExpression.Compile("/platforms/platform");
+ private XPathExpression referenceExpression = XPathExpression.Compile("/document/reference");
+ private XPathExpression versionNodesExpression = XPathExpression.Compile("versions//version");
+ private XPathExpression apiGroupExpression = XPathExpression.Compile("string(apidata/@group)");
+ private XPathExpression topicdataGroupExpression = XPathExpression.Compile("string(topicdata/@group)");
+ private XPathExpression topicdataSubgroupExpression = XPathExpression.Compile("string(topicdata/@subgroup)");
+ private XPathExpression listTypeNameExpression = XPathExpression.Compile("string(apidata/@name)");
+ private XPathExpression apiNamespaceNameExpression = XPathExpression.Compile("string(containers/namespace/apidata/@name)");
+ private XPathExpression memberTypeNameExpression = XPathExpression.Compile("string(containers/type/apidata/@name)");
+
+ private XPathExpression listTopicElementNodesExpression = XPathExpression.Compile("elements//element");
+ private XPathExpression elementIdExpression = XPathExpression.Compile("string(@api)");
+
+ public PlatformsComponent(BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration)
+ {
+ // get the filter files
+ XPathNodeIterator filterNodes = configuration.Select("filter");
+ foreach (XPathNavigator filterNode in filterNodes)
+ {
+ string filterFiles = filterNode.GetAttribute("files", String.Empty);
+ if ((filterFiles == null) || (filterFiles.Length == 0))
+ throw new ConfigurationErrorsException("The filter/@files attribute must specify a path.");
+ ParseDocuments(filterFiles);
+ }
+ //WriteMessage(MessageLevel.Info, String.Format("Indexed {0} elements.", index.Count));
+ }
+
+ public void ParseDocuments(string wildcardPath)
+ {
+ string filterFiles = Environment.ExpandEnvironmentVariables(wildcardPath);
+ if ((filterFiles == null) || (filterFiles.Length == 0))
+ throw new ConfigurationErrorsException("The filter path is an empty string.");
+
+ WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", filterFiles));
+ string directoryPart = Path.GetDirectoryName(filterFiles);
+ if (String.IsNullOrEmpty(directoryPart))
+ directoryPart = Environment.CurrentDirectory;
+ directoryPart = Path.GetFullPath(directoryPart);
+ string filePart = Path.GetFileName(filterFiles);
+ string[] files = Directory.GetFiles(directoryPart, filePart);
+ foreach (string file in files)
+ ParseDocument(file);
+ WriteMessage(MessageLevel.Info, String.Format("Found {0} files in {1}.", files.Length, filterFiles));
+ }
+
+ private void AddPlatformVersionFilter(string platformId, string versionId, XPathNavigator platformNode, string file)
+ {
+ Dictionary<string, VersionFilter> platformFrameworks;
+ if (!versionFilters.TryGetValue(platformId, out platformFrameworks))
+ {
+ platformFrameworks = new Dictionary<string, VersionFilter>();
+ versionFilters.Add(platformId, platformFrameworks);
+ }
+
+ try
+ {
+ VersionFilter filter;
+ XmlReader platformReader = platformNode.ReadSubtree();
+ platformReader.MoveToContent();
+ if (!platformFrameworks.TryGetValue(versionId, out filter))
+ {
+ filter = new VersionFilter(platformReader, versionId, file);
+ }
+ else
+ {
+ // if the platform already has a filter for this version, add the data from the current platform node
+ filter.AddPlatformNode(platformReader, file);
+ }
+ platformReader.Close();
+
+ platformFrameworks.Remove(versionId);
+ platformFrameworks.Add(versionId, filter);
+ }
+ catch (Exception e)
+ {
+ WriteMessage(MessageLevel.Error, e.Message);
+ }
+ }
+
+ private void ParseDocument(string file)
+ {
+ try
+ {
+ XPathDocument document = new XPathDocument(file);
+
+ XPathNodeIterator platformNodes = document.CreateNavigator().Select(platformQuery);
+ foreach (XPathNavigator platformNode in platformNodes)
+ {
+ string platformId = platformNode.GetAttribute("name", String.Empty);
+ string[] platformIds = platformId.Split(',');
+
+ string version = platformNode.GetAttribute("version", String.Empty);
+ string[] versionIds = version.Split(',');
+ for (int i = 0; i < versionIds.Length; i++)
+ {
+ for (int j = 0; j < platformIds.Length; j++)
+ {
+ XPathNavigator platformNodeClone = platformNode.Clone();
+ AddPlatformVersionFilter(platformIds[j], versionIds[i], platformNodeClone, file);
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ WriteMessage(MessageLevel.Error, e.Message);
+ }
+ }
+
+ public override void Apply(XmlDocument document, string key)
+ {
+ XPathNavigator targetDoc = document.CreateNavigator();
+ XPathNavigator referenceNode = targetDoc.SelectSingleNode(referenceExpression);
+ string apiGroup = (string)referenceNode.Evaluate(apiGroupExpression);
+ string topicdataGroup = (string)referenceNode.Evaluate(topicdataGroupExpression);
+ string topicdataSubgroup = (string)referenceNode.Evaluate(topicdataSubgroupExpression);
+
+ // get the namespace and typename of the current type to locate the filter information that applies to the current topic
+ // For filtering inherited members, the platform filters use the namespace and typename of the inheriting type, not the declaring type,
+ string topicNamespaceName = (string)referenceNode.Evaluate(apiNamespaceNameExpression);
+ string topicTypeName = (string)referenceNode.Evaluate(memberTypeNameExpression);
+
+ // write platforms info for normal api topics (excluding memberlist and overload list topics
+ if (topicdataGroup != "list" && topicdataSubgroup != "DerivedTypeList" && (apiGroup == "type" || apiGroup == "member") && versionFilters.Count > 0)
+ {
+ WriteApiPlatforms(referenceNode, apiGroup, key, topicTypeName, topicNamespaceName);
+ }
+
+ // write platforms for elements//element nodes (member list and overload topics; not root or namespace)
+ if ((topicdataGroup == "list" && topicdataSubgroup != "DerivedTypeList") && apiGroup != "root" && versionFilters.Count > 0)
+ {
+ if (topicdataSubgroup != "overload")
+ topicTypeName = (string)referenceNode.Evaluate(listTypeNameExpression);
+
+ XPathNodeIterator elementNodes = referenceNode.Select(listTopicElementNodesExpression);
+ foreach (XPathNavigator elementNode in elementNodes)
+ {
+ string elementId = (string)elementNode.Evaluate(elementIdExpression);
+ WriteApiPlatforms(elementNode, "member", elementId, topicTypeName, topicNamespaceName);
+ }
+ }
+ }
+
+ private void WriteApiPlatforms(XPathNavigator referenceNode, string apiGroup, string key, string topicTypeName, string topicNamespaceName)
+ {
+ XPathNodeIterator versionNodes = referenceNode.Select(versionNodesExpression);
+ List<string> supportedPlatforms = new List<string>();
+ XmlWriter platformsWriter = referenceNode.AppendChild();
+
+ foreach (string platformId in versionFilters.Keys)
+ {
+ Dictionary<string, VersionFilter> filters = versionFilters[platformId];
+ bool included = false;
+ foreach (XPathNavigator versionNode in versionNodes)
+ {
+ string versionId = versionNode.GetAttribute("name", string.Empty);
+ VersionFilter filter;
+ if (filters.TryGetValue(versionId, out filter))
+ {
+ switch (apiGroup)
+ {
+ case "type":
+ included = filter.IsIncludedType(referenceNode, key, topicNamespaceName);
+ break;
+ case "member":
+ included = filter.IsIncludedMember(referenceNode, key, topicTypeName, topicNamespaceName);
+ break;
+ }
+ }
+ if (included)
+ break;
+ }
+
+ if (included)
+ supportedPlatforms.Add(platformId);
+ }
+ platformsWriter.WriteStartElement("platforms");
+ foreach (string platformId in supportedPlatforms)
+ {
+ platformsWriter.WriteElementString("platform", platformId);
+ }
+ platformsWriter.WriteEndElement();
+ platformsWriter.Close();
+ }
+
+ }
+
+ public abstract class InclusionFilter
+ {
+ public InclusionFilter(string file)
+ {
+ sourceFiles.Add(file);
+ }
+
+ protected List<string> sourceFiles = new List<string>();
+
+ protected static XPathExpression apiNameExpression = XPathExpression.Compile("string(apidata/@name)");
+ protected static XPathExpression apiParameterNodesExpression = XPathExpression.Compile("parameters/parameter");
+ protected static XPathExpression apiParameterTypeNameExpression = XPathExpression.Compile("string(.//type/@api)");
+ protected static XPathExpression apiParameterTemplateNameExpression = XPathExpression.Compile("string(.//template/@name)");
+ }
+
+ public class VersionFilter : InclusionFilter
+ {
+
+ public VersionFilter(XmlReader platformReader, string id, string file)
+ : base(file)
+ {
+ // platform/@version can only list included framework versions; excluding versions is not supported
+ included = true;
+ versionId = id;
+ AddPlatformNode(platformReader, file);
+ }
+
+ public void AddPlatformNode(XmlReader platformReader, string file)
+ {
+ XmlReader subtree = platformReader.ReadSubtree();
+ while (subtree.Read())
+ {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "namespace"))
+ {
+ string namespaceName = subtree.GetAttribute("name");
+
+ NamespaceFilter namespaceFilter;
+ if (!namespaceFilters.TryGetValue(namespaceName, out namespaceFilter))
+ {
+ namespaceFilter = new NamespaceFilter(subtree, file);
+ }
+ else
+ {
+ // if the version already has a filter for this namespace, add the data from the current namespace node
+ // unless the namespace node has a different @include value, in which case log a warning
+ string nsIncludeAttr = subtree.GetAttribute("include");
+ bool nsIncluded = Convert.ToBoolean(string.IsNullOrEmpty(nsIncludeAttr) ? "true" : nsIncludeAttr);
+ if (nsIncluded != namespaceFilter.Included)
+ {
+ // write warning message about conflicting filters
+ // ISSUE: how to invoke WriteMessage from here
+ Console.Write("");
+ }
+ else
+ {
+ namespaceFilter.AddNamespaceNode(subtree, file);
+ }
+
+ }
+ namespaceFilters.Remove(namespaceName);
+ namespaceFilters.Add(namespaceName, namespaceFilter);
+ }
+ }
+ subtree.Close();
+ }
+
+ private string versionId;
+
+ // platform/@version can only list included framework versions; excluding versions is not supported
+ private bool included;
+
+ private Dictionary<string, NamespaceFilter> namespaceFilters = new Dictionary<string, NamespaceFilter>();
+
+ public string VersionId
+ {
+ get
+ {
+ return (versionId);
+ }
+ }
+
+ public Dictionary<string, NamespaceFilter> NamespaceFilters
+ {
+ get
+ {
+ return (namespaceFilters);
+ }
+ }
+
+ /// <summary>
+ /// If we get here, we know that the platform supports this version, and the api is included in this version.
+ /// So returns true unless the type or its namespace are explicitly excluded by this version filter.
+ /// </summary>
+ /// <param name="referenceNode">The type's reflection data.</param>
+ /// <returns></returns>
+ public bool IsIncludedType(XPathNavigator referenceNode, string key, string topicNamespaceName)
+ {
+ // if we have a filter for the topic's namespace, check it
+ NamespaceFilter namespaceFilter;
+ if (namespaceFilters.TryGetValue(topicNamespaceName, out namespaceFilter))
+ {
+ return namespaceFilter.IsIncludedType(referenceNode, key);
+ }
+ return included;
+ }
+
+ public bool IsIncludedMember(XPathNavigator referenceNode, string key, string topicTypeName, string topicNamespaceName)
+ {
+ // if we have a filter for the topic's namespace, check it
+ NamespaceFilter namespaceFilter;
+ if (namespaceFilters.TryGetValue(topicNamespaceName, out namespaceFilter))
+ {
+ return namespaceFilter.IsIncludedMember(referenceNode, key, topicTypeName);
+ }
+ return included;
+ }
+ }
+
+
+ public class NamespaceFilter : InclusionFilter
+ {
+
+ public NamespaceFilter(XmlReader namespaceReader, string file)
+ : base(file)
+ {
+ //name = namespaceReader.GetAttribute("name");
+ string includeAttr = namespaceReader.GetAttribute("include");
+ included = Convert.ToBoolean(string.IsNullOrEmpty(includeAttr) ? "true" : includeAttr);
+ AddNamespaceNode(namespaceReader, file);
+ }
+
+ public void AddNamespaceNode(XmlReader namespaceReader, string file)
+ {
+ XmlReader subtree = namespaceReader.ReadSubtree();
+ while (subtree.Read())
+ {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "type"))
+ {
+ string typeName = subtree.GetAttribute("name");
+
+ TypeFilter typeFilter;
+ if (!typeFilters.TryGetValue(typeName, out typeFilter))
+ {
+ typeFilter = new TypeFilter(subtree, file);
+ }
+ else
+ {
+ // if the namespace already has a filter for this type, add the data from the current type node
+ // unless the type node has a different @include value, in which case log a warning
+ string typeIncludeAttr = subtree.GetAttribute("include");
+ bool typeIncluded = Convert.ToBoolean(string.IsNullOrEmpty(typeIncludeAttr) ? "true" : typeIncludeAttr);
+ if (typeIncluded != typeFilter.Included)
+ {
+ // write warning message about conflicting filters
+ // ISSUE: how to invoke WriteMessage from here
+ Console.Write("");
+ }
+ else
+ {
+ typeFilter.AddTypeNode(subtree, file);
+ }
+ }
+ typeFilters.Remove(typeName);
+ typeFilters.Add(typeName, typeFilter);
+ }
+ }
+ subtree.Close();
+ }
+
+ //private string name;
+
+ private bool included;
+ public bool Included
+ {
+ get
+ {
+ return (included);
+ }
+ }
+
+ private Dictionary<string, TypeFilter> typeFilters = new Dictionary<string, TypeFilter>();
+ public Dictionary<string, TypeFilter> TypeFilters
+ {
+ get
+ {
+ return (typeFilters);
+ }
+ }
+
+ public bool IsIncludedType(XPathNavigator referenceNode, string key)
+ {
+ // get the type's name
+ string typeName = (string)referenceNode.Evaluate(apiNameExpression);
+
+ // if we have a filter for that type, check it
+ TypeFilter typeFilter;
+ if (typeFilters.TryGetValue(typeName, out typeFilter))
+ {
+ return typeFilter.Included;
+ }
+ return included;
+ }
+
+ public bool IsIncludedMember(XPathNavigator referenceNode, string key, string topicTypeName)
+ {
+ // if we have a filter for the type, check it
+ TypeFilter typeFilter;
+ if (typeFilters.TryGetValue(topicTypeName, out typeFilter))
+ {
+ return typeFilter.IsIncludedMember(referenceNode, key);
+ }
+ return included;
+ }
+ }
+
+ public class TypeFilter : InclusionFilter
+ {
+
+ public TypeFilter(XmlReader typeReader, string file)
+ : base(file)
+ {
+ //name = typeReader.GetAttribute("name");
+ string includeAttr = typeReader.GetAttribute("include");
+ included = Convert.ToBoolean(string.IsNullOrEmpty(includeAttr) ? "true" : includeAttr);
+ AddTypeNode(typeReader, file);
+ }
+
+ public void AddTypeNode(XmlReader typeReader, string file)
+ {
+ XmlReader subtree = typeReader.ReadSubtree();
+ while (subtree.Read())
+ {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "member"))
+ {
+ string memberName = subtree.GetAttribute("name");
+
+ MemberFilter memberFilter;
+ if (!memberFilters.TryGetValue(memberName, out memberFilter))
+ {
+ memberFilter = new MemberFilter(subtree, file);
+ }
+ else
+ {
+ // if the type already has a filter for this member, add the data from the current member node
+ // unless the member node has a different @include value, in which case log a warning
+ string memberIncludeAttr = subtree.GetAttribute("include");
+ bool memberIncluded = Convert.ToBoolean(string.IsNullOrEmpty(memberIncludeAttr) ? "true" : memberIncludeAttr);
+ if (memberIncluded != memberFilter.Included)
+ {
+ // write warning message about conflicting filters
+ // ISSUE: how to invoke WriteMessage from here
+ Console.Write("");
+ }
+ else
+ {
+ memberFilter.AddMemberNode(subtree, file);
+ }
+ }
+ memberFilters.Remove(memberName);
+ memberFilters.Add(memberName, memberFilter);
+ }
+ }
+ subtree.Close();
+ }
+
+ //private string name;
+
+ private bool included;
+ public bool Included
+ {
+ get
+ {
+ return (included);
+ }
+ }
+
+ private Dictionary<string, MemberFilter> memberFilters = new Dictionary<string, MemberFilter>();
+ public Dictionary<string, MemberFilter> MemberFilters
+ {
+ get
+ {
+ return (memberFilters);
+ }
+ }
+
+ public bool IsIncludedMember(XPathNavigator referenceNode, string key)
+ {
+ // get the member's name
+ string memberName = (string)referenceNode.Evaluate(apiNameExpression);
+
+ // if we have a filter for that member, check it
+ MemberFilter memberFilter;
+ if (memberFilters.TryGetValue(memberName, out memberFilter))
+ {
+ return memberFilter.IsIncludedMember(referenceNode, key);
+ }
+ return included;
+ }
+
+ }
+
+ public class MemberFilter : InclusionFilter
+ {
+
+ public MemberFilter(XmlReader memberReader, string file)
+ : base(file)
+ {
+ //name = memberReader.GetAttribute("name");
+
+ string includeAttr = memberReader.GetAttribute("include");
+ included = Convert.ToBoolean(string.IsNullOrEmpty(includeAttr) ? "true" : includeAttr);
+ AddMemberNode(memberReader, file);
+ }
+
+ public void AddMemberNode(XmlReader memberReader, string file)
+ {
+ XmlReader subtree = memberReader.ReadSubtree();
+ while (subtree.Read())
+ {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "overload"))
+ {
+ string overloadId = subtree.GetAttribute("api");
+ string paramTypes = subtree.GetAttribute("types");
+ string paramNames = subtree.GetAttribute("names");
+ string overloadIncludeAttr = subtree.GetAttribute("include");
+ bool overloadIncluded = Convert.ToBoolean(string.IsNullOrEmpty(overloadIncludeAttr) ? "true" : overloadIncludeAttr);
+ // check for existing overload filters that identify the same overload
+ bool alreadyFiltered = false;
+ foreach (OverloadFilter overloadFilter in overloadFilters)
+ {
+ if (!string.IsNullOrEmpty(paramTypes) && paramTypes == overloadFilter.ParamTypes)
+ alreadyFiltered = true;
+ if (alreadyFiltered && (overloadIncluded != overloadFilter.Included))
+ {
+ // write warning message about conflicting filters
+ // ISSUE: how to invoke WriteMessage from here
+ Console.Write("");
+ }
+ }
+ if (!alreadyFiltered)
+ {
+ OverloadFilter overloadFilter = new OverloadFilter(subtree, file);
+ overloadFilters.Add(overloadFilter);
+ }
+ }
+ }
+ subtree.Close();
+ }
+
+ //private string name;
+
+ private bool included;
+ public bool Included
+ {
+ get
+ {
+ return (included);
+ }
+ }
+
+ private List<OverloadFilter> overloadFilters = new List<OverloadFilter>();
+
+ public bool IsIncludedMember(XPathNavigator referenceNode, string key)
+ {
+ if (overloadFilters.Count == 0)
+ return included;
+
+ // get the member's paramTypes string
+
+
+ // get the member's paramNames string
+ XPathNodeIterator parameterNodes = referenceNode.Select(apiParameterNodesExpression);
+
+ StringBuilder paramNames = new StringBuilder();
+ StringBuilder paramTypes = new StringBuilder();
+ int i = 0;
+ foreach (XPathNavigator parameterNode in parameterNodes)
+ {
+ i++;
+ paramNames.Append(parameterNode.GetAttribute("name", string.Empty));
+ if (i < parameterNodes.Count)
+ paramNames.Append(",");
+
+ // BUGBUG: code here and in the psx conversion transform is a quick hack; make it better
+ string arrayOf = (parameterNode.SelectSingleNode("arrayOf") == null) ? "" : "[]";
+ string typeName = (string)parameterNode.Evaluate(apiParameterTypeNameExpression);
+ if (string.IsNullOrEmpty(typeName))
+ typeName = (string)parameterNode.Evaluate(apiParameterTemplateNameExpression);
+
+ int basenameStart = typeName.LastIndexOf(':') + 1;
+ if (basenameStart > 0 && basenameStart < typeName.Length)
+ typeName = typeName.Substring(basenameStart);
+
+ paramTypes.Append(typeName + arrayOf);
+ if (i < parameterNodes.Count)
+ paramTypes.Append(",");
+ }
+
+ foreach (OverloadFilter overloadFilter in overloadFilters)
+ {
+ if (paramTypes.ToString() == overloadFilter.ParamTypes)
+ return overloadFilter.Included;
+ }
+
+ return included;
+ }
+
+ }
+
+ public class OverloadFilter : InclusionFilter
+ {
+
+ public OverloadFilter(XmlReader overloadReader, string file)
+ : base(file)
+ {
+ //name = overloadReader.GetAttribute("name");
+ string includeAttr = overloadReader.GetAttribute("include");
+ included = Convert.ToBoolean(string.IsNullOrEmpty(includeAttr) ? "true" : includeAttr);
+ overloadId = overloadReader.GetAttribute("api");
+ paramTypes = overloadReader.GetAttribute("types");
+ paramNames = overloadReader.GetAttribute("names");
+ }
+
+ //private string name;
+
+ private bool included;
+ public bool Included
+ {
+ get
+ {
+ return (included);
+ }
+ }
+
+ private string paramTypes;
+ public string ParamTypes
+ {
+ get
+ {
+ return (paramTypes);
+ }
+ }
+
+ private string paramNames;
+ public string ParamNames
+ {
+ get
+ {
+ return (paramNames);
+ }
+ }
+ private string overloadId;
+ public string OverloadId
+ {
+ get
+ {
+ return (overloadId);
+ }
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..41965fc
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/AssemblyInfo.cs
@@ -0,0 +1,42 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BuildComponents")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("BuildComponents")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("146f3298-2c7f-4588-88f2-520438232a23")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.Designer.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..930f32a
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.42
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace BuildComponents.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.settings b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.settings
new file mode 100644
index 0000000..8e615f2
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Properties/Settings.settings
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles />
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/References.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/References.cs
new file mode 100644
index 0000000..ba23c6f
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/References.cs
@@ -0,0 +1,340 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace BuildComponents {
+
+ public interface ISimpleReference {
+
+ string Id { get; }
+
+ }
+
+ public abstract partial class Reference { }
+
+ // Namespace
+
+ public partial class NamespaceReference : Reference, ISimpleReference {
+
+ internal NamespaceReference (string id) {
+ this.namespaceId = id;
+ }
+
+ private string namespaceId;
+
+ public string Id {
+ get {
+ return (namespaceId);
+ }
+ }
+
+ }
+
+ // Type
+
+ public abstract partial class TypeReference : Reference { }
+
+ public partial class SimpleTypeReference : TypeReference {
+
+ internal SimpleTypeReference (string id) {
+ this.typeId = id;
+ }
+
+ private string typeId;
+
+ public string Id {
+ get {
+ return (typeId);
+ }
+ }
+
+
+ }
+
+ public partial class ReferenceTypeReference : TypeReference {
+
+ private TypeReference referedToType;
+
+ public TypeReference ReferedToType {
+ get {
+ return (referedToType);
+ }
+ }
+
+ internal ReferenceTypeReference (TypeReference referedToType) {
+ if (referedToType == null) throw new ArgumentNullException("referedToType");
+ this.referedToType = referedToType;
+ }
+ }
+
+ public partial class PointerTypeReference : TypeReference {
+
+ internal PointerTypeReference (TypeReference pointedToType) {
+ if (pointedToType == null) throw new ArgumentNullException("pointedToType");
+ this.pointedToType = pointedToType;
+ }
+
+ private TypeReference pointedToType;
+
+ public TypeReference PointedToType {
+ get {
+ return (pointedToType);
+ }
+ }
+
+ }
+
+ public partial class ArrayTypeReference : TypeReference {
+
+ internal ArrayTypeReference (TypeReference elementType, int rank) {
+ if (elementType == null) throw new ArgumentNullException("elementType");
+ if (rank <= 0) throw new ArgumentOutOfRangeException("rank");
+ this.elementType = elementType;
+ this.rank = rank;
+ }
+
+ private int rank;
+
+ private TypeReference elementType;
+
+ public int Rank {
+ get {
+ return (rank);
+ }
+ }
+
+ public TypeReference ElementType {
+ get {
+ return (elementType);
+ }
+ }
+
+ }
+
+ public class TemplateTypeReference : TypeReference {
+
+ internal TemplateTypeReference (string templateId, int position) {
+ if (template == null) throw new ArgumentNullException("template");
+ if (position < 0) throw new ArgumentOutOfRangeException("position");
+ this.template = null; // fix this: create a reference
+ this.position = position;
+ }
+
+ internal TemplateTypeReference (ISimpleReference template, int position) {
+ if (template == null) throw new ArgumentNullException("template");
+ if (position < 0) throw new ArgumentOutOfRangeException("position");
+ this.template = template;
+ this.position = position;
+ }
+
+ private ISimpleReference template;
+
+ private int position;
+ }
+
+ public abstract partial class MemberReference : Reference {}
+
+ public partial class SimpleMemberReference : MemberReference, ISimpleReference {
+
+ internal SimpleMemberReference (string id) {
+ if (id == null) throw new ArgumentNullException("id");
+ this.memberId = id;
+ }
+
+ private string memberId;
+
+ public string Id {
+ get {
+ return(memberId);
+ }
+ }
+
+
+
+ }
+
+
+
+
+ // ***** XML PARSING ****
+
+ public partial class Reference {
+
+ public static Reference Create (XmlReader element) {
+ if (element == null) throw new ArgumentNullException("element");
+ switch (element.LocalName) {
+ case "namespace":
+ return (NamespaceReference.Create(element));
+ case "member":
+ return (MemberReference.Create(element));
+ default:
+ return (TypeReference.Create(element));
+ }
+ }
+
+ public static Reference Create (XPathNavigator node) {
+ if (node == null) throw new ArgumentNullException("node");
+ if (node.NodeType == XPathNodeType.Element) {
+ string tag = node.LocalName;
+ if (tag == "namespace") return (NamespaceReference.Create(node));
+ //if (tag == "member") return (MemberReference.Create(node));
+ return (TypeReference.Create(node));
+ } else {
+ return (null);
+ }
+ }
+
+ protected static XPathExpression referenceApiExpression = XPathExpression.Compile("string(@api)");
+
+
+ }
+
+ public partial class NamespaceReference {
+
+ public static new NamespaceReference Create (XmlReader space) {
+ if (space == null) throw new ArgumentNullException("space");
+
+ string api = space.GetAttribute("api");
+
+ return(new NamespaceReference(api));
+
+ }
+
+ public static new NamespaceReference Create (XPathNavigator space) {
+ if (space == null) throw new ArgumentNullException("space");
+ string api = (string) space.Evaluate(referenceApiExpression);
+ return(new NamespaceReference(api));
+ }
+
+ }
+
+ public partial class TypeReference {
+
+ public static new TypeReference Create (XmlReader element) {
+ if (element == null) throw new ArgumentNullException("element");
+ switch (element.LocalName) {
+ case "type":
+ // also handle specialization!
+ return(SimpleTypeReference.Create(element));
+ case "referenceTo":
+ return(ReferenceTypeReference.Create(element));
+ case "pointerTo":
+ return(PointerTypeReference.Create(element));
+ case "arrayOf":
+ return(ArrayTypeReference.Create(element));
+
+ }
+ return (null);
+ }
+
+ public static new TypeReference Create (XPathNavigator element) {
+ if (element == null) throw new ArgumentNullException("element");
+ string tag = element.LocalName;
+ if (tag == "type") {
+ bool isSpecialized = (bool)element.Evaluate("boolean(.//specialization)");
+ if (isSpecialized) {
+ // deal with specialization!
+ // return (CreateSpecializedTypeReference(element));
+ return (SimpleTypeReference.Create(element));
+ } else {
+ return (SimpleTypeReference.Create(element));
+ }
+ } else if (tag == "arrayOf") {
+ string rankValue = element.GetAttribute("rank", String.Empty);
+ XPathNavigator elementNode = element.SelectSingleNode("*[1]");
+ return (new ArrayTypeReference(TypeReference.Create(elementNode), Convert.ToInt32(rankValue)));
+ } else if (tag == "referenceTo") {
+ XPathNavigator referedToNode = element.SelectSingleNode("*[1]");
+ return (new ReferenceTypeReference(TypeReference.Create(referedToNode)));
+ } else if (tag == "pointerTo") {
+ XPathNavigator pointedToNode = element.SelectSingleNode("*[1]");
+ return (new PointerTypeReference(TypeReference.Create(pointedToNode)));
+ } else if (tag == "template") {
+ //string nameValue = element.GetAttribute("name", String.Empty);
+ string indexValue = element.GetAttribute("index", String.Empty);
+ string apiValue = element.GetAttribute("api", String.Empty);
+ if ((!String.IsNullOrEmpty(apiValue)) && (!String.IsNullOrEmpty(indexValue))) {
+ return (new TemplateTypeReference(apiValue, Convert.ToInt32(indexValue)));
+ // return (new IndexedTemplateTypeReference(apiValue, Convert.ToInt32(indexValue)));
+ } else {
+ throw new InvalidOperationException();
+ // return (new NamedTemplateTypeReference(nameValue));
+ }
+ }
+
+ throw new InvalidOperationException(String.Format("INVALID '{0}'", tag));
+ }
+
+ }
+
+ public partial class SimpleTypeReference {
+
+ public static new SimpleTypeReference Create (XmlReader type) {
+ if (type == null) throw new ArgumentNullException("type");
+ string api = type.GetAttribute("api");
+ return (new SimpleTypeReference(api));
+ }
+
+ public static new SimpleTypeReference Create (XPathNavigator type) {
+ if (type == null) throw new ArgumentNullException("type");
+ string api = (string)type.Evaluate(referenceApiExpression);
+ return(new SimpleTypeReference(api));
+ }
+
+ }
+
+ public partial class ReferenceTypeReference {
+
+ public static new ReferenceTypeReference Create (XmlReader referenceTo) {
+ if (referenceTo == null) throw new ArgumentException("refernceTo");
+ referenceTo.Read();
+ TypeReference referedToType = TypeReference.Create(referenceTo);
+ return (new ReferenceTypeReference(referedToType));
+ }
+
+ public static new ReferenceTypeReference Create (XPathNavigator referenceTo) {
+ XPathNavigator referedToNode = referenceTo.SelectSingleNode("*[1]");
+ TypeReference referedToType = TypeReference.Create(referedToNode);
+ return (new ReferenceTypeReference(referedToType));
+ }
+ }
+
+ public partial class PointerTypeReference {
+
+ public static new PointerTypeReference Create (XmlReader pointerTo) {
+ if (pointerTo == null) throw new ArgumentNullException("pointerTo");
+ pointerTo.Read();
+ TypeReference pointedToType = TypeReference.Create(pointerTo);
+ return (new PointerTypeReference(pointedToType));
+ }
+
+ public static new PointerTypeReference Create (XPathNavigator pointerTo) {
+ XPathNavigator pointedToNode = pointerTo.SelectSingleNode("*[1]");
+ TypeReference pointedToType = TypeReference.Create(pointedToNode);
+ return (new PointerTypeReference(pointedToType));
+ }
+ }
+
+ public partial class ArrayTypeReference {
+
+ public static new ArrayTypeReference Create (XmlReader arrayOf) {
+ if (arrayOf == null) throw new ArgumentNullException("arrayOf");
+
+ int rank = 1;
+ string rankText = arrayOf.GetAttribute("rank");
+ if (!String.IsNullOrEmpty(rankText)) rank = Convert.ToInt32(rankText);
+
+ arrayOf.Read();
+ TypeReference elementType = TypeReference.Create(arrayOf);
+
+ return (new ArrayTypeReference(elementType, rank));
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveArtLinksComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveArtLinksComponent.cs
new file mode 100644
index 0000000..77d763d
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveArtLinksComponent.cs
@@ -0,0 +1,195 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class ResolveArtLinksComponent : BuildComponent {
+
+ public ResolveArtLinksComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNodeIterator targets_nodes = configuration.Select("targets");
+ foreach (XPathNavigator targets_node in targets_nodes) {
+
+ string input = targets_node.GetAttribute("input", String.Empty);
+ if (String.IsNullOrEmpty(input)) WriteMessage(MessageLevel.Error, "Each targets element must have an input attribute specifying a directory containing art files.");
+ input = Environment.ExpandEnvironmentVariables(input);
+ if (!Directory.Exists(input)) WriteMessage(MessageLevel.Error, String.Format("The art input directory '{0}' does not exist.", input));
+
+ string baseOutputPath = targets_node.GetAttribute("baseOutput", String.Empty);
+ if (!String.IsNullOrEmpty(baseOutputPath)) {
+ baseOutputPath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(baseOutputPath));
+ }
+
+ string outputPath_value = targets_node.GetAttribute("outputPath", string.Empty);
+ if (string.IsNullOrEmpty(outputPath_value)) WriteMessage(MessageLevel.Error, "Each targets element must have an output attribute specifying a directory in which to place referenced art files.");
+ XPathExpression output_XPath = XPathExpression.Compile(outputPath_value);
+
+ string linkValue = targets_node.GetAttribute("link", String.Empty);
+ if (String.IsNullOrEmpty(linkValue)) linkValue = "../art";
+ //linkValue = Environment.ExpandEnvironmentVariables(linkValue);
+
+ string map = targets_node.GetAttribute("map", String.Empty);
+ if (String.IsNullOrEmpty(map)) WriteMessage(MessageLevel.Error, "Each targets element must have a map attribute specifying a file that maps art ids to files in the input directory.");
+ map = Environment.ExpandEnvironmentVariables(map);
+ if (!File.Exists(map)) WriteMessage(MessageLevel.Error, String.Format("The art map file '{0}' does not exist.", map));
+
+ string format = targets_node.GetAttribute("format", String.Empty);
+ XPathExpression format_xpath = String.IsNullOrEmpty(format) ? null : XPathExpression.Compile(format);
+
+ string relative_to = targets_node.GetAttribute("relative-to", String.Empty);
+ XPathExpression relative_to_xpath = String.IsNullOrEmpty(relative_to) ? null : XPathExpression.Compile(relative_to);
+
+ AddTargets(map, input, baseOutputPath, output_XPath, linkValue, format_xpath, relative_to_xpath);
+
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Indexed {0} art targets.", targets.Count));
+
+ }
+
+ private void AddTargets (string map, string input, string baseOutputPath, XPathExpression outputXPath, string link, XPathExpression formatXPath, XPathExpression relativeToXPath) {
+
+ XPathDocument document = new XPathDocument(map);
+
+ XPathNodeIterator items = document.CreateNavigator().Select("/*/item");
+ foreach (XPathNavigator item in items) {
+
+ string id = (string) item.Evaluate(artIdExpression);
+ string file = (string) item.Evaluate(artFileExpression);
+ string text = (string) item.Evaluate(artTextExpression);
+
+ id = id.ToLower();
+ string name = Path.GetFileName(file);
+
+ ArtTarget target = new ArtTarget();
+ target.Id = id;
+ target.InputPath = Path.Combine(input, file);
+ target.baseOutputPath = baseOutputPath;
+ target.OutputXPath = outputXPath;
+
+ if (string.IsNullOrEmpty(name)) target.LinkPath = link;
+ else target.LinkPath = string.Format("{0}/{1}", link, name);
+
+ target.Text = text;
+ target.Name = name;
+ target.FormatXPath = formatXPath;
+ target.RelativeToXPath = relativeToXPath;
+
+ targets[id] = target;
+ // targets.Add(id, target);
+ }
+
+ }
+
+ private XPathExpression artIdExpression = XPathExpression.Compile("string(@id)");
+ private XPathExpression artFileExpression = XPathExpression.Compile("string(image/@file)");
+ private XPathExpression artTextExpression = XPathExpression.Compile("string(image/altText)");
+
+ private Dictionary<string,ArtTarget> targets = new Dictionary<string,ArtTarget>();
+
+ public override void Apply (XmlDocument document, string id) {
+
+ XPathNodeIterator artLinkIterator = document.CreateNavigator().Select(artLinkExpression);
+ XPathNavigator[] artLinks = BuildComponentUtilities.ConvertNodeIteratorToArray(artLinkIterator);
+ foreach (XPathNavigator artLink in artLinks) {
+
+ string name = artLink.GetAttribute("target", String.Empty).ToLower();
+
+ if (targets.ContainsKey(name)) {
+ ArtTarget target = targets[name];
+
+ // evaluate the path
+ string path = document.CreateNavigator().Evaluate(target.OutputXPath).ToString();
+
+ if (target.baseOutputPath != null) path = Path.Combine(target.baseOutputPath, path);
+ string outputPath = Path.Combine(path, target.Name);
+
+ string targetDirectory = Path.GetDirectoryName(outputPath);
+
+ if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory);
+
+ if (File.Exists(target.InputPath)) {
+
+ if (File.Exists(outputPath)) {
+ File.SetAttributes(outputPath, FileAttributes.Normal);
+ }
+
+ File.Copy(target.InputPath, outputPath, true);
+ } else {
+ WriteMessage(MessageLevel.Warn, String.Format("The file '{0}' for the art target '{1}' was not found.", target.InputPath, name));
+ }
+
+ // Get the relative art path for HXF generation.
+ int index = target.LinkPath.IndexOf('/');
+ string artPath = target.LinkPath.Substring(index+1, target.LinkPath.Length - (index+1));
+
+ FileCreatedEventArgs fe = new FileCreatedEventArgs(artPath, Path.GetDirectoryName(path));
+ OnComponentEvent(fe);
+
+ XmlWriter writer = artLink.InsertAfter();
+
+ writer.WriteStartElement("img");
+ if (!String.IsNullOrEmpty(target.Text)) writer.WriteAttributeString("alt", target.Text);
+
+ if (target.FormatXPath == null) {
+ writer.WriteAttributeString("src", target.LinkPath);
+ }
+ else {
+ // WebDocs way, which uses the 'format' xpath expression to calculate the target path
+ // and then makes it relative to the current page if the 'relative-to' attribute is
+ // used.
+ string src = BuildComponentUtilities.EvalXPathExpr(document, target.FormatXPath, "key", Path.GetFileName(outputPath));
+ if (target.RelativeToXPath != null)
+ src = BuildComponentUtilities.GetRelativePath(src, BuildComponentUtilities.EvalXPathExpr(document, target.RelativeToXPath, "key", id));
+ writer.WriteAttributeString("src", src);
+ }
+
+ writer.WriteEndElement();
+
+ writer.Close();
+
+ artLink.DeleteSelf();
+
+ } else {
+ WriteMessage(MessageLevel.Warn, String.Format("Unknown art target '{0}'", name));
+ }
+
+ }
+
+ }
+
+ private static XPathExpression artLinkExpression = XPathExpression.Compile("//artLink");
+
+ }
+
+ internal class ArtTarget {
+
+ public string Id;
+
+ public string InputPath;
+
+ public string baseOutputPath;
+
+ public XPathExpression OutputXPath;
+
+ public string LinkPath;
+
+ public string Text;
+
+ public string Name;
+
+ public XPathExpression FormatXPath;
+
+ public XPathExpression RelativeToXPath;
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveConceptualLinksComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveConceptualLinksComponent.cs
new file mode 100644
index 0000000..2531e23
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveConceptualLinksComponent.cs
@@ -0,0 +1,448 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using System.Text.RegularExpressions;
+using System.Web;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ public class ResolveConceptualLinksComponent : BuildComponent {
+
+ // Instantiation logic
+
+ public ResolveConceptualLinksComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ string showBrokenLinkTextValue = configuration.GetAttribute("showBrokenLinkText", String.Empty);
+ if (!String.IsNullOrEmpty(showBrokenLinkTextValue)) showBrokenLinkText = Convert.ToBoolean(showBrokenLinkTextValue);
+
+ XPathNodeIterator targetsNodes = configuration.Select("targets");
+ foreach (XPathNavigator targetsNode in targetsNodes) {
+
+ // the base directory containing target; required
+ string baseValue = targetsNode.GetAttribute("base", String.Empty);
+ if (String.IsNullOrEmpty(baseValue)) WriteMessage(MessageLevel.Error, "Every targets element must have a base attribute that specifies the path to a directory of target metadata files.");
+ baseValue = Environment.ExpandEnvironmentVariables(baseValue);
+ if (!Directory.Exists(baseValue)) WriteMessage(MessageLevel.Error, String.Format("The specified target metadata directory '{0}' does not exist.", baseValue));
+
+ // an xpath expression to construct a file name
+ // (not currently used; pattern is hard-coded to $target.cmp.xml
+ string filesValue = targetsNode.GetAttribute("files", String.Empty);
+
+ // an xpath expression to construct a url
+ string urlValue = targetsNode.GetAttribute("url", String.Empty);
+ XPathExpression urlExpression;
+ if (String.IsNullOrEmpty(urlValue)) {
+ urlExpression = XPathExpression.Compile("concat(/metadata/topic/@id,'.htm')");
+ } else {
+ urlExpression = CompileXPathExpression(urlValue);
+ }
+
+ // an xpath expression to construct link text
+ string textValue = targetsNode.GetAttribute("text", String.Empty);
+ XPathExpression textExpression;
+ if (String.IsNullOrEmpty(textValue)) {
+ textExpression = XPathExpression.Compile("string(/metadata/topic/title)");
+ } else {
+ textExpression = CompileXPathExpression(textValue);
+ }
+
+ // the type of link to create to targets found in the directory; required
+ string typeValue = targetsNode.GetAttribute("type", String.Empty);
+ if (String.IsNullOrEmpty(typeValue)) WriteMessage(MessageLevel.Error, "Every targets element must have a type attribute that specifies what kind of link to create to targets found in that directory.");
+
+ // convert the link type to an enumeration member
+ LinkType type = LinkType.None;
+ try {
+ type = (LinkType) Enum.Parse(typeof(LinkType), typeValue, true);
+ } catch (ArgumentException) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a valid link type.", typeValue));
+ }
+
+ // we have all the required information; create a TargetDirectory and add it to our collection
+ TargetDirectory targetDirectory = new TargetDirectory(baseValue, urlExpression, textExpression, type);
+ targetDirectories.Add(targetDirectory);
+
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Collected {0} targets directories.", targetDirectories.Count));
+
+ }
+
+ private XPathExpression CompileXPathExpression (string xpath) {
+ XPathExpression expression = null;
+ try {
+ expression = XPathExpression.Compile(xpath);
+ } catch (ArgumentException e) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a valid XPath expression. The error message is: {1}", xpath, e.Message));
+ } catch (XPathException e) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a valid XPath expression. The error message is: {1}", xpath, e.Message));
+ }
+ return (expression);
+ }
+
+ // Conceptual link resolution logic
+
+ public override void Apply (XmlDocument document, string key) {
+ ResolveConceptualLinks(document, key);
+ }
+
+ private bool showBrokenLinkText = false;
+
+ private string BrokenLinkDisplayText (string target, string text) {
+ if (showBrokenLinkText) {
+ return(String.Format("{0}", text));
+ } else {
+ return(String.Format("[{0}]", target));
+ }
+ }
+
+ private TargetDirectoryCollection targetDirectories = new TargetDirectoryCollection();
+
+ private static XPathExpression conceptualLinks = XPathExpression.Compile("//conceptualLink");
+
+ private static Regex validGuid = new Regex(@"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", RegexOptions.Compiled);
+
+ private void ResolveConceptualLinks (XmlDocument document, string key) {
+
+ // find links
+ XPathNodeIterator linkIterator = document.CreateNavigator().Select(conceptualLinks);
+
+ // copy them to an array, because enumerating through an XPathNodeIterator
+ // fails when the nodes in it are altered
+ XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);
+
+ foreach (XPathNavigator linkNode in linkNodes) {
+
+ ConceptualLinkInfo link = ConceptualLinkInfo.Create(linkNode);
+
+ // determine url, text, and link type
+ string url = null;
+ string text = null;
+ LinkType type = LinkType.None;
+ bool isValidLink = validGuid.IsMatch(link.Target);
+ if (isValidLink) {
+ // a valid link; try to fetch target info
+ TargetInfo target = GetTargetInfoFromCache(link.Target.ToLower());
+ if (target == null) {
+ // no target found; issue warning, set link style to none, and text to in-source fall-back
+ //type = LinkType.None;
+ type = LinkType.Index;
+ text = BrokenLinkDisplayText(link.Target, link.Text);
+ WriteMessage(MessageLevel.Warn, String.Format("Unknown conceptual link target '{0}'.", link.Target));
+ } else {
+ // found target; get url, text, and type from stored info
+ url = target.Url;
+ text = target.Text;
+ type = target.Type;
+ }
+ } else {
+ // not a valid link; issue warning, set link style to none, and text to invalid target
+ //type = LinkType.None;
+ type = LinkType.Index;
+ text = BrokenLinkDisplayText(link.Target, link.Text);
+ WriteMessage(MessageLevel.Warn, String.Format("Invalid conceptual link target '{0}'.", link.Target));
+ }
+
+ // write opening link tag and target info
+ XmlWriter writer = linkNode.InsertAfter();
+ switch (type) {
+ case LinkType.None:
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nolink");
+ break;
+ case LinkType.Local:
+ writer.WriteStartElement("a");
+ writer.WriteAttributeString("href", url);
+ break;
+ case LinkType.Index:
+ writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
+ writer.WriteAttributeString("keywords", link.Target.ToLower());
+ writer.WriteAttributeString("tabindex", "0");
+ break;
+ }
+
+ // write the link text
+ writer.WriteString(text);
+
+ // write the closing link tag
+ writer.WriteEndElement();
+ writer.Close();
+
+ // delete the original tag
+ linkNode.DeleteSelf();
+ }
+ }
+
+
+
+
+ // a simple caching system for target names
+
+ private TargetInfo GetTargetInfoFromCache (string target) {
+
+ TargetInfo info;
+ if (!cache.TryGetValue(target, out info)) {
+ info = targetDirectories.GetTargetInfo(target + ".cmp.xml");
+
+ if (cache.Count >= cacheSize) cache.Clear();
+
+ cache.Add(target, info);
+ }
+
+ return(info);
+
+ }
+
+ private static int cacheSize = 1000;
+
+ private Dictionary<string,TargetInfo> cache = new Dictionary<string,TargetInfo>(cacheSize);
+
+ //private CustomContext context = new CustomContext();
+
+ }
+
+ // different types of links
+
+ internal enum LinkType {
+ None, // not active
+ Local, // a href
+ Index // mshelp:link keyword
+ //Regex // regular expression with match/replace
+ }
+
+ // a representation of a targets directory, along with all the assoicated expressions used to
+ // find target metadat files in it, and extract urls and link text from those files
+
+ internal class TargetDirectory {
+
+ private string directory;
+
+ private XPathExpression fileExpression = XPathExpression.Compile("concat($target,'.cmp.htm')");
+
+ private XPathExpression urlExpression = XPathExpression.Compile("concat(/metadata/topic/@id,'.htm')");
+
+ private XPathExpression textExpression = XPathExpression.Compile("string(/metadata/topic/title)");
+
+ private LinkType type;
+
+ public string Directory {
+ get {
+ return (directory);
+ }
+ }
+
+ public XPathExpression UrlExpression {
+ get {
+ return (urlExpression);
+ }
+ }
+
+ public XPathExpression TextExpression {
+ get {
+ return (textExpression);
+ }
+ }
+
+
+ public LinkType LinkType {
+ get {
+ return (type);
+ }
+ }
+
+ public TargetDirectory (string directory, LinkType type) {
+ if (directory == null) throw new ArgumentNullException("directory");
+ this.directory = directory;
+ this.type = type;
+ }
+
+ public TargetDirectory (string directory, XPathExpression urlExpression, XPathExpression textExpression, LinkType type) {
+ if (directory == null) throw new ArgumentNullException("directory");
+ if (urlExpression == null) throw new ArgumentNullException("urlExpression");
+ if (textExpression == null) throw new ArgumentNullException("textExpression");
+ this.directory = directory;
+ this.urlExpression = urlExpression;
+ this.textExpression = textExpression;
+ this.type = type;
+ }
+
+ private XPathDocument GetDocument (string file) {
+ string path = Path.Combine(directory, file);
+ if (File.Exists(path)) {
+ XPathDocument document = new XPathDocument(path);
+ return (document);
+ } else {
+ return (null);
+ }
+ }
+
+ public TargetInfo GetTargetInfo (string file) {
+ XPathDocument document = GetDocument(file);
+ if (document == null) {
+ return(null);
+ } else {
+ XPathNavigator context = document.CreateNavigator();
+
+ string url = context.Evaluate(urlExpression).ToString();
+ string text = context.Evaluate(textExpression).ToString();
+ TargetInfo info = new TargetInfo(url, text, type);
+ return(info);
+ }
+ }
+
+ public TargetInfo GetTargetInfo (XPathNavigator linkNode, CustomContext context) {
+
+ // compute the metadata file name to open
+ XPathExpression localFileExpression = fileExpression.Clone();
+ localFileExpression.SetContext(context);
+ string file = linkNode.Evaluate(localFileExpression).ToString();
+ if (String.IsNullOrEmpty(file)) return (null);
+
+ // load the metadata file
+ XPathDocument metadataDocument = GetDocument(file);
+ if (metadataDocument == null) return (null);
+
+ // querry the metadata file for the target url and link text
+ XPathNavigator metadataNode = metadataDocument.CreateNavigator();
+ XPathExpression localUrlExpression = urlExpression.Clone();
+ localUrlExpression.SetContext(context);
+ string url = metadataNode.Evaluate(localUrlExpression).ToString();
+ XPathExpression localTextExpression = textExpression.Clone();
+ localTextExpression.SetContext(context);
+ string text = metadataNode.Evaluate(localTextExpression).ToString();
+
+ // return this information
+ TargetInfo info = new TargetInfo(url, text, type);
+ return (info);
+ }
+
+
+
+ }
+
+ // our collection of targets directories
+
+ internal class TargetDirectoryCollection {
+
+ public TargetDirectoryCollection() {}
+
+ private List<TargetDirectory> targetDirectories = new List<TargetDirectory>();
+
+ public int Count {
+ get {
+ return(targetDirectories.Count);
+ }
+ }
+
+ public void Add (TargetDirectory targetDirectory) {
+ targetDirectories.Add(targetDirectory);
+ }
+
+ public TargetInfo GetTargetInfo (string file) {
+ foreach (TargetDirectory targetDirectory in targetDirectories) {
+ TargetInfo info = targetDirectory.GetTargetInfo(file);
+ if (info != null) return (info);
+ }
+ return (null);
+ }
+
+ public TargetInfo GetTargetInfo (XPathNavigator linkNode, CustomContext context) {
+ foreach (TargetDirectory targetDirectory in targetDirectories) {
+ TargetInfo info = targetDirectory.GetTargetInfo(linkNode, context);
+ if (info != null) return (info);
+ }
+ return (null);
+ }
+
+ }
+
+ // a representation of a resolved target, containing all the information necessary to actually write out the link
+
+ internal class TargetInfo {
+
+ private string url;
+
+ private string text;
+
+ private LinkType type;
+
+ public string Url {
+ get {
+ return(url);
+ }
+ }
+
+ public string Text {
+ get {
+ return(text);
+ }
+ }
+
+ public LinkType Type {
+ get {
+ return(type);
+ }
+ }
+
+ internal TargetInfo (string url, string text, LinkType type) {
+ if (url == null) throw new ArgumentNullException("url");
+ if (text == null) throw new ArgumentNullException("url");
+ this.url = url;
+ this.text = text;
+ this.type = type;
+ }
+ }
+
+ // a representation of a conceptual link
+
+ internal class ConceptualLinkInfo {
+
+ private string target;
+
+ private string text;
+
+ private bool showText = false;
+
+ public string Target {
+ get {
+ return (target);
+ }
+ }
+
+ public string Text {
+ get {
+ return (text);
+ }
+ }
+
+ public bool ShowText {
+ get {
+ return (showText);
+ }
+ }
+
+ private ConceptualLinkInfo () { }
+
+ public static ConceptualLinkInfo Create (XPathNavigator node) {
+ if (node == null) throw new ArgumentNullException("node");
+
+ ConceptualLinkInfo info = new ConceptualLinkInfo();
+
+ info.target = node.GetAttribute("target", String.Empty);
+ info.text = node.ToString();
+
+ return(info);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveReferenceLinksComponent2.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveReferenceLinksComponent2.cs
new file mode 100644
index 0000000..22587ac
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ResolveReferenceLinksComponent2.cs
@@ -0,0 +1,497 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ // replace the old component with the new one
+ public class ResolveReferenceLinksComponent : ResolveReferenceLinksComponent2 {
+
+ public ResolveReferenceLinksComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) { }
+
+ }
+
+ public class ResolveReferenceLinksComponent2 : BuildComponent {
+
+ // instantiation logic
+
+ public ResolveReferenceLinksComponent2 (BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration) {
+
+ // base-url is an xpath expression applied against the current document to pick up the save location of the
+ // document. If specified, local links will be made relative to the base-url.
+ string baseUrlValue = configuration.GetAttribute("base-url", String.Empty);
+ if (!String.IsNullOrEmpty(baseUrlValue))
+ baseUrl = XPathExpression.Compile(baseUrlValue);
+
+ // url-format is a string format that is used to format the value of local href attributes. The default is
+ // "{0}.htm" for backwards compatibility.
+ string hrefFormatValue = configuration.GetAttribute("href-format", String.Empty);
+ if (!String.IsNullOrEmpty(hrefFormatValue))
+ hrefFormat = hrefFormatValue;
+
+ // the container XPath can be replaced; this is useful
+ string containerValue = configuration.GetAttribute("container", String.Empty);
+ if (!String.IsNullOrEmpty(containerValue)) XmlTargetCollectionUtilities.ContainerExpression = containerValue;
+
+ targets = new TargetCollection();
+ resolver = new LinkTextResolver(targets);
+
+ XPathNodeIterator targets_nodes = configuration.Select("targets");
+ foreach (XPathNavigator targets_node in targets_nodes) {
+
+ // get target type
+ string typeValue = targets_node.GetAttribute("type", String.Empty);
+ if (String.IsNullOrEmpty(typeValue)) WriteMessage(MessageLevel.Error, "Each targets element must have a type attribute that specifies which type of links to create.");
+
+ LinkType2 type = LinkType2.None;
+ try {
+ type = (LinkType2)Enum.Parse(typeof(LinkType2), typeValue, true);
+ if ((type == LinkType2.Msdn) && (msdn == null)) {
+ WriteMessage(MessageLevel.Info, "Creating MSDN URL resolver.");
+ msdn = new MsdnResolver();
+ }
+ } catch (ArgumentException) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a supported reference link type.", typeValue));
+ }
+
+ // get base directory
+ string baseValue = targets_node.GetAttribute("base", String.Empty);
+
+ // get file pattern
+ string filesValue = targets_node.GetAttribute("files", String.Empty);
+ if (String.IsNullOrEmpty(filesValue)) WriteMessage(MessageLevel.Error, "Each targets element must have a files attribute specifying which target files to load.");
+
+ // determine whether to search recursively
+ bool recurse = false;
+ string recurseValue = targets_node.GetAttribute("recurse", String.Empty);
+ if (!String.IsNullOrEmpty(recurseValue)) {
+ if (String.Compare(recurseValue, Boolean.TrueString, true) == 0) {
+ recurse = true;
+ } else if (String.Compare(recurseValue, Boolean.FalseString, true) == 0) {
+ recurse = false;
+ } else {
+ WriteMessage(MessageLevel.Error, String.Format("On the targets element, recurse='{0}' is not an allowed value.", recurseValue));
+ }
+ }
+
+ // turn baseValue and filesValue into directoryPath and filePattern
+ string fullPath;
+ if (String.IsNullOrEmpty(baseValue)) {
+ fullPath = filesValue;
+ } else {
+ fullPath = Path.Combine(baseValue, filesValue);
+ }
+ fullPath = Environment.ExpandEnvironmentVariables(fullPath);
+ string directoryPath = Path.GetDirectoryName(fullPath);
+ if (String.IsNullOrEmpty(directoryPath)) directoryPath = Environment.CurrentDirectory;
+ string filePattern = Path.GetFileName(fullPath);
+
+ // verify that directory exists
+ if (!Directory.Exists(directoryPath)) WriteMessage(MessageLevel.Error, String.Format("The targets directory '{0}' does not exist.", directoryPath));
+
+ // add the specified targets from the directory
+ WriteMessage(MessageLevel.Info, String.Format("Searching directory '{0}' for targets files of the form '{1}'.", directoryPath, filePattern));
+ AddTargets(directoryPath, filePattern, recurse, type);
+
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} reference targets.", targets.Count));
+
+ string locale_value = configuration.GetAttribute("locale", String.Empty);
+ if (!String.IsNullOrEmpty(locale_value) && msdn != null) msdn.Locale = locale_value;
+
+ string target_value = configuration.GetAttribute("linkTarget", String.Empty);
+ if (!String.IsNullOrEmpty(target_value)) linkTarget = target_value;
+ }
+
+ private void AddTargets (string directory, string filePattern, bool recurse, LinkType2 type) {
+ string[] files = Directory.GetFiles(directory, filePattern);
+ foreach (string file in files) {
+ AddTargets(file, type);
+ }
+ if (recurse) {
+ string[] subdirectories = Directory.GetDirectories(directory);
+ foreach (string subdirectory in subdirectories) {
+ AddTargets(subdirectory, filePattern, recurse, type);
+ }
+ }
+ }
+
+ private void AddTargets (string file, LinkType2 type) {
+ try {
+ XPathDocument document = new XPathDocument(file);
+ XmlTargetCollectionUtilities.AddTargets(targets, document.CreateNavigator(), type);
+ } catch (XmlSchemaException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The reference targets file '{0}' is not well-formed XML. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while opening the reference targets file '{0}'. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ }
+ }
+
+ private string linkTarget = "_blank";
+
+ // target information storage
+
+ private TargetCollection targets;
+
+ private LinkTextResolver resolver;
+
+ private static XPathExpression referenceLinkExpression = XPathExpression.Compile("//referenceLink");
+
+ // WebDocs target url formatting
+
+ private XPathExpression baseUrl;
+
+ private string hrefFormat = "{0}.htm";
+
+ // component logic
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // XmlNodeList link_nodes = document.SelectNodes("//referenceLink");
+ XPathNodeIterator linkIterator = document.CreateNavigator().Select(referenceLinkExpression);
+
+ XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(linkIterator);
+
+ foreach (XPathNavigator linkNode in linkNodes) {
+
+ // extract link information
+ ReferenceLinkInfo2 link = ReferenceLinkInfo2.Create(linkNode);
+
+ if (link == null) {
+ WriteMessage(MessageLevel.Warn, "Invalid referenceLink element.");
+ } else {
+
+ // determine target, link type, and display options
+ string targetId = link.Target;
+ DisplayOptions options = link.DisplayOptions;
+ LinkType2 type = LinkType2.None;
+
+ Target target = targets[targetId];
+ if (target == null) {
+ // no such target known; set link type to none and warn
+ type = LinkType2.None;
+ WriteMessage(MessageLevel.Warn, String.Format("Unknown reference link target '{0}'.", targetId));
+ } else {
+ // if overload is prefered and found, change targetId and make link options hide parameters
+ if (link.PreferOverload) {
+
+ bool isConversionOperator = false;
+
+ MethodTarget method = target as MethodTarget;
+ if (method != null) {
+ isConversionOperator = method.conversionOperator;
+ }
+
+ MemberTarget member = target as MemberTarget;
+
+ // if conversion operator is found, always link to individual topic.
+ if ((member != null) && (!String.IsNullOrEmpty(member.OverloadId)) && !isConversionOperator) {
+ Target overloadTarget = targets[member.OverloadId];
+ if (overloadTarget != null) {
+ target = overloadTarget;
+ targetId = overloadTarget.Id;
+ }
+ }
+
+ // if individual conversion operator is found, always display parameters.
+ if (isConversionOperator && member != null && (!string.IsNullOrEmpty(member.OverloadId))) {
+ options = options | DisplayOptions.ShowParameters;
+ } else {
+ options = options & ~DisplayOptions.ShowParameters;
+ }
+ }
+
+ // get stored link type
+ type = target.DefaultLinkType;
+
+ // if link type is local or index, determine which
+ if (type == LinkType2.LocalOrIndex) {
+ if ((key != null) && targets.Contains(key) && (target.Container == targets[key].Container)) {
+ type = LinkType2.Local;
+ } else {
+ type = LinkType2.Index;
+ }
+ }
+ }
+
+ // links to this page are not live
+ if (targetId == key) {
+ type = LinkType2.Self;
+ } else if ((target != null) && (key != null) && targets.Contains(key) && (target.File == targets[key].File)) {
+ type = LinkType2.Self;
+ }
+
+ // get msdn endpoint, if needed
+ string msdnUrl = null;
+ if (type == LinkType2.Msdn) {
+ if ((msdn == null) || (msdn.IsDisabled)) {
+ // no msdn resolver
+ } else {
+ msdnUrl = msdn.GetMsdnUrl(targetId);
+ if (String.IsNullOrEmpty(msdnUrl)) {
+ WriteMessage(MessageLevel.Warn, String.Format("MSDN URL not found for target '{0}'.", targetId));
+ }
+ }
+ if (String.IsNullOrEmpty(msdnUrl)) type = LinkType2.None;
+ }
+
+ // write opening link tag and target info
+ XmlWriter writer = linkNode.InsertAfter();
+ switch (type) {
+ case LinkType2.None:
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nolink");
+ break;
+ case LinkType2.Self:
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "selflink");
+ break;
+ case LinkType2.Local:
+ // format link with prefix and/or postfix
+ string href = String.Format(hrefFormat, target.File);
+
+ // make link relative, if we have a baseUrl
+ if (baseUrl != null)
+ href = BuildComponentUtilities.GetRelativePath(href, BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key));
+
+ writer.WriteStartElement("a");
+ writer.WriteAttributeString("href", href);
+ break;
+ case LinkType2.Index:
+ writer.WriteStartElement("mshelp", "link", "http://msdn.microsoft.com/mshelp");
+ writer.WriteAttributeString("keywords", targetId);
+ writer.WriteAttributeString("tabindex", "0");
+ break;
+ case LinkType2.Msdn:
+ writer.WriteStartElement("a");
+ writer.WriteAttributeString("href", msdnUrl);
+ writer.WriteAttributeString("target", linkTarget);
+ break;
+ }
+
+ // write the link text
+ if (String.IsNullOrEmpty(link.DisplayTarget)) {
+ if (link.Contents == null) {
+ if (target != null) {
+ resolver.WriteTarget(target, options, writer);
+ } else {
+ //Console.WriteLine("Attemting to create reference");
+ Reference reference = TextReferenceUtilities.CreateReference(targetId);
+ //Console.WriteLine("Returned");
+ if (reference is InvalidReference) WriteMessage(MessageLevel.Warn, String.Format("Invalid reference link target '{0}'.", targetId));
+ resolver.WriteReference(reference, options, writer);
+ }
+ } else {
+ // write contents to writer
+ link.Contents.WriteSubtree(writer);
+ }
+ } else {
+ //Console.WriteLine("Display target = {0}", link.DisplayTarget);
+ if ((String.Compare(link.DisplayTarget, "content", true) == 0) && (link.Contents != null)) {
+ // Use the contents as an XML representation of the display target
+
+ //Console.WriteLine(link.Contents.NodeType);
+ Reference reference = XmlTargetCollectionUtilities.CreateReference(link.Contents);
+ //Console.WriteLine(reference.GetType().FullName);
+ resolver.WriteReference(reference, options, writer);
+ } if ((String.Compare(link.DisplayTarget, "format", true) == 0) && (link.Contents != null)) {
+ // Use the contents as a format string for the display target
+
+ string format = link.Contents.OuterXml;
+ //Console.WriteLine("format = {0}", format);
+
+ string input = null;
+ StringWriter textStore = new StringWriter();
+ try {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.ConformanceLevel = ConformanceLevel.Fragment;
+
+ XmlWriter xmlStore = XmlWriter.Create(textStore, settings);
+ try {
+ if (target != null) {
+ resolver.WriteTarget(target, options, xmlStore);
+ } else {
+ Reference reference = TextReferenceUtilities.CreateReference(targetId);
+ resolver.WriteReference(reference, options, xmlStore);
+ }
+ } finally {
+ xmlStore.Close();
+ }
+ input = textStore.ToString();
+ } finally {
+ textStore.Close();
+ }
+ //Console.WriteLine("input = {0}", input);
+
+ string output = String.Format(format, input);
+ //Console.WriteLine("output = {0}", output);
+
+ XmlDocumentFragment fragment = document.CreateDocumentFragment();
+ fragment.InnerXml = output;
+ fragment.WriteTo(writer);
+
+ //writer.WriteRaw(output);
+ }
+ else if ((String.Compare(link.DisplayTarget, "extension", true) == 0) && (link.Contents != null))
+ {
+ Reference extMethodReference = XmlTargetCollectionUtilities.CreateExtensionMethodReference(link.Contents);
+ resolver.WriteReference(extMethodReference, options, writer);
+ } else {
+ // Use the display target value as a CER for the display target
+
+ TextReferenceUtilities.SetGenericContext(key);
+ Reference reference = TextReferenceUtilities.CreateReference(link.DisplayTarget);
+ //Console.WriteLine("Reference is {0}", reference.GetType().FullName);
+ resolver.WriteReference(reference, options, writer);
+ }
+ }
+
+ // write the closing link tag
+ writer.WriteEndElement();
+ writer.Close();
+ }
+
+ // delete the original tag
+ linkNode.DeleteSelf();
+
+ }
+
+ }
+
+ // msdn resolver
+
+ private MsdnResolver msdn = null;
+
+
+ }
+
+
+ internal class ReferenceLinkInfo2 {
+
+ // stored data
+
+ private string target;
+
+ private string displayTarget;
+
+ private DisplayOptions options = DisplayOptions.Default;
+
+ private bool preferOverload = false;
+
+ private XPathNavigator contents;
+
+ // data accessors
+
+ public string Target {
+ get {
+ return(target);
+ }
+ }
+
+ public string DisplayTarget {
+ get {
+ return(displayTarget);
+ }
+ }
+
+ public DisplayOptions DisplayOptions {
+ get {
+ return(options);
+ }
+ }
+
+ public bool PreferOverload {
+ get {
+ return(preferOverload);
+ }
+ }
+
+ public XPathNavigator Contents {
+ get {
+ return(contents);
+ }
+ }
+
+ // creation logic
+
+ private ReferenceLinkInfo2 () {}
+
+ public static ReferenceLinkInfo2 Create (XPathNavigator element) {
+ if (element == null) throw new ArgumentNullException("element");
+
+ ReferenceLinkInfo2 info = new ReferenceLinkInfo2();
+
+ info.target = element.GetAttribute("target", String.Empty);
+ if (String.IsNullOrEmpty(info.target)) return(null);
+
+ info.displayTarget = element.GetAttribute("display-target", String.Empty);
+
+ string showContainer = element.GetAttribute("show-container", String.Empty);
+ if (String.IsNullOrEmpty(showContainer)) showContainer = element.GetAttribute("qualified", String.Empty);
+ if (!String.IsNullOrEmpty(showContainer)) {
+ if (String.Compare(showContainer, Boolean.TrueString, true) == 0) {
+ info.options = info.options | DisplayOptions.ShowContainer;
+ } else if (String.Compare(showContainer, Boolean.FalseString, true) == 0) {
+ info.options = info.options & ~DisplayOptions.ShowContainer;
+ } else {
+ return(null);
+ }
+ }
+
+ string showTemplates = element.GetAttribute("show-templates", String.Empty);
+ if (!String.IsNullOrEmpty(showTemplates)) {
+ if (String.Compare(showTemplates, Boolean.TrueString, true) == 0) {
+ info.options = info.options | DisplayOptions.ShowTemplates;
+ } else if (String.Compare(showTemplates, Boolean.FalseString, true) == 0) {
+ info.options = info.options & ~DisplayOptions.ShowTemplates;
+ } else {
+ return(null);
+ }
+ }
+
+ string showParameters = element.GetAttribute("show-parameters", String.Empty);
+ if (!String.IsNullOrEmpty(showParameters)) {
+ if (String.Compare(showParameters, Boolean.TrueString, true) == 0) {
+ info.options = info.options | DisplayOptions.ShowParameters;
+ } else if (String.Compare(showParameters, Boolean.FalseString, true) == 0) {
+ info.options = info.options & ~DisplayOptions.ShowParameters;
+ } else {
+ return(null);
+ }
+ }
+
+
+ string preferOverload = element.GetAttribute("prefer-overload", String.Empty);
+ if (String.IsNullOrEmpty(preferOverload)) preferOverload = element.GetAttribute("auto-upgrade", String.Empty);
+ if (!String.IsNullOrEmpty(preferOverload)) {
+ if (String.Compare(preferOverload, Boolean.TrueString, true) == 0) {
+ info.preferOverload = true;
+ } else if (String.Compare(preferOverload, Boolean.FalseString, true) == 0) {
+ info.preferOverload = false;
+ } else {
+ return(null);
+ }
+ }
+
+ info.contents = element.Clone();
+ if (!info.contents.MoveToFirstChild()) info.contents = null;
+
+ return(info);
+ }
+
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SaveComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SaveComponent.cs
new file mode 100644
index 0000000..8b8fea9
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SaveComponent.cs
@@ -0,0 +1,149 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Configuration;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.IO;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class SaveComponent : BuildComponent {
+
+ private CustomContext context = new CustomContext();
+
+ private XPathExpression path_expression;
+
+ private XPathExpression select_expression;
+
+ private XmlWriterSettings settings = new XmlWriterSettings();
+
+ public SaveComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // load the target path format
+ XPathNavigator save_node = configuration.SelectSingleNode("save");
+ if (save_node == null) throw new ConfigurationErrorsException("When instantiating a save component, you must specify a the target file using the <save> element.");
+
+ string base_value = save_node.GetAttribute("base", String.Empty);
+ if (!String.IsNullOrEmpty(base_value)) {
+ basePath = Path.GetFullPath(Environment.ExpandEnvironmentVariables(base_value));
+ }
+
+ string path_value = save_node.GetAttribute("path", String.Empty);
+ if (String.IsNullOrEmpty(path_value)) WriteMessage(MessageLevel.Error, "Each save element must have a path attribute specifying an XPath that evaluates to the location to save the file.");
+ path_expression = XPathExpression.Compile(path_value);
+
+ string select_value = save_node.GetAttribute("select", String.Empty);
+ if (!String.IsNullOrEmpty(select_value))
+ select_expression = XPathExpression.Compile(select_value);
+
+ settings.Encoding = Encoding.UTF8;
+
+ string indent_value = save_node.GetAttribute("indent", String.Empty);
+ if (!String.IsNullOrEmpty(indent_value)) settings.Indent = Convert.ToBoolean(indent_value);
+
+ string omit_value = save_node.GetAttribute("omit-xml-declaration", String.Empty);
+ if (!String.IsNullOrEmpty(omit_value)) settings.OmitXmlDeclaration = Convert.ToBoolean(omit_value);
+
+ linkPath = save_node.GetAttribute("link", String.Empty);
+ if (String.IsNullOrEmpty(linkPath)) linkPath = "../html";
+
+ // encoding
+
+ settings.CloseOutput = true;
+
+ }
+
+ private string basePath = null;
+
+ private string linkPath = null;
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // set the evaluation context
+ context["key"] = key;
+
+ XPathExpression path_xpath = path_expression.Clone();
+ path_xpath.SetContext(context);
+
+ // evaluate the path
+ string path = document.CreateNavigator().Evaluate(path_xpath).ToString();
+ string file = Path.GetFileName(path);
+
+ string fileLinkPath = Path.Combine(linkPath, file);
+ if (basePath != null) path = Path.Combine(basePath, path);
+
+
+ // *SECURIY* The path name may be derived from user entered meta data in Doc Studio and as such
+ // it is not trustworthy. To pass, the path must be inside the directory tree base_directory
+ // (which is the current directory if a path is not specified).
+
+ // This test is causing problems
+ /*
+ string absoluteBasePath = (basePath == null) ? Directory.GetCurrentDirectory() : Path.GetFullPath(basePath);
+ string targetPath = Path.GetDirectoryName(path);
+ if (!targetPath.StartsWith(absoluteBasePath, StringComparison.CurrentCultureIgnoreCase)) {
+ WriteMessage(MessageLevel.Error, string.Format("Cannot save document outside of base directory: {0}", targetPath));
+ return;
+ }
+ */
+ string targetDirectory = Path.GetDirectoryName(path);
+ if (!Directory.Exists(targetDirectory)) Directory.CreateDirectory(targetDirectory);
+
+ // save the document
+ // select_expression determines which nodes get saved. If there is no select_expression
+ // we simply save the root node as before. If there is a select_expression, we evaluate the
+ // xpath expression and save the resulting node set. The select expression also enables the
+ // "literal-text" processing instruction, which outputs its content as unescaped text.
+ if (select_expression == null) {
+ XmlNode doctype = document.DocumentType;
+ try {
+ //Console.WriteLine("path = '{0}'", path);
+ //document.Save(path);
+
+ using (XmlWriter writer = XmlWriter.Create(path, settings)) {
+ document.Save(writer);
+ }
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An access error occured while attempting to save to the file '{0}'. The error message is: {1}", path, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("Invalid XML was written to the output file '{0}'. The error message is: '{1}'", path, BuildComponentUtilities.GetExceptionMessage(e)));
+ }
+
+ // Get the relative html path for HXF generation.
+ int index = fileLinkPath.IndexOf('/');
+ string htmlPath = fileLinkPath.Substring(index + 1, fileLinkPath.Length - (index + 1));
+
+ FileCreatedEventArgs fe = new FileCreatedEventArgs(htmlPath, Path.GetDirectoryName(targetDirectory));
+ OnComponentEvent(fe);
+ }
+ else {
+ // IMPLEMENTATION NOTE: The separate StreamWriter is used to maintain XML indenting.
+ // Without it the XmlWriter won't honor our indent settings after plain text nodes have been
+ // written.
+ settings.ConformanceLevel = ConformanceLevel.Auto;
+ using (StreamWriter output = File.CreateText(path)) {
+ using (XmlWriter writer = XmlWriter.Create(output, settings)) {
+ XPathExpression select_xpath = select_expression.Clone();
+ select_xpath.SetContext(context);
+ XPathNodeIterator ni = document.CreateNavigator().Select(select_expression);
+ while (ni.MoveNext()) {
+ if (ni.Current.NodeType == XPathNodeType.ProcessingInstruction && ni.Current.Name.Equals("literal-text")) {
+ writer.Flush();
+ output.Write(ni.Current.Value);
+ }
+ else
+ ni.Current.WriteSubtree(writer);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SharedContentComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SharedContentComponent.cs
new file mode 100644
index 0000000..2a255fc
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SharedContentComponent.cs
@@ -0,0 +1,380 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Schema;
+
+// still have problems with spaces
+
+namespace Microsoft.Ddue.Tools {
+
+ public class SharedContentComponent : BuildComponent {
+
+ public SharedContentComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // get context
+ context = GetContext(configuration);
+
+ // get the tags to be resolved
+ XPathNodeIterator resolve_nodes = configuration.Select("replace");
+ foreach (XPathNavigator resolve_node in resolve_nodes) {
+ string path = resolve_node.GetAttribute("elements", String.Empty);
+ if (String.IsNullOrEmpty(path)) path = "//(include|includeAttribute)";
+ // if (String.IsNullOrEmpty(path)) WriteMessage(MessageLevel.Error, "Each resolve element must contain a path attribute specifying an XPath expression for shared content elements.");
+ try {
+ XPathExpression path_expresion = XPathExpression.Compile(path, context);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The elements expression '{0}' is not a valid XPath.", path));
+ }
+
+ string item = resolve_node.GetAttribute("item", String.Empty);
+ if (String.IsNullOrEmpty(item)) item = "string(@item)";
+ try {
+ XPathExpression item_expression = XPathExpression.Compile(item, context);
+ } catch (XPathException) {
+ WriteMessage(MessageLevel.Error, String.Format("The item expression '{0}' is not a valid XPath.", item));
+ }
+
+ string parameters = resolve_node.GetAttribute("parameters", String.Empty);
+ if (String.IsNullOrEmpty(parameters)) parameters = "parameter";
+
+ string attribute = resolve_node.GetAttribute("attribute", String.Empty);
+ if (String.IsNullOrEmpty(attribute)) attribute = "string(@name)";
+
+ elements.Add( new SharedContentElement(path, item, parameters, attribute, context) );
+ }
+
+ // Console.WriteLine("{0} elements explicitly defined", elements.Count);
+
+ if (elements.Count == 0) elements.Add( new SharedContentElement(@"//include | //includeAttribute", "string(@item)", "parameter", "string(@name)", context) );
+
+ // get the source and target formats
+ XPathNodeIterator content_nodes = configuration.Select("content");
+ foreach (XPathNavigator content_node in content_nodes)
+ {
+ // get the files
+ string sharedContentFiles = content_node.GetAttribute("file", String.Empty);
+ if (String.IsNullOrEmpty(sharedContentFiles))
+ WriteMessage(MessageLevel.Error, "The content/@file attribute must specify a path.");
+ ParseDocuments(sharedContentFiles);
+ }
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} shared content items.", content.Count));
+ }
+
+ public void ParseDocuments(string wildcardPath)
+ {
+ string sharedContentFiles = Environment.ExpandEnvironmentVariables(wildcardPath);
+ if (String.IsNullOrEmpty(sharedContentFiles))
+ WriteMessage(MessageLevel.Error, "The content/@file attribute specifies an empty string.");
+
+ WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", sharedContentFiles));
+ string directoryPart = Path.GetDirectoryName(sharedContentFiles);
+ if (String.IsNullOrEmpty(directoryPart))
+ directoryPart = Environment.CurrentDirectory;
+ directoryPart = Path.GetFullPath(directoryPart);
+ string filePart = Path.GetFileName(sharedContentFiles);
+ string[] files = Directory.GetFiles(directoryPart, filePart);
+ foreach (string file in files)
+ LoadContent(file);
+ WriteMessage(MessageLevel.Info, String.Format("Found {0} files in {1}.", files.Length, sharedContentFiles));
+ }
+
+ private void LoadContent(string file)
+ {
+
+ WriteMessage(MessageLevel.Info, String.Format("Loading shared content file '{0}'.", file) );
+
+ try {
+ XmlReader reader = XmlReader.Create(file);
+
+ try {
+ reader.MoveToContent();
+ while (!reader.EOF) {
+
+ if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "item")) {
+
+ string key = reader.GetAttribute("id").ToLower();
+ string value = reader.ReadInnerXml();
+
+ if (content.ContainsKey(key)) WriteMessage(MessageLevel.Info, String.Format("Overriding shared content item '{0}' with value in file '{1}'.", key, file));
+ content[key] = value;
+ // content.Add(key, value);
+ } else {
+ reader.Read();
+ }
+
+ }
+ } finally {
+ reader.Close();
+ }
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' could not be opened. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' is not well-formed. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XmlSchemaException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The shared content file '{0}' is not valid. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ }
+
+ }
+
+ private void DetectLoops () {
+
+ }
+
+ // Stored data
+
+ // The context
+ private CustomContext context = new CustomContext();
+
+ // The shared content items
+ private Dictionary<string,string> content = new Dictionary<string,string>();
+
+ // THe shared content elements
+ private List<SharedContentElement> elements = new List<SharedContentElement>();
+
+ public override void Apply (XmlDocument document, string key) {
+ ResolveContent(document);
+ }
+
+ // private XPathExpression expression = XPathExpression.Compile("//include | //includeAttribute");
+
+ private void ResolveContent (XmlDocument document) {
+ //Console.WriteLine("doc={0}", document.CreateNavigator().InnerXml);
+ ResolveContent(document, document.CreateNavigator());
+ }
+
+ private void ResolveContent (XmlDocument document, XPathNavigator start) {
+
+ // for each kind of shared content element
+ foreach (SharedContentElement element in elements) {
+
+ // find all such elements
+ XPathNodeIterator nodeIterator = start.Select(element.Path);
+ // Console.WriteLine("Found {0} shared content elements.", nodeIterator.Count);
+
+ // convert to an array so as not to cause an error when manipulating the document
+ XPathNavigator[] nodes = ConvertIteratorToArray(nodeIterator);
+
+ // process each element
+ foreach (XPathNavigator node in nodes) {
+
+ // Console.WriteLine(node.LocalName);
+
+ // get the key
+ string item = node.Evaluate(element.Item).ToString().ToLower();
+
+ // check for missing key
+ if (String.IsNullOrEmpty(item)) {
+ WriteMessage(MessageLevel.Warn, "A shared content element did not specify an item.");
+ } else {
+
+ // Console.WriteLine("node={0}", node.OuterXml);
+
+ // extract parameters
+ List<string> parameters = new List<string>();
+ XPathNodeIterator parameter_nodes = node.Select(element.Parameters);
+ foreach (XPathNavigator parameter_node in parameter_nodes) {
+ string parameter = BuildComponentUtilities.GetInnerXml(parameter_node);
+ // Console.WriteLine("parameter={0}", parameter);
+ parameters.Add(parameter);
+ }
+
+ // get the content
+ string content = GetContent(item, parameters.ToArray());
+
+ // check for missing content
+ if (content == null) {
+ WriteMessage(MessageLevel.Warn, String.Format("Missing shared content item. Tag:'{0}'; Id:'{1}'.", node.LocalName, item));
+ } else {
+
+ // store the content in a document fragment
+ XmlDocumentFragment fragment = document.CreateDocumentFragment();
+ fragment.InnerXml = content;
+
+ // resolve any shared content in the fragment
+ ResolveContent(document, fragment.CreateNavigator());
+ //string resolvedContent = fragment.InnerXml;
+ //Console.WriteLine("value = '{0}'", resolvedContent);
+
+ // look for an attribute name
+ string attribute = node.Evaluate(element.Attribute).ToString();
+
+ // insert the resolved content
+ if (String.IsNullOrEmpty(attribute)) {
+ // as mixed content
+ // node.InsertAfter(resolvedContent);
+ XmlWriter writer = node.InsertAfter();
+ fragment.WriteTo(writer);
+ writer.Close();
+ } else {
+ // as an attribute
+ XPathNavigator parent = node.CreateNavigator();
+ parent.MoveToParent();
+ parent.CreateAttribute(String.Empty, attribute, String.Empty, fragment.InnerText);
+ }
+
+ }
+
+
+ }
+
+ // keep a reference to the parent element
+ XPathNavigator parentElement = node.CreateNavigator();
+ parentElement.MoveToParent();
+
+ // remove the node
+ node.DeleteSelf();
+
+ // if there is no content left in the parent element, make sure it is self-closing
+ if (!parentElement.HasChildren && !parentElement.IsEmptyElement) {
+
+ //If 'node' was already the root then we will have a blank node now and
+ //doing an InsertAfter() will throw an exception.
+ if (parentElement.Name.Length > 0)
+ {
+ // create a new element
+ XmlWriter attributeWriter = parentElement.InsertAfter();
+ attributeWriter.WriteStartElement(parentElement.Prefix, parentElement.LocalName, parentElement.NamespaceURI);
+
+ // copy attributes to it
+ XmlReader attributeReader = parentElement.ReadSubtree();
+ attributeReader.Read();
+ attributeWriter.WriteAttributes(attributeReader, false);
+ attributeReader.Close();
+
+ // close it
+ attributeWriter.WriteEndElement();
+ attributeWriter.Close();
+
+ // delete the old element
+ parentElement.DeleteSelf();
+ }
+ else
+ {
+ //if we are inside a tag such as title, removing the content will make it in the
+ //form of <title /> which is not allowed in html.
+ //Since this usually means there is a problem with the shared content or the transforms
+ //leading up to this we will just report the error here.
+ WriteMessage(MessageLevel.Error, "Error replacing item.");
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+ // look up shared content
+ private string GetContent (string key, string[] parameters) {
+
+ string value;
+ if (content.TryGetValue(key, out value)) {
+ try {
+ value = String.Format(value, parameters);
+ } catch (FormatException) {
+ WriteMessage(MessageLevel.Error, String.Format("The shared content item '{0}' could not be formatted with {1} parameters.", key, parameters.Length));
+ }
+
+ return(value);
+ } else {
+ return(null);
+ }
+
+ }
+
+ private static XPathNavigator[] ConvertIteratorToArray (XPathNodeIterator iterator) {
+ XPathNavigator[] result = new XPathNavigator[iterator.Count];
+ for (int i=0; i<result.Length; i++) {
+ iterator.MoveNext();
+ result[i] = iterator.Current.Clone();
+ }
+ return(result);
+ }
+
+ private static CustomContext GetContext (XPathNavigator configuration) {
+
+ CustomContext context = new CustomContext();
+
+ XPathNodeIterator context_nodes = configuration.Select("context");
+ foreach (XPathNavigator context_node in context_nodes) {
+ string prefix = context_node.GetAttribute("prefix", String.Empty);
+ string name = context_node.GetAttribute("name", String.Empty);
+ context.AddNamespace(prefix, name);
+ }
+
+ return(context);
+
+ }
+
+ }
+
+ internal class SharedContentElement {
+
+ public SharedContentElement (string path, string item, string parameters, string attribute, IXmlNamespaceResolver context) {
+ this.path = XPathExpression.Compile(path, context);
+ this.item = XPathExpression.Compile(item, context);
+ this.parameters = XPathExpression.Compile(parameters, context);
+ this.attribute = XPathExpression.Compile(attribute, context);
+ }
+
+
+
+ public SharedContentElement (string path, string item, string parameters, string attribute) {
+ this.path = XPathExpression.Compile(path);
+ this.item = XPathExpression.Compile(item);
+ this.parameters = XPathExpression.Compile(parameters);
+ if (attribute != null) {
+ this.attribute = XPathExpression.Compile(attribute);
+ }
+ }
+
+ private XPathExpression path;
+
+ private XPathExpression item;
+
+ private XPathExpression parameters;
+
+ private XPathExpression attribute;
+
+ public XPathExpression Path {
+ get {
+ return(path);
+ }
+ }
+
+ public XPathExpression Item {
+ get {
+ return(item);
+ }
+ }
+
+ public XPathExpression Parameters {
+ get {
+ return(parameters);
+ }
+ }
+
+ public XPathExpression Attribute {
+ get {
+ return(attribute);
+ }
+ }
+
+ public bool IsAttribute {
+ get {
+ return(attribute != null);
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SnippetComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SnippetComponent.cs
new file mode 100644
index 0000000..d4a3d68
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SnippetComponent.cs
@@ -0,0 +1,1223 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// <summary>Contains code to insert snippets directly from the source files without using any
+// intermediate XML files.
+// </summary>
+namespace Microsoft.Ddue.Tools
+{
+ using System;
+ using System.Configuration;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Text;
+ using System.Text.RegularExpressions;
+ using System.Xml;
+ using System.Xml.XPath;
+ using System.Globalization;
+ using System.Diagnostics;
+
+ /// <summary>
+ /// SnippetComponent class to replace the snippet code references.
+ /// </summary>
+ public class SnippetComponent : BuildComponent
+ {
+ #region Private members
+ /// <summary>
+ /// Regex to validate the snippet references.
+ /// </summary>
+ private static Regex validSnippetReference = new Regex(
+ @"^[^#\a\b\f\n\r\t\v]+#(\w+,)*\w+$",
+ RegexOptions.Compiled);
+
+ /// <summary>
+ /// Dictionary to map language folder names to language id.
+ /// </summary>
+ private static Dictionary<string, string> languageMap = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
+
+ /// <summary>
+ /// List that controls the order in which languages snippets are displayed.
+ /// </summary>
+ private static List<string> languageList = new List<string>();
+
+ /// <summary>
+ /// Dictionary consisting of example name as key and example path as value.
+ /// </summary>
+ private Dictionary<string, string> exampleIndex = new Dictionary<string, string>();
+
+ /// <summary>
+ /// Dictionary consisting of exampleName\unitName as key with a null value.
+ /// </summary>
+ private Dictionary<string, string> approvedSnippetIndex = new Dictionary<string,string>();
+
+ /// <summary>
+ /// Dictionary containing the example name as key and list of rejected language snippets as values.
+ /// </summary>
+ private Dictionary<string, List<string>> rejectedSnippetIndex = new Dictionary<string, List<string>>();
+
+ /// <summary>
+ /// List of unit folder names to exclude from sample parsing.
+ /// </summary>
+ private Dictionary<string, Object> excludedUnits = new Dictionary<string, Object>();
+
+ /// <summary>
+ /// Dictionary consisting of exampleName\unitName as key with a null value.
+ /// </summary>
+ private SnippetCache snippetCache = null;
+
+ /// <summary>
+ /// XPathExpression to look for snippet references in the topics.
+ /// </summary>
+ private XPathExpression selector;
+
+ /// <summary>
+ /// XmlNamespaceManager to set the context.
+ /// </summary>
+ private XmlNamespaceManager context = new CustomContext();
+
+ /// <summary>
+ /// List of languages.
+ /// </summary>
+ private List<Language> languages = new List<Language>();
+
+ /// <summary>
+ /// snippet store.
+ /// </summary>
+ private Dictionary<SnippetIdentifier, List<Snippet>> snippets = new Dictionary<SnippetIdentifier, List<Snippet>>();
+ #endregion
+
+ #region Constructor
+
+ /// <summary>
+ /// Constructor for SnippetComponent class.
+ /// </summary>
+ /// <param name="assembler">An instance of Build Assembler</param>
+ /// <param name="configuration">configuration to be parsed for information related to snippets</param>
+ public SnippetComponent(BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration)
+ {
+ Debug.Assert(assembler != null);
+ Debug.Assert(configuration != null);
+
+ // Get the parsnip examples location.
+ XPathNodeIterator examplesNode = configuration.Select("examples/example");
+
+ if (examplesNode.Count == 0)
+ WriteMessage(MessageLevel.Error, "Each snippet component element must have a child element named 'examples' containing an element named 'example' with an attribute named 'directory', whose value is a path to the directory containing examples.");
+
+ foreach (XPathNavigator exampleNode in examplesNode)
+ {
+ string rootDirectory = exampleNode.GetAttribute("directory", string.Empty);
+
+ if (string.IsNullOrEmpty(rootDirectory))
+ WriteMessage(MessageLevel.Error, "Each examples element must have a directory attribute specifying a directory containing parsnip samples.");
+
+ rootDirectory = Environment.ExpandEnvironmentVariables(rootDirectory);
+ if (!Directory.Exists(rootDirectory))
+ WriteMessage(MessageLevel.Error, String.Format("The examples/@directory attribute specified a directory that doesn't exist: '{0}'", rootDirectory));
+
+ // create a dictionary that maps the example names to the example path under the root directory
+ this.loadExamples(rootDirectory);
+ }
+
+ // Get the approved log files location.
+ XPathNodeIterator approvedSnippetsNode = configuration.Select("approvalLogs/approvalLog");
+
+ if (approvedSnippetsNode.Count == 0)
+ WriteMessage(MessageLevel.Warn, "The config did not have an 'approvalLogs' node to specify a snippet approval logs.");
+
+ foreach (XPathNavigator node in approvedSnippetsNode)
+ {
+ string approvalLogFile = node.GetAttribute("file", string.Empty);
+
+ if (string.IsNullOrEmpty(approvalLogFile))
+ WriteMessage(MessageLevel.Error, "The approvalLog node must have a 'file' attribute specifying the path to a snippet approval log.");
+
+ approvalLogFile = Environment.ExpandEnvironmentVariables(approvalLogFile);
+ if (!File.Exists(approvalLogFile))
+ WriteMessage(MessageLevel.Error, String.Format("The approvalLog/@file attribute specified a file that doesn't exist: '{0}'", approvalLogFile));
+
+ // load the approval log into the approvedSnippetIndex dictionary
+ this.parseApprovalLogFiles(approvalLogFile);
+ }
+
+ // Get the names of the unit directories in the sample tree to exclude from parsing
+ // <excludedUnits><unitFolder name="CPP_OLD" /></excludedUnits>
+ XPathNodeIterator excludedUnitNodes = configuration.Select("excludedUnits/unitFolder");
+ foreach (XPathNavigator unitFolder in excludedUnitNodes)
+ {
+ string folderName = unitFolder.GetAttribute("name", string.Empty);
+
+ if (string.IsNullOrEmpty(folderName))
+ WriteMessage(MessageLevel.Error, "Each excludedUnits/unitFolder node must have a 'name' attribute specifying the name of a folder name to exclude.");
+
+ folderName = Environment.ExpandEnvironmentVariables(folderName);
+
+ // add the folderName to the list of names to be excluded
+ this.excludedUnits.Add(folderName.ToLower(),null);
+ }
+
+ // Get the languages defined.
+ XPathNodeIterator languageNodes = configuration.Select("languages/language");
+ foreach (XPathNavigator languageNode in languageNodes)
+ {
+ // read the @languageId, @unit, and @extension attributes
+ string languageId = languageNode.GetAttribute("languageId", string.Empty);
+ if (string.IsNullOrEmpty(languageId))
+ WriteMessage(MessageLevel.Error, "Each language node must specify an @languageId attribute.");
+
+ string unit = languageNode.GetAttribute("unit", string.Empty);
+
+ // if both @languageId and @unit are specified, add this language to the language map
+ if (!string.IsNullOrEmpty(unit))
+ languageMap.Add(unit.ToLower(), languageId);
+
+ // add languageId to the languageList for purpose of ordering snippets in the output
+ if (!languageList.Contains(languageId))
+ languageList.Add(languageId.ToLower());
+
+ string extension = languageNode.GetAttribute("extension", string.Empty);
+ if (!string.IsNullOrEmpty(extension))
+ {
+ if (!extension.Contains("."))
+ {
+ extension = "." + extension;
+ WriteMessage(MessageLevel.Warn, String.Format("The @extension value must begin with a period. Adding a period to the extension value '{0}' of the {1} language.", extension, languageId));
+ }
+ else
+ {
+ int indexOfPeriod = extension.IndexOf('.');
+ if (indexOfPeriod != 0)
+ {
+ extension = extension.Substring(indexOfPeriod);
+ WriteMessage(MessageLevel.Warn, String.Format("The @extension value must begin with a period. Using the substring beginning with the first period of the specified extension value '{0}' of the {1} language.", extension, languageId));
+ }
+ }
+ }
+
+ // read the color nodes, if any, and add them to the list of colorization rules
+ List<ColorizationRule> rules = new List<ColorizationRule>();
+
+ XPathNodeIterator colorNodes = languageNode.Select("color");
+ foreach (XPathNavigator colorNode in colorNodes)
+ {
+ string pattern = colorNode.GetAttribute("pattern", String.Empty);
+ string region = colorNode.GetAttribute("region", String.Empty);
+ string name = colorNode.GetAttribute("class", String.Empty);
+ if (String.IsNullOrEmpty(region))
+ {
+ rules.Add(new ColorizationRule(pattern, name));
+ }
+ else
+ {
+ rules.Add(new ColorizationRule(pattern, region, name));
+ }
+ }
+
+ this.languages.Add(new Language(languageId, extension, rules));
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} colorization rules for the language '{1}', extension '{2}.", rules.Count, languageId, extension));
+ }
+
+ this.context.AddNamespace("ddue", "http://ddue.schemas.microsoft.com/authoring/2003/5");
+ this.selector = XPathExpression.Compile("//ddue:codeReference");
+ this.selector.SetContext(this.context);
+
+ // create the snippet cache
+ snippetCache = new SnippetCache(100, approvedSnippetIndex, languageMap, languages, excludedUnits);
+ }
+ #endregion
+
+ #region Public methods
+ /// <summary>
+ /// Apply method to perform the actual work of the component.
+ /// </summary>
+ /// <param name="document">document to be parsed for snippet references</param>
+ /// <param name="key">Id of a topic</param>
+ public override void Apply(XmlDocument document, string key)
+ {
+ // clear out the snippets dictionary of any snippets from the previous document
+ snippets.Clear();
+
+ XPathNodeIterator nodesIterator = document.CreateNavigator().Select(this.selector);
+ XPathNavigator[] nodes = BuildComponentUtilities.ConvertNodeIteratorToArray(nodesIterator);
+ foreach (XPathNavigator node in nodes)
+ {
+ // get the snippet reference, which can contain one or more snippet ids
+ string reference = node.Value;
+
+ // check for validity of reference
+ if (!validSnippetReference.IsMatch(reference))
+ {
+ WriteMessage(MessageLevel.Warn, "Skipping invalid snippet reference: " + reference);
+ continue;
+ }
+
+ // get the identifiers from the codeReference
+ SnippetIdentifier[] identifiers = SnippetIdentifier.ParseReference(reference);
+
+ // load the language-specific snippets for each of the specified identifiers
+ foreach (SnippetIdentifier identifier in identifiers)
+ {
+ if (snippets.ContainsKey(identifier))
+ continue;
+
+ // look up the snippets example path
+ string examplePath = string.Empty;
+ if (!this.exampleIndex.TryGetValue(identifier.Example, out examplePath))
+ {
+ WriteMessage(MessageLevel.Warn, String.Format("Snippet with identifier '{0}' was not found. The '{1}' example was not found in the examples directory.", identifier.ToString(), identifier.Example));
+ continue;
+ }
+
+ // get the snippet from the snippet cache
+ List<Snippet> snippetList = snippetCache.GetContent(examplePath, identifier);
+ if (snippetList != null)
+ {
+ snippets.Add(identifier, snippetList);
+ }
+ else
+ {
+ // if no approval log was specified in the config, all snippets are treated as approved by default
+ // so show an warning message that the snippet was not found
+ if (approvedSnippetIndex.Count == 0)
+ WriteMessage(MessageLevel.Warn, string.Format("No Snippet with identifier '{0}' was found.", identifier.ToString()));
+ else
+ {
+ // show a warning message: either snippet not found, or snippet not approved.
+ bool isApproved = false;
+
+ foreach (string snippetIndex in this.approvedSnippetIndex.Keys)
+ {
+ string[] splitSnippet = snippetIndex.Split('\\');
+ if (splitSnippet[0] == identifier.Example)
+ {
+ isApproved = true;
+ break;
+ }
+ }
+
+ // check whether snippets are present in parsnip approval logs and throw warnings accordingly.
+ if (!isApproved || !rejectedSnippetIndex.ContainsKey(identifier.Example))
+ WriteMessage(MessageLevel.Warn, string.Format("The snippet with identifier '{0}' was omitted because it is not present in parsnip approval logs.", identifier.ToString()));
+ else
+ WriteMessage(MessageLevel.Warn, string.Format("No Snippet with identifier '{0}' was found.", identifier.ToString()));
+ }
+
+ continue;
+ }
+
+ // write warning messages for any rejected units for this example
+ List<string> rejectedUnits;
+ if (rejectedSnippetIndex.TryGetValue(identifier.Example, out rejectedUnits))
+ {
+ foreach (string rejectedUnit in rejectedUnits)
+ WriteMessage(MessageLevel.Warn, string.Format("The '{0}' snippet with identifier '{1}' was omitted because the {2}\\{0} unit did not pass Parsnip testing.", rejectedUnit, identifier.ToString(), identifier.Example));
+ }
+ }
+
+ if (identifiers.Length == 1)
+ {
+ // one snippet referenced
+ SnippetIdentifier identifier = identifiers[0];
+
+ if (snippets.ContainsKey(identifier))
+ {
+ writeSnippetContent(node, identifier, snippets[identifier]);
+ }
+ }
+ else
+ {
+ // handle case where codeReference contains multiple identifiers
+ // Each language's set of snippets from multiple identifiers are displayed in a single block;
+
+ // create dictionary that maps each language to its set of snippets
+ Dictionary<string, List<Snippet>> map = new Dictionary<string, List<Snippet>>();
+ foreach (SnippetIdentifier identifier in identifiers)
+ {
+ List<Snippet> values;
+ if (snippets.TryGetValue(identifier, out values))
+ {
+ foreach (Snippet value in values)
+ {
+ List<Snippet> pieces;
+ if (!map.TryGetValue(value.Language.LanguageId, out pieces))
+ {
+ pieces = new List<Snippet>();
+ map.Add(value.Language.LanguageId, pieces);
+ }
+ pieces.Add(value);
+ }
+ }
+ }
+
+ // now write the collection of snippet pieces to the document
+ XmlWriter writer = node.InsertAfter();
+ writer.WriteStartElement("snippets");
+ writer.WriteAttributeString("reference", reference);
+
+ // first write the snippets in the order their language shows up in the language map (if any)
+ foreach (string devlang in languageList)
+ {
+ foreach (KeyValuePair<string, List<Snippet>> entry in map)
+ {
+ if (!(devlang == entry.Key.ToLower()))
+ continue;
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", entry.Key);
+ writer.WriteString("\n");
+
+ // write the set of snippets for this language
+ List<Snippet> values = entry.Value;
+ for (int i = 0; i < values.Count; i++)
+ {
+ if (i > 0)
+ writer.WriteString("\n...\n\n\n");
+ // write the colorized or plaintext snippet text
+ WriteSnippetText(values[i], writer);
+ }
+
+ writer.WriteEndElement();
+ }
+ }
+
+ // now write any snippets whose language isn't in the language map
+ foreach (KeyValuePair<string, List<Snippet>> entry in map)
+ {
+ if (languageList.Contains(entry.Key.ToLower()))
+ continue;
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", entry.Key);
+ writer.WriteString("\n");
+
+ // write the set of snippets for this language
+ List<Snippet> values = entry.Value;
+ for (int i = 0; i < values.Count; i++)
+ {
+ if (i > 0)
+ writer.WriteString("\n...\n\n\n");
+ // write the colorized or plaintext snippet text
+ WriteSnippetText(values[i], writer);
+ }
+
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ writer.Close();
+ }
+ node.DeleteSelf();
+ }
+ }
+ #endregion
+
+ #region Private methods
+ /// <summary>
+ /// Index the example names to paths.
+ /// </summary>
+ /// <param name="rootDirectory">root directory location of parsnip samples</param>
+ private void loadExamples(string rootDirectory)
+ {
+ try
+ {
+ DirectoryInfo root = new DirectoryInfo(rootDirectory);
+ DirectoryInfo[] areaDirectories = root.GetDirectories();
+
+ foreach (DirectoryInfo area in areaDirectories)
+ {
+ DirectoryInfo[] exampleDirectories = area.GetDirectories();
+
+ foreach (DirectoryInfo example in exampleDirectories)
+ {
+ string path;
+ if (this.exampleIndex.TryGetValue(example.Name.ToLower(CultureInfo.InvariantCulture), out path))
+ WriteMessage(MessageLevel.Warn, string.Format("The example '{0}' under folder '{1}' already exists under '{2}'", example.Name, example.FullName, path));
+
+ this.exampleIndex[example.Name.ToLower(CultureInfo.InvariantCulture)] = example.FullName;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ WriteMessage(MessageLevel.Error, string.Format(System.Threading.Thread.CurrentThread.CurrentCulture, "The loading of examples failed:{0}", e.Message));
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Index the approved snippets.
+ /// </summary>
+ /// <param name="file">approved snippets log file</param>
+ private void parseApprovalLogFiles(string file)
+ {
+ string sampleName = string.Empty;
+ string unitName = string.Empty;
+ List<string> rejectedUnits = null;
+
+ XmlReader reader = XmlReader.Create(file);
+ try
+ {
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ if (reader.Name == "Sample")
+ {
+ sampleName = reader.GetAttribute("name").ToLower(CultureInfo.InvariantCulture);
+ //create a new rejectedUnits list for this sample
+ rejectedUnits = null;
+ }
+
+ if (reader.Name == "Unit")
+ {
+ unitName = reader.GetAttribute("name").ToLower(CultureInfo.InvariantCulture);
+
+ bool include = Convert.ToBoolean(reader.GetAttribute("include"));
+
+ if (include)
+ {
+ if (this.approvedSnippetIndex.ContainsKey(Path.Combine(sampleName, unitName)))
+ WriteMessage(MessageLevel.Warn, string.Format("Sample '{0}' already exists in the approval log files.", sampleName));
+ this.approvedSnippetIndex[Path.Combine(sampleName, unitName)] = null;
+ }
+ else
+ {
+ if (rejectedUnits == null)
+ {
+ rejectedUnits = new List<string>();
+ rejectedSnippetIndex[sampleName] = rejectedUnits;
+ }
+ rejectedUnits.Add(unitName);
+ }
+ }
+ }
+ }
+ }
+ catch (XmlException e)
+ {
+ WriteMessage(MessageLevel.Error, String.Format("The specified approval log file is not well-formed. The error message is: {0}", e.Message));
+ }
+ finally
+ {
+ reader.Close();
+ }
+ }
+
+ /// <summary>
+ /// Write the snippet content to output files.
+ /// </summary>
+ /// <param name="node">code reference node</param>
+ /// <param name="identifier">List of snippets</param>
+ private void writeSnippetContent(XPathNavigator node, SnippetIdentifier identifier, List<Snippet> snippetList)
+ {
+ if (snippetList == null || snippetList.Count == 0)
+ {
+ WriteMessage(MessageLevel.Warn, "Empty snippet list past for node " + node.Name);
+ return;
+ }
+
+ XmlWriter writer = node.InsertAfter();
+ writer.WriteStartElement("snippets");
+ writer.WriteAttributeString("reference", node.Value);
+
+ // first write the snippets in the order their language shows up in the language map (if any)
+ foreach (string devlang in languageList)
+ {
+ foreach (Snippet snippet in snippetList)
+ {
+ if (!(devlang == snippet.Language.LanguageId.ToLower()))
+ continue;
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", snippet.Language.LanguageId);
+ writer.WriteString("\n");
+ // write the colorized or plaintext snippet text
+ WriteSnippetText(snippet, writer);
+ writer.WriteEndElement();
+ }
+ }
+
+ // now write any snippets whose language isn't in the language map
+ foreach (Snippet snippet in snippetList)
+ {
+ if (languageList.Contains(snippet.Language.LanguageId.ToLower()))
+ continue;
+ writer.WriteStartElement("snippet");
+ writer.WriteAttributeString("language", snippet.Language.LanguageId);
+ writer.WriteString("\n");
+ // write the colorized or plaintext snippet text
+ WriteSnippetText(snippet, writer);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ writer.Close();
+ }
+
+ private void WriteSnippetText(Snippet snippet, XmlWriter writer)
+ {
+ // if colorization rules are defined, then colorize the snippet.
+ if (snippet.Language.ColorizationRules != null)
+ {
+ writeColorizedSnippet(colorizeSnippet(snippet.Content, snippet.Language.ColorizationRules), writer);
+ }
+ else
+ {
+ writer.WriteString(snippet.Content);
+ }
+ }
+
+ private static ICollection<Region> colorizeSnippet(string text, List<ColorizationRule> rules)
+ {
+ // Console.WriteLine("colorizing: '{0}'", text);
+ // create a linked list consiting entirely of one uncolored region
+ LinkedList<Region> regions = new LinkedList<Region>();
+ regions.AddFirst(new Region(text));
+
+ // loop over colorization rules
+ foreach (ColorizationRule rule in rules)
+ {
+ // loop over regions
+ LinkedListNode<Region> node = regions.First;
+ while (node != null)
+ {
+ // only try to colorize uncolored regions
+ if (node.Value.ClassName != null)
+ {
+ node = node.Next;
+ continue;
+ }
+
+ // find matches in the region
+ string regionText = node.Value.Text;
+ Capture[] matches = rule.Apply(regionText);
+
+ // if no matches were found, continue to the next region
+ if (matches.Length == 0)
+ {
+ node = node.Next;
+ continue;
+ }
+
+ // we found matches; break the region into colored and uncolered subregions
+ // index is where we are looking from; index-1 is the end of the last match
+ int index = 0;
+
+ LinkedListNode<Region> referenceNode = node;
+
+ foreach (Capture match in matches)
+ {
+ // create a leading uncolored region
+ if (match.Index > index)
+ {
+ //Console.WriteLine("uncolored: {0} '{1}' -> {2} '{3}'", index, regionText[index], match.Index - 1, regionText[match.Index - 1]);
+ Region uncoloredRegion = new Region(regionText.Substring(index, match.Index - index));
+ referenceNode = regions.AddAfter(referenceNode, uncoloredRegion);
+ }
+
+ // create a colored region
+ // Console.WriteLine("name = {0}", rule.ClassName);
+ //Console.WriteLine("colored: {0} '{1}' -> {2} '{3}'", match.Index, regionText[match.Index], match.Index + match.Length - 1, regionText[match.Index + match.Length - 1]);
+ Region coloredRegion = new Region(rule.ClassName, regionText.Substring(match.Index, match.Length));
+ referenceNode = regions.AddAfter(referenceNode, coloredRegion);
+
+ index = match.Index + match.Length;
+ }
+
+ // create a trailing uncolored region
+ if (index < regionText.Length)
+ {
+ Region uncoloredRegion = new Region(regionText.Substring(index));
+ referenceNode = regions.AddAfter(referenceNode, uncoloredRegion);
+ }
+
+ // remove the original node
+ regions.Remove(node);
+ node = referenceNode.Next;
+ }
+ }
+ return (regions);
+ }
+
+ private static void writeColorizedSnippet(ICollection<Region> regions, XmlWriter writer)
+ {
+ foreach (Region region in regions)
+ {
+ // Console.WriteLine("writing {0}", region.ClassName);
+ if (region.ClassName == null)
+ {
+ writer.WriteString(region.Text);
+ }
+ else
+ {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", region.ClassName);
+ writer.WriteString(region.Text);
+ writer.WriteEndElement();
+ }
+ }
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Language class.
+ /// </summary>
+ internal class Language
+ {
+ #region Private members
+ /// <summary>
+ /// The id of the programming language.
+ /// </summary>
+ private string languageId;
+
+ /// <summary>
+ /// Language file extension.
+ /// </summary>
+ private string extension;
+
+ /// <summary>
+ /// List of colorization rules.
+ /// </summary>
+ private List<ColorizationRule> colorizationRules;
+ #endregion
+
+ #region Constructor
+ /// <summary>
+ /// Language Constructor
+ /// </summary>
+ /// <param name="languageId">language id</param>
+ /// <param name="extension">language file extension</param>
+ /// <param name="rules">colorization rules</param>
+ public Language(string languageId, string extension, List<ColorizationRule> rules)
+ {
+ this.languageId = languageId;
+ this.extension = extension;
+ this.colorizationRules = rules;
+ }
+ #endregion
+
+ #region Public properties
+ /// <summary>
+ /// Gets the languageId.
+ /// </summary>
+ public string LanguageId
+ {
+ get
+ {
+ return this.languageId;
+ }
+ }
+
+ /// <summary>
+ /// Gets the file extension
+ /// </summary>
+ public string Extension
+ {
+ get
+ {
+ return this.extension;
+ }
+ }
+
+ /// <summary>
+ /// Gets the colorization rules
+ /// </summary>
+ public List<ColorizationRule> ColorizationRules
+ {
+ get
+ {
+ return this.colorizationRules;
+ }
+ }
+ #endregion
+
+ #region Public methods
+ /// <summary>
+ /// Check if the language is defined.
+ /// </summary>
+ /// <param name="languageId">language id</param>
+ /// <param name="extension">file extension</param>
+ /// <returns>boolean indicating if a language is defined</returns>
+ public bool IsMatch(string languageId, string extension)
+ {
+ if (this.languageId == languageId)
+ {
+ if (this.extension == extension)
+ {
+ return true;
+ }
+ else if (this.extension == "*")
+ {
+ return true;
+ }
+ }
+ else if (this.languageId == "*")
+ {
+ if (this.extension == extension)
+ {
+ return true;
+ }
+
+ if (this.extension == "*")
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Snippet class.
+ /// </summary>
+ internal class Snippet
+ {
+ #region Private Members
+ /// <summary>
+ /// snippet content.
+ /// </summary>
+ private string content;
+
+ /// <summary>
+ /// snippet language
+ /// </summary>
+ private Language language;
+ #endregion
+
+ #region Constructor
+ /// <summary>
+ /// Constructor for Snippet class.
+ /// </summary>
+ /// <param name="content">snippet content</param>
+ /// <param name="language">snippet language</param>
+ public Snippet(string content, Language language)
+ {
+ this.content = content;
+ this.language = language;
+ }
+ #endregion
+
+ #region Public properties
+ /// <summary>
+ /// Gets the snippet content.
+ /// </summary>
+ public string Content
+ {
+ get
+ {
+ return this.content;
+ }
+ }
+
+ /// <summary>
+ /// Gets the snippet language.
+ /// </summary>
+ public Language Language
+ {
+ get
+ {
+ return this.language;
+ }
+ }
+ #endregion
+ }
+
+ internal class SnippetCache
+ {
+ private int _cacheSize = 100;
+
+ private LinkedList<String> lruLinkedList;
+
+ private Dictionary<string, IndexedExample> cache;
+
+ private Dictionary<string, string> _approvalIndex;
+ private Dictionary<string, string> _languageMap;
+ private List<Language> _languages;
+ private Dictionary<string, Object> _excludedUnits;
+
+ public SnippetCache(int cacheSize, Dictionary<string, string> approvalIndex, Dictionary<string, string> languageMap, List<Language> languages, Dictionary<string, Object> excludedUnits)
+ {
+ _cacheSize = cacheSize;
+ _approvalIndex = approvalIndex;
+ _languageMap = languageMap;
+ _languages = languages;
+ _excludedUnits = excludedUnits;
+
+ cache = new Dictionary<string, IndexedExample>(_cacheSize);
+
+ lruLinkedList = new LinkedList<string>();
+ }
+
+ public List<Snippet> GetContent(string examplePath, SnippetIdentifier snippetId)
+ {
+
+ // get the example containing the identifier
+ IndexedExample exampleIndex = GetCachedExample(examplePath);
+ if (exampleIndex == null)
+ return (null);
+
+ //
+ return exampleIndex.GetContent(snippetId);
+ }
+
+ private IndexedExample GetCachedExample(string examplePath)
+ {
+ IndexedExample exampleIndex;
+ if (cache.TryGetValue(examplePath, out exampleIndex))
+ {
+ // move the file from its current position to the head of the lru linked list
+ lruLinkedList.Remove(exampleIndex.ListNode);
+ lruLinkedList.AddFirst(exampleIndex.ListNode);
+ }
+ else
+ {
+ // not in the cache, so load and index a new example
+ exampleIndex = new IndexedExample(examplePath, _approvalIndex, _languageMap, _languages, _excludedUnits);
+ if (cache.Count >= _cacheSize)
+ {
+ // the cache is full
+ // the last node in the linked list has the path of the next file to remove from the cache
+ if (lruLinkedList.Last != null)
+ {
+ cache.Remove(lruLinkedList.Last.Value);
+ lruLinkedList.RemoveLast();
+ }
+ }
+ // add the new file to the cache and to the head of the lru linked list
+ cache.Add(examplePath, exampleIndex);
+ exampleIndex.ListNode = lruLinkedList.AddFirst(examplePath);
+ }
+ return (exampleIndex);
+ }
+
+
+ }
+
+ internal class IndexedExample
+ {
+ /// <summary>
+ /// snippet store.
+ /// </summary>
+ private Dictionary<SnippetIdentifier, List<Snippet>> exampleSnippets = new Dictionary<SnippetIdentifier, List<Snippet>>();
+ private Dictionary<string, string> _approvalIndex;
+ private Dictionary<string, string> _languageMap;
+ private List<Language> _languages;
+ private Dictionary<string, Object> _excludedUnits;
+
+ public IndexedExample(string examplePath, Dictionary<string, string> approvalIndex, Dictionary<string, string> languageMap, List<Language> languages, Dictionary<string, Object> excludedUnits)
+ {
+ _approvalIndex = approvalIndex;
+ _languageMap = languageMap;
+ _languages = languages;
+ _excludedUnits = excludedUnits;
+
+ // load all the snippets under the specified example path
+ this.ParseExample(new DirectoryInfo(examplePath));
+ }
+
+ public List<Snippet> GetContent(SnippetIdentifier identifier)
+ {
+ if (exampleSnippets.ContainsKey(identifier))
+ return exampleSnippets[identifier];
+ else
+ return null;
+ }
+
+ private LinkedListNode<string> listNode;
+ public LinkedListNode<string> ListNode
+ {
+ get
+ {
+ return (listNode);
+ }
+ set
+ {
+ listNode = value;
+ }
+ }
+
+ /// <summary>
+ /// Check whether the snippet unit is approved
+ /// </summary>
+ /// <param name="unit">unit directory</param>
+ /// <returns>boolean indicating whether the snippet unit is approved</returns>
+ private bool isApprovedUnit(DirectoryInfo unit)
+ {
+ string sampleName = unit.Parent.Name.ToLower(CultureInfo.InvariantCulture);
+ string unitName = unit.Name.ToLower(CultureInfo.InvariantCulture);
+
+ // return false if the unit name is in the list of names to exclude
+ if (_excludedUnits.ContainsKey(unitName))
+ return false;
+
+ // if no approval log is specified, all snippets are approved by default
+ if (_approvalIndex.Count == 0)
+ return true;
+
+ if (_approvalIndex.ContainsKey(Path.Combine(sampleName, unitName)))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Parse the example directory.
+ /// </summary>
+ /// <param name="unit">unit directory</param>
+ private void ParseExample(DirectoryInfo exampleDirectory)
+ {
+ // process the approved language-specific unit directories for this example
+ DirectoryInfo[] unitDirectories = exampleDirectory.GetDirectories();
+
+ foreach (DirectoryInfo unit in unitDirectories)
+ {
+ if (this.isApprovedUnit(unit))
+ this.ParseUnit(unit);
+ }
+ }
+
+ /// <summary>
+ /// Parse the unit directory for language files.
+ /// </summary>
+ /// <param name="unit">unit directory containing a language-specific version of the example</param>
+ private void ParseUnit(DirectoryInfo unit)
+ {
+ // the language is the Unit Directory name, or the language id mapped to that name
+ string language = unit.Name;
+ if (_languageMap.ContainsKey(language.ToLower()))
+ language = _languageMap[language.ToLower()];
+
+ ParseDirectory(unit, language, unit.Parent.Name);
+ }
+
+ /// <summary>
+ /// Parse an example subdir looking for source files containing snipppets.
+ /// </summary>
+ /// <param name="directory">The directory to parse</param>
+ /// <param name="language">the id of a programming language</param>
+ /// <param name="exampleName">the name of the example</param>
+ private void ParseDirectory(DirectoryInfo directory, string language, string exampleName)
+ {
+ // parse the files in this directory
+ FileInfo[] files = directory.GetFiles();
+ foreach (FileInfo file in files)
+ ParseFile(file, language, exampleName);
+
+ // recurse to get files in any subdirectories
+ DirectoryInfo[] subdirectories = directory.GetDirectories();
+ foreach (DirectoryInfo subdirectory in subdirectories)
+ ParseDirectory(subdirectory, language, exampleName);
+ }
+
+ /// <summary>
+ /// Parse the language files to retrieve the snippet content.
+ /// </summary>
+ /// <param name="file">snippet file</param>
+ /// <param name="language">snippet language</param>
+ /// <param name="example">name of the example that contains this file</param>
+ private void ParseFile(FileInfo file, string language, string exampleName)
+ {
+ string snippetLanguage = string.Empty;
+
+ // The snippet language is the name (or id mapping) of the Unit folder
+ // unless the file extension is .xaml
+ // NOTE: this is just preserving the way ExampleBuilder handled it (which we can change when we're confident there are no unwanted side-effects)
+ if (file.Extension.ToLower() == ".xaml")
+ snippetLanguage = "XAML";
+ else
+ snippetLanguage = language;
+
+ // get the text in the file
+ StreamReader reader = file.OpenText();
+ string text = reader.ReadToEnd();
+ reader.Close();
+
+ this.parseSnippetContent(text, snippetLanguage, file.Extension, exampleName);
+ }
+
+ /// <summary>
+ /// Parse the snippet content.
+ /// </summary>
+ /// <param name="text">content to be parsed</param>
+ /// <param name="language">snippet language</param>
+ /// <param name="extension">file extension</param>
+ /// <param name="example">snippet example</param>
+ private void parseSnippetContent(string text, string language, string extension, string example)
+ {
+ // parse the text for snippets
+ for (Match match = find.Match(text); match.Success; match = find.Match(text, match.Index + 10))
+ {
+ string snippetIdentifier = match.Groups["id"].Value;
+ string snippetContent = match.Groups["tx"].Value;
+ snippetContent = clean.Replace(snippetContent, "\n");
+
+ //if necessary, clean one more time to catch snippet comments on consecutive lines
+ if (clean.Match(snippetContent).Success)
+ {
+ snippetContent = clean.Replace(snippetContent, "\n");
+ }
+
+ snippetContent = cleanAtStart.Replace(snippetContent, "");
+ snippetContent = cleanAtEnd.Replace(snippetContent, "");
+
+ // get the language/extension from our languages List, which may contain colorization rules for the language
+ Language snippetLanguage = new Language(language, extension, null);
+ foreach (Language lang in _languages)
+ {
+ if (!lang.IsMatch(language, extension))
+ continue;
+ snippetLanguage = lang;
+ break;
+ }
+
+ SnippetIdentifier identifier = new SnippetIdentifier(example, snippetIdentifier);
+ // BUGBUG: i don't think this ever happens, but if it did we should write an error
+ if (!IsLegalXmlText(snippetContent))
+ {
+ // WriteMessage(MessageLevel.Warn, String.Format("Snippet '{0}' language '{1}' contains illegal characters.", identifier.ToString(), snippetLanguage.LanguageId));
+ continue;
+ }
+
+ snippetContent = StripLeadingSpaces(snippetContent);
+
+ // Add the snippet information to dictionary
+ Snippet snippet = new Snippet(snippetContent, snippetLanguage);
+ List<Snippet> values;
+
+ if (!this.exampleSnippets.TryGetValue(identifier, out values))
+ {
+ values = new List<Snippet>();
+ this.exampleSnippets.Add(identifier, values);
+ }
+ values.Add(snippet);
+ }
+ }
+
+ private bool IsLegalXmlText(string text)
+ {
+ foreach (char c in text)
+ {
+ if (!IsLegalXmlCharacter(c)) return (false);
+ }
+ return (true);
+ }
+
+ private bool IsLegalXmlCharacter(char c)
+ {
+ if (c < 0x20)
+ {
+ return ((c == 0x09) || (c == 0x0A) || (c == 0x0D));
+ }
+ else
+ {
+ if (c < 0xD800)
+ {
+ return (true);
+ }
+ else
+ {
+ return ((c >= 0xE000) && (c <= 0xFFFD));
+ }
+ }
+ }
+
+ private static string StripLeadingSpaces(string text)
+ {
+
+ if (text == null) throw new ArgumentNullException("text");
+
+ // split the text into lines
+ string[] stringSeparators = new string[] { "\r\n" };
+ string[] lines = text.Split(stringSeparators, StringSplitOptions.None);
+
+ // no need to do this if there is only one line
+ if (lines.Length == 1) return (lines[0]);
+
+ // figure out how many leading spaces to delete
+ int spaces = Int32.MaxValue;
+ for (int i = 0; i < lines.Length; i++)
+ {
+
+ string line = lines[i];
+
+ // skip empty lines
+ if (line.Length == 0) continue;
+
+ // determine the number of leading spaces
+ int index = 0;
+ while (index < line.Length)
+ {
+ if (line[index] != ' ') break;
+ index++;
+ }
+
+ if (index == line.Length)
+ {
+ // lines that are all spaces should just be treated as empty
+ lines[i] = String.Empty;
+ }
+ else
+ {
+ // otherwise, keep track of the minimum number of leading spaces
+ if (index < spaces) spaces = index;
+ }
+
+ }
+
+ // re-form the string with leading spaces deleted
+ StringBuilder result = new StringBuilder();
+ foreach (string line in lines)
+ {
+ if (line.Length == 0)
+ {
+ result.AppendLine();
+ }
+ else
+ {
+ result.AppendLine(line.Substring(spaces));
+ }
+ }
+ // Console.WriteLine("AFTER:");
+ // Console.WriteLine(result.ToString());
+ return (result.ToString());
+
+ }
+
+ /// <summary>
+ /// Regex to find the snippet content.
+ /// </summary>
+ private static Regex find = new Regex(
+ @"<snippet(?<id>\w+)>.*\n(?<tx>(.|\n)*?)\n.*</snippet(\k<id>)>",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ /// <summary>
+ /// Regex to clean the snippet content.
+ /// </summary>
+ private static Regex clean = new Regex(
+ @"\n[^\n]*?<(/?)snippet(\w+)>[^\n]*?\n",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ /// <summary>
+ /// Regex to clean the start of the snippet.
+ /// </summary>
+ private static Regex cleanAtStart = new Regex(
+ @"^[^\n]*?<(/?)snippet(\w+)>[^\n]*?\n",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ /// <summary>
+ /// Regex to clean the end of the snippet.
+ /// </summary>
+ private static Regex cleanAtEnd = new Regex(
+ @"\n[^\n]*?<(/?)snippet(\w+)>[^\n]*?$",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled);
+
+ }
+
+
+}
+
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SwitchComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SwitchComponent.cs
new file mode 100644
index 0000000..48f9fbe
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SwitchComponent.cs
@@ -0,0 +1,77 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Diagnostics;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class SwitchComponent : BuildComponent {
+
+ public SwitchComponent(BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // get the condition
+ XPathNavigator condition_element = configuration.SelectSingleNode("switch");
+ if (condition_element == null) {
+ throw new ConfigurationErrorsException("You must specifiy a condition using the <switch> statement with a 'value' attribute.");
+ }
+ string condition_value = condition_element.GetAttribute("value", String.Empty);
+ if (String.IsNullOrEmpty(condition_value)) {
+ throw new ConfigurationErrorsException("The switch statement must have a 'value' attribute, which is an xpath expression.");
+ }
+ condition = XPathExpression.Compile(condition_value);
+
+ // load the component stacks for each case
+ XPathNodeIterator case_elements = configuration.Select("case");
+ foreach (XPathNavigator case_element in case_elements) {
+ string case_value = case_element.GetAttribute("value", String.Empty);
+ BuildComponent[] components = BuildAssembler.LoadComponents(case_element);
+ cases.Add(case_value, components);
+ }
+ }
+
+ // data held by the component
+
+ private XPathExpression condition;
+
+ private Dictionary<string,IEnumerable<BuildComponent>> cases = new Dictionary<string,IEnumerable<BuildComponent>>();
+
+ // the action of the component
+
+ public override void Apply(XmlDocument document, string key) {
+
+ // evaluate the condition
+ string result = document.CreateNavigator().Evaluate(condition).ToString();
+
+ // get the corresponding component stack
+ IEnumerable<BuildComponent> components;
+ if (cases.TryGetValue(result, out components)) {
+ // apply it
+ foreach (BuildComponent component in components) {
+ component.Apply(document, key);
+ }
+ } else {
+ // no such case exists
+ }
+
+ }
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (IEnumerable<BuildComponent> components in cases.Values) {
+ foreach (BuildComponent component in components) {
+ component.Dispose();
+ }
+ }
+ }
+ base.Dispose(disposing);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SyntaxComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SyntaxComponent.cs
new file mode 100644
index 0000000..3573712
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/SyntaxComponent.cs
@@ -0,0 +1,283 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class SyntaxComponent : BuildComponent {
+
+ public SyntaxComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNavigator syntax_node = configuration.SelectSingleNode("syntax");
+ string syntax_input_xpath = syntax_node.GetAttribute("input", String.Empty);
+ if (String.IsNullOrEmpty(syntax_input_xpath)) throw new ConfigurationErrorsException("You must specify an XPath for input in the syntax element.");
+ syntax_input = XPathExpression.Compile(syntax_input_xpath);
+ string syntax_output_xpath = syntax_node.GetAttribute("output", String.Empty);
+ if (String.IsNullOrEmpty(syntax_output_xpath)) throw new ConfigurationErrorsException("You must specify an XPath for output in the syntax element.");
+ syntax_output = XPathExpression.Compile(syntax_output_xpath);
+
+ writerType = typeof(ManagedSyntaxWriter);
+ //if (writerType == null) Console.WriteLine("null writer");
+
+ XPathNodeIterator generator_nodes = configuration.Select("generators/generator");
+ foreach (XPathNavigator generator_node in generator_nodes) {
+
+ // get the data to load the generator
+ string assembly_path = generator_node.GetAttribute("assembly", String.Empty);
+ if (String.IsNullOrEmpty(assembly_path)) WriteMessage(MessageLevel.Error, "Each generator element must have an assembly attribute.");
+ string type_name = generator_node.GetAttribute("type", String.Empty);
+ if (String.IsNullOrEmpty(type_name)) WriteMessage(MessageLevel.Error, "Each generator element must have a type attribute.");
+
+ // expand environment variables in the path
+ assembly_path = Environment.ExpandEnvironmentVariables(assembly_path);
+
+ //Console.WriteLine("loading {0} from {1}", type_name, assembly_path);
+ try {
+ Assembly assembly = Assembly.LoadFrom(assembly_path);
+ SyntaxGenerator generator = (SyntaxGenerator)assembly.CreateInstance(type_name, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[1] { generator_node.Clone() }, null, null);
+
+ if (generator == null) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'.", type_name, assembly_path));
+ } else {
+ generators.Add(generator);
+ }
+
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A file access error occured while attempting to load the build component '{0}'. The error message is: {1}", assembly_path, e.Message));
+ } catch (BadImageFormatException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A syntax generator assembly '{0}' is invalid. The error message is: {1}.", assembly_path, e.Message));
+ } catch (TypeLoadException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' does not exist in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.Message));
+ } catch (MissingMethodException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' does not have an appropriate constructor. The error message is: {2}", type_name, assembly_path, e.Message));
+ } catch (TargetInvocationException e) {
+ WriteMessage(MessageLevel.Error, String.Format("An error occured while attempting to instantiate the type '{0}' in the assembly '{1}'. The error message is: {2}", type_name, assembly_path, e.InnerException.Message));
+ } catch (InvalidCastException) {
+ WriteMessage(MessageLevel.Error, String.Format("The type '{0}' in the assembly '{1}' is not a SyntaxGenerator.", type_name, assembly_path));
+ }
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Loaded {0} syntax generators.", generators.Count));
+
+ }
+
+ private XPathExpression syntax_input;
+
+ private XPathExpression syntax_output;
+
+ private Type writerType;
+
+ private List<SyntaxGenerator> generators = new List<SyntaxGenerator>();
+
+ public override void Apply (XmlDocument document, string key) {
+
+ XPathNavigator input = document.CreateNavigator().SelectSingleNode(syntax_input);
+ if (input == null) Console.WriteLine("null input");
+
+ XPathNavigator output = document.CreateNavigator().SelectSingleNode(syntax_output);
+ if (output == null) Console.WriteLine("null output");
+
+ SyntaxWriter writer = (SyntaxWriter) Activator.CreateInstance(writerType, new Object[1] { output });
+
+ foreach (SyntaxGenerator generator in generators) {
+ generator.WriteSyntax(input, writer);
+ }
+
+ }
+
+ }
+
+ // the writer
+
+ public abstract class SyntaxWriter {
+
+ protected SyntaxWriter (XPathNavigator location) {}
+
+ // Syntax block APIs
+
+ public virtual int Position {
+ get {
+ return (-1);
+ }
+ }
+
+ public abstract void WriteStartBlock(string language);
+
+ public abstract void WriteStartSubBlock(string classId);
+
+ public abstract void WriteEndSubBlock();
+
+ public abstract void WriteString(string text);
+
+ public abstract void WriteStringWithStyle (string text, string style);
+
+ public abstract void WriteReferenceLink (string reference);
+
+ public abstract void WriteReferenceLink (string reference, string text);
+
+ public virtual void WriteLine () {
+ WriteString("\n");
+ }
+
+ public virtual void WriteKeyword (string keyword) {
+ WriteStringWithStyle(keyword, "keyword");
+ }
+
+ public virtual void WriteParameter (string parameter) {
+ WriteStringWithStyle(parameter, "parameter");
+ }
+
+ public virtual void WriteIdentifier (string identifier) {
+ WriteStringWithStyle(identifier, "identifier");
+ }
+
+ public virtual void WriteLiteral (string literal) {
+ WriteStringWithStyle(literal, "literal");
+ }
+
+ public virtual void WriteMessage(string message)
+ {
+ WriteMessage(message, null);
+ }
+
+ public abstract void WriteMessage(string message, IEnumerable<string> parameters);
+
+ public abstract void WriteEndBlock();
+
+ }
+
+ // the concrete writer
+ // the should really be moved out
+
+ public class ManagedSyntaxWriter : SyntaxWriter {
+
+ public ManagedSyntaxWriter (XPathNavigator location) : base(location) {
+ if (location == null) Console.WriteLine("null location");
+ this.location = location;
+ }
+
+ XPathNavigator location;
+
+ XmlWriter writer;
+
+ // position along the line
+ int position = 0;
+
+ public override int Position {
+ get {
+ return (position);
+ }
+ }
+
+ public override void WriteStartBlock(string language)
+ {
+ writer = location.AppendChild();
+ writer.WriteStartElement("div");
+ writer.WriteAttributeString("codeLanguage", language);
+ position = 0;
+ }
+
+ public override void WriteStartSubBlock(string classId)
+ {
+ writer.WriteStartElement("div");
+ writer.WriteAttributeString("class", classId);
+ position = 0;
+ }
+
+ public override void WriteEndSubBlock()
+ {
+ writer.WriteEndElement();
+ position = 0;
+ }
+
+ public override void WriteLine () {
+ base.WriteLine();
+ position = 0;
+ }
+
+ public override void WriteString(string text)
+ {
+ writer.WriteString(text);
+ position += text.Length;
+ }
+
+ public override void WriteStringWithStyle (string text, string style) {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", style);
+ WriteString(text);
+ writer.WriteEndElement();
+ position += text.Length;
+ }
+
+ public override void WriteReferenceLink (string reference) {
+ writer.WriteStartElement("referenceLink");
+ writer.WriteAttributeString("target", reference);
+ writer.WriteAttributeString("prefer-overload", "false");
+ writer.WriteAttributeString("show-container", "false");
+ writer.WriteAttributeString("show-templates", "false");
+ writer.WriteAttributeString("show-parameters", "false");
+ writer.WriteEndElement();
+ position += 10; // approximate
+ }
+
+ public override void WriteReferenceLink (string reference, string text) {
+ writer.WriteStartElement("referenceLink");
+ writer.WriteAttributeString("target", reference);
+ writer.WriteAttributeString("prefer-overload", "false");
+ writer.WriteAttributeString("show-container", "false");
+ writer.WriteAttributeString("show-templates", "false");
+ writer.WriteAttributeString("show-parameters", "false");
+ writer.WriteString(text);
+ writer.WriteEndElement();
+ position += text.Length;
+ }
+
+ public override void WriteEndBlock () {
+ writer.WriteEndElement();
+ writer.Close();
+ position = 0;
+ }
+
+ public override void WriteMessage(string message, IEnumerable<string> parameters)
+ {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "message");
+ writer.WriteStartElement("include");
+ writer.WriteAttributeString("item", message);
+ if (parameters != null)
+ {
+ foreach (string parameter in parameters)
+ {
+ writer.WriteStartElement("parameter");
+ writer.WriteRaw(parameter);
+ writer.WriteEndElement();
+ }
+ }
+ writer.WriteEndElement();
+ writer.WriteEndElement();
+ }
+
+ }
+
+ // the abstract generator
+
+ public abstract class SyntaxGenerator {
+
+ protected SyntaxGenerator (XPathNavigator configuration) { }
+
+ public abstract void WriteSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ }
+
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TargetCollection.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TargetCollection.cs
new file mode 100644
index 0000000..188da53
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TargetCollection.cs
@@ -0,0 +1,2739 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ // The basic object model here is this:
+ // * Target objects represent files that can be targeted by a reference link
+ // * Different child objects of Target represent different sorts of API targets: Namespace, Type, Member, etc.
+ // * Targets are stored in a TargetCollection
+ // To indicate relationships between targets (e.g. a Method takes a particular type parameter), we
+ // introduce another set of classes:
+ // * Reference objects refer to a specific target
+ // * Objects like SpecializedTypeReference and ArrayTypeReference that represent decorated types
+ // There are two ways to construct such objects:
+ // * XML from a reflection information file defines Target and Reference objects. XmlUtilities does this.
+ // * Code entity reference strings construct Reference objecs. CerUtilities does this.
+ // Finally, we need a way to write the link text corresponding to a reference:
+ // * LinkTextResolver contains routines that, given a reference, writes the corresponding link text
+
+ // all arguments of public methods are verified
+
+ // The fact that the creation methods (via XML or CER strings) for references and their rendering methods
+ // are seperated from the declarations of the reference types goes against OO principals. (The consequent
+ // absence of virtual methods also makes for a lot of ugly casting to figure out what method to call.)
+ // But there is a reason for it: I wanted all the code that intrepreted XML together, all the code that
+ // intrepreted CER strings together, and all the code that did link text renderig together, and I wanted
+ // them all seperate from each other. I belive this is extremely important for maintainability. It may
+ // be possible to leverage partial classes to do this in a more OO fashion.
+
+ public class Test {
+
+ public static void Main (string[] args) {
+
+ TargetCollection targets = new TargetCollection();
+
+ XPathDocument document = new XPathDocument(args[0]);
+ XPathNavigator node = document.CreateNavigator();
+ XmlTargetCollectionUtilities.AddTargets(targets, node, LinkType2.Local);
+ Console.WriteLine(targets.Count);
+
+ LinkTextResolver resolver = new LinkTextResolver(targets);
+
+ // test writer
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ XmlWriter writer = XmlWriter.Create(Console.Out, settings);
+ writer.WriteStartDocument();
+ writer.WriteStartElement("types");
+ XPathNodeIterator apiNodes = node.Select("/*/apis/api[not(apidata/@subgroup='enumeration')]//*[@display-api]");
+ foreach (XPathNavigator apiNode in apiNodes) {
+ string api = apiNode.GetAttribute("display-api", String.Empty);
+ if (api[1] != ':') continue;
+
+ string id = (string) apiNode.Evaluate("string(ancestor::api[1]/@id)");
+ TextReferenceUtilities.SetGenericContext(id);
+
+ Reference reference = TextReferenceUtilities.CreateReference(api);
+
+ writer.WriteStartElement("test");
+ writer.WriteAttributeString("api", api);
+ writer.WriteAttributeString("context", id);
+ if (reference == null) {
+ writer.WriteString("NULL REFERENCE");
+ } else {
+ resolver.WriteReference(reference, DisplayOptions.ShowContainer | DisplayOptions.ShowTemplates | DisplayOptions.ShowParameters, writer);
+ }
+ writer.WriteEndElement();
+
+ }
+
+ writer.WriteEndElement();
+ writer.WriteEndDocument();
+ writer.Close();
+
+ }
+
+ }
+
+ // contains a collection of targets
+
+ public class TargetCollection {
+
+ private Dictionary<string, Target> index = new Dictionary<string, Target>();
+
+ // read the collection
+
+ public Target this[string id] {
+ get {
+ Target result;
+ index.TryGetValue(id, out result);
+ return (result);
+ }
+ }
+
+ public bool Contains (string id) {
+ return( index.ContainsKey(id) );
+ }
+
+ public IEnumerable<string> Ids {
+ get {
+ return (index.Keys);
+ }
+ }
+
+ public IEnumerable<Target> Targets {
+ get {
+ return (index.Values);
+ }
+ }
+
+ public int Count {
+ get {
+ return(index.Count);
+ }
+ }
+
+ // change the collection
+
+ public void Add (Target target) {
+ index[target.Id] = target;
+ //index.Add(target.Id, target);
+ }
+
+ public void Clear () {
+ index.Clear();
+ }
+
+ }
+
+ // targets
+
+ public class Target {
+
+ internal string id;
+
+ internal string container;
+
+ internal string file;
+
+ internal LinkType2 type;
+
+ public string Id {
+ get {
+ return (id);
+ }
+ }
+
+ public string Container {
+ get {
+ return (container);
+ }
+ }
+
+ public string File {
+ get {
+ return(file);
+ }
+ }
+
+ internal LinkType2 DefaultLinkType {
+ get {
+ return (type);
+ }
+ }
+
+ public virtual void Add (TargetCollection targets) {
+ targets.Add(this);
+ }
+
+ }
+
+ public class NamespaceTarget : Target {
+
+ internal string name;
+
+ public string Name {
+ get {
+ return(name);
+ }
+ }
+
+ }
+
+ public class TypeTarget : Target {
+
+ internal string name;
+
+ internal NamespaceReference containingNamespace;
+
+ internal SimpleTypeReference containingType;
+
+ internal string[] templates;
+
+ public string Name {
+ get {
+ return(name);
+ }
+ }
+
+ public NamespaceReference Namespace {
+ get {
+ return (containingNamespace);
+ }
+ }
+
+ public SimpleTypeReference OuterType {
+ get {
+ return (containingType);
+ }
+ }
+
+ public string[] Templates {
+ get {
+ return(templates);
+ }
+ }
+
+ }
+
+ public class EnumerationTarget : TypeTarget {
+
+ internal MemberTarget[] elements;
+
+ public override void Add (TargetCollection targets) {
+ base.Add(targets);
+
+ foreach (MemberTarget element in elements) {
+ element.Add(targets);
+ }
+ }
+
+ }
+
+ public class MemberTarget : Target {
+
+ internal string name;
+
+ internal SimpleTypeReference containingType;
+
+ internal string overload;
+
+ public string Name {
+ get {
+ return (name);
+ }
+ }
+
+ public TypeReference Type {
+ get {
+ return (containingType);
+ }
+ }
+
+ public string OverloadId {
+ get {
+ return (overload);
+ }
+ }
+
+ }
+
+ public class ConstructorTarget : MemberTarget {
+
+ internal Parameter[] parameters;
+
+ public Parameter[] Parameters {
+ get {
+ return (parameters);
+ }
+ }
+
+ }
+
+ public class ProcedureTarget : MemberTarget {
+
+ internal bool conversionOperator;
+
+ internal MemberReference explicitlyImplements = null;
+
+ public bool ConversionOperator {
+ get {
+ return (conversionOperator);
+ }
+ }
+
+ public MemberReference ExplicitlyImplements {
+ get {
+ return (explicitlyImplements);
+ }
+ }
+
+ }
+
+ public class EventTarget : ProcedureTarget {
+ }
+
+ public class PropertyTarget : ProcedureTarget {
+
+ internal Parameter[] parameters;
+
+ internal TypeReference returnType;
+
+ public Parameter[] Parameters {
+ get {
+ return (parameters);
+ }
+ }
+
+ }
+
+ public class MethodTarget : ProcedureTarget {
+
+ internal Parameter[] parameters;
+
+ internal TypeReference returnType;
+
+ internal string[] templates;
+
+ public Parameter[] Parameters {
+ get {
+ return (parameters);
+ }
+ }
+
+ public string[] Templates {
+ get {
+ return (templates);
+ }
+ }
+
+ // property to hold specialized template arguments (used with extension methods)
+ internal TypeReference[] templateArgs;
+ public TypeReference[] TemplateArgs
+ {
+ get
+ {
+ return (templateArgs);
+ }
+ }
+
+ }
+
+ public class Parameter {
+
+ private string name;
+
+ private TypeReference type;
+
+ public string Name {
+ get {
+ return (name);
+ }
+ }
+
+ public TypeReference Type {
+ get {
+ return (type);
+ }
+ }
+
+
+ internal Parameter (string name, TypeReference type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ }
+
+ // ***** Reference objects *****
+
+ public abstract class Reference { }
+
+ public class NamespaceReference : Reference {
+
+ private string namespaceId;
+
+ public string Id {
+ get {
+ return(namespaceId);
+ }
+ }
+
+ public Target Resolve (TargetCollection targets) {
+ return(targets[namespaceId]);
+ }
+
+ internal NamespaceReference (string id) {
+ this.namespaceId = id;
+ }
+
+ }
+
+ public abstract class TypeReference : Reference {}
+
+ public class SimpleTypeReference : TypeReference {
+
+ private string typeId;
+
+ public string Id {
+ get {
+ return(typeId);
+ }
+ }
+
+ public Target Resolve (TargetCollection targets) {
+ return(targets[typeId]);
+ }
+
+ internal SimpleTypeReference (string id) {
+ this.typeId = id;
+ }
+
+ }
+
+ public class SpecializedTypeReference : TypeReference {
+
+ private Specialization[] specializations;
+
+ public Specialization[] Specializations {
+ get {
+ return (specializations);
+ }
+ }
+
+ internal SpecializedTypeReference (Specialization[] specializations) {
+ if (specializations == null) throw new ArgumentNullException("specializations");
+ this.specializations = specializations;
+ }
+
+ public Dictionary<IndexedTemplateTypeReference, TypeReference> GetSpecializationDictionary () {
+ Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary = new Dictionary<IndexedTemplateTypeReference, TypeReference>();
+ foreach (Specialization specialization in specializations) {
+ for (int index=0; index<specialization.Arguments.Length; index++) {
+ IndexedTemplateTypeReference template = new IndexedTemplateTypeReference(specialization.TemplateType.Id, index);
+ dictionary.Add(template, specialization.Arguments[index]);
+ }
+ }
+ return (dictionary);
+ }
+
+ }
+
+ public class Specialization {
+
+ private SimpleTypeReference template;
+
+ public TypeReference[] arguments;
+
+ public SimpleTypeReference TemplateType {
+ get {
+ return (template);
+ }
+ }
+
+ [CLSCompliant(false)]
+ public TypeReference[] Arguments {
+ get {
+ return (arguments);
+ }
+ }
+
+ internal Specialization (SimpleTypeReference template, TypeReference[] arguments) {
+ if (template == null) throw new ArgumentNullException("template");
+ if (arguments == null) throw new ArgumentNullException("arguments");
+ this.template = template;
+ this.arguments = arguments;
+ }
+
+ }
+
+ public abstract class TemplateTypeReference : TypeReference { }
+
+ public class IndexedTemplateTypeReference : TemplateTypeReference {
+
+ private string templateId;
+
+ private int index;
+
+ public string TemplateId {
+ get {
+ return (templateId);
+ }
+ }
+
+ public int Index {
+ get {
+ return (index);
+ }
+ }
+
+ internal IndexedTemplateTypeReference (string templateId, int index) {
+ if (templateId == null) throw new ArgumentNullException("templateId");
+ if (index < 0) throw new ArgumentOutOfRangeException("index");
+ this.templateId = templateId;
+ this.index = index;
+ }
+
+ public override int GetHashCode () {
+ return (index ^ templateId.GetHashCode());
+ }
+
+ public override bool Equals (object obj) {
+ IndexedTemplateTypeReference other = obj as IndexedTemplateTypeReference;
+ if (other == null) return (false);
+ if ((this.index == other.index) && (this.templateId == other.templateId)) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+ }
+
+ public class NamedTemplateTypeReference : TemplateTypeReference {
+
+ private string name;
+
+ public string Name {
+ get {
+ return (name);
+ }
+ }
+
+ public NamedTemplateTypeReference (string name) {
+ this.name = name;
+ }
+
+ }
+
+ public class TypeTemplateTypeReference : TemplateTypeReference {
+
+ private SimpleTypeReference template;
+
+ private int position;
+
+ public SimpleTypeReference TemplateType {
+ get {
+ return (template);
+ }
+ }
+
+ public int Position {
+ get {
+ return (position);
+ }
+ }
+
+ internal TypeTemplateTypeReference (SimpleTypeReference template, int position) {
+ if (template == null) throw new ArgumentNullException("template");
+ if (position < 0) throw new ArgumentOutOfRangeException("position");
+ this.template = template;
+ this.position = position;
+ }
+
+ }
+
+ public class MethodTemplateTypeReference : TemplateTypeReference {
+
+ private MemberReference template;
+
+ private int position;
+
+ public MemberReference TemplateMethod {
+ get {
+ return (template);
+ }
+ }
+
+ public int Position {
+ get {
+ return (position);
+ }
+ }
+
+ internal MethodTemplateTypeReference (MemberReference template, int position) {
+ this.template = template;
+ this.position = position;
+ }
+
+ }
+
+ public class ArrayTypeReference : TypeReference {
+
+ private int rank;
+
+ private TypeReference elementType;
+
+ public int Rank {
+ get {
+ return(rank);
+ }
+ }
+
+ public TypeReference ElementType {
+ get {
+ return(elementType);
+ }
+ }
+
+ internal ArrayTypeReference (TypeReference elementType, int rank) {
+ if (elementType == null) throw new ArgumentNullException("elementType");
+ if (rank <= 0) throw new ArgumentOutOfRangeException("rank");
+ this.elementType = elementType;
+ this.rank = rank;
+ }
+
+ }
+
+ public class ReferenceTypeReference : TypeReference {
+
+ private TypeReference referedToType;
+
+ public TypeReference ReferedToType {
+ get {
+ return (referedToType);
+ }
+ }
+
+ internal ReferenceTypeReference (TypeReference referedToType) {
+ if (referedToType == null) throw new ArgumentNullException("referedToType");
+ this.referedToType = referedToType;
+ }
+ }
+
+ public class PointerTypeReference : TypeReference {
+
+ private TypeReference pointedToType;
+
+ public TypeReference PointedToType {
+ get {
+ return (pointedToType);
+ }
+ }
+
+ internal PointerTypeReference (TypeReference pointedToType) {
+ if (pointedToType == null) throw new ArgumentNullException("pointedToType");
+ this.pointedToType = pointedToType;
+ }
+ }
+
+
+ public abstract class MemberReference : Reference { }
+
+ /// <summary>
+ /// Contains the information to generate the display string for an extension method link
+ /// </summary>
+ public class ExtensionMethodReference : Reference
+ {
+ private string methodName;
+ public string Name
+ {
+ get
+ {
+ return (methodName);
+ }
+ }
+
+ private Parameter[] parameters;
+ public Parameter[] Parameters
+ {
+ get
+ {
+ return (parameters);
+ }
+ }
+
+ private TypeReference[] templateArgs;
+ public TypeReference[] TemplateArgs
+ {
+ get
+ {
+ return (templateArgs);
+ }
+ }
+
+ internal ExtensionMethodReference(string methodName, Parameter[] parameters, TypeReference[] templateArgs)
+ {
+ if (methodName == null)
+ throw new ArgumentNullException("methodName");
+ this.methodName = methodName;
+ this.parameters = parameters;
+ this.templateArgs = templateArgs;
+ }
+ }
+
+
+ public class SimpleMemberReference : MemberReference {
+
+ private string memberId;
+
+ public string Id {
+ get {
+ return(memberId);
+ }
+ }
+
+ public Target Resolve (TargetCollection targets) {
+ return(targets[memberId]);
+ }
+
+ internal SimpleMemberReference (string id) {
+ if (id == null) throw new ArgumentNullException("id");
+ this.memberId = id;
+ }
+
+ }
+
+
+ public class SpecializedMemberReference : MemberReference {
+
+ private SimpleMemberReference member;
+
+ private SpecializedTypeReference type;
+
+ public SimpleMemberReference TemplateMember {
+ get {
+ return(member);
+ }
+ }
+
+ public SpecializedTypeReference SpecializedType {
+ get {
+ return (type);
+ }
+ }
+
+ internal SpecializedMemberReference (SimpleMemberReference member, SpecializedTypeReference type) {
+ if (member == null) throw new ArgumentNullException("member");
+ if (type == null) throw new ArgumentNullException("type");
+ this.member = member;
+ this.type = type;
+ }
+
+ }
+
+ public class SpecializedMemberWithParametersReference : MemberReference {
+
+ private string prefix;
+
+ private SpecializedTypeReference type;
+
+ private string member;
+
+ private TypeReference[] parameters;
+
+ public string Prefix {
+ get {
+ return (prefix);
+ }
+ }
+
+ public SpecializedTypeReference SpecializedType {
+ get {
+ return (type);
+ }
+ }
+
+ public string MemberName {
+ get {
+ return (member);
+ }
+ }
+
+ public TypeReference[] ParameterTypes {
+ get {
+ return(parameters);
+ }
+ }
+
+ internal SpecializedMemberWithParametersReference (string prefix, SpecializedTypeReference type, string member, TypeReference[] parameters) {
+ if (type == null) throw new ArgumentNullException("type");
+ if (parameters == null) throw new ArgumentNullException("parameters");
+ this.prefix = prefix;
+ this.type = type;
+ this.member = member;
+ this.parameters = parameters;
+ }
+
+ }
+
+ public class InvalidReference : Reference {
+
+ private string id;
+
+ public String Id {
+ get {
+ return (id);
+ }
+ }
+
+ internal InvalidReference (string id) {
+ this.id = id;
+ }
+
+ }
+
+ // ***** Logic to construct Target & Reference objects from XML reflection data *****
+ // Anything that depends on specifics of the XML reflection data format lives here
+
+ public static class XmlTargetCollectionUtilities {
+
+ // XPath expressions for extracting data
+
+ // topic data
+ private static XPathExpression topicIdExpression = XPathExpression.Compile("string(@id)");
+ private static XPathExpression topicContainerExpression = XPathExpression.Compile("string(containers/library/@assembly)");
+ private static XPathExpression topicFileExpression = XPathExpression.Compile("string(file/@name)");
+ private static XPathExpression topicGroupExpression = XPathExpression.Compile("string(topicdata/@group)");
+
+ // api data
+ private static XPathExpression apiNameExpression = XPathExpression.Compile("string(apidata/@name)");
+ private static XPathExpression apiGroupExpression = XPathExpression.Compile("string(apidata/@group)");
+ private static XPathExpression apiSubgroupExpression = XPathExpression.Compile("string(apidata/@subgroup)");
+ private static XPathExpression apiSubsubgroupExpression = XPathExpression.Compile("string(apidata/@subsubgroup)");
+
+ // member data
+ private static XPathExpression apiOverloadIdExpression = XPathExpression.Compile("string(overload/@api | memberdata/@overload)");
+
+ // explicit implmentation data
+ private static XPathExpression apiIsExplicitImplementationExpression = XPathExpression.Compile("boolean(memberdata/@visibility='private' and proceduredata/@virtual='true' and boolean(implements/member))");
+ private static XPathExpression apiImplementedMembersExpression = XPathExpression.Compile("implements/member");
+
+ // op_explicit and op_implicit data
+ private static XPathExpression apiIsConversionOperatorExpression = XPathExpression.Compile("boolean((apidata/@subsubgroup='operator') and (apidata/@name='Explicit' or apidata/@name='Implicit'))");
+
+ // container data
+ private static XPathExpression apiContainingNamespaceExpression = XPathExpression.Compile("(containers/namespace)[1]");
+ private static XPathExpression apiContainingTypeExpression = XPathExpression.Compile("(containers/type)[1]");
+
+ // reference data
+ private static XPathExpression referenceApiExpression = XPathExpression.Compile("string(@api)");
+
+ // template data
+ private static XPathExpression apiTemplatesExpression = XPathExpression.Compile("templates/template");
+ private static XPathExpression templateNameExpression = XPathExpression.Compile("string(@name)");
+
+ // extension method template data
+ private static XPathExpression methodTemplateArgsExpression = XPathExpression.Compile("templates/*");
+
+ // Change the container
+
+ public static string ContainerExpression {
+ get {
+ return (topicContainerExpression.Expression);
+ }
+ set {
+ topicContainerExpression = XPathExpression.Compile(value);
+ }
+ }
+
+ // super factory method
+
+ public static void AddTargets (TargetCollection targets, XPathNavigator topicsNode, LinkType2 type) {
+ XPathNodeIterator topicNodes = topicsNode.Select("/*/apis/api[not(topicdata/@notopic)]");
+ foreach (XPathNavigator topicNode in topicNodes) {
+ Target target = CreateTarget(topicNode, type);
+ if (target != null) target.Add(targets);
+ }
+ }
+
+ // Target factory methods
+
+ public static Target CreateTarget (XPathNavigator topic, LinkType2 type) {
+ if (topic == null) throw new ArgumentNullException("topic");
+
+ bool isApiTarget = (bool)topic.Evaluate("boolean(apidata)");
+
+ Target target;
+ if (isApiTarget) {
+ target = CreateApiTarget(topic, type);
+ } else {
+ target = new Target();
+ }
+
+ if (target == null) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));
+
+ target.id = (string)topic.Evaluate(topicIdExpression);
+ if (String.IsNullOrEmpty(target.id)) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));
+
+ target.container = (string)topic.Evaluate(topicContainerExpression);
+
+ target.file = (string)topic.Evaluate(topicFileExpression);
+ if (String.IsNullOrEmpty(target.file)) throw new XmlSchemaValidationException(String.Format("The target file '{0}' is not valid.", topic.BaseURI));
+
+ target.type = type;
+
+ return(target);
+ }
+
+ private static Target CreateApiTarget (XPathNavigator api, LinkType2 linkType) {
+ string subGroup = (string) api.Evaluate(apiGroupExpression);
+ if (subGroup == "namespace") {
+ return( CreateNamespaceTarget(api) );
+ } else if (subGroup == "type") {
+ return (CreateTypeTarget(api, linkType));
+ } else if (subGroup == "member") {
+ return (CreateMemberTarget(api));
+ } else {
+ return (null);
+ }
+
+ }
+
+ private static NamespaceTarget CreateNamespaceTarget (XPathNavigator api) {
+ NamespaceTarget target = new NamespaceTarget();
+ target.name = (string) api.Evaluate(apiNameExpression);
+ if (String.IsNullOrEmpty(target.name)) target.name = "(Default Namespace)";
+ return(target);
+ }
+
+ private static TypeTarget CreateTypeTarget (XPathNavigator api, LinkType2 linkType) {
+ string subgroup = (string)api.Evaluate(apiSubgroupExpression);
+
+ TypeTarget target;
+ if (subgroup == "enumeration") {
+ target = CreateEnumerationTarget(api, linkType);
+ } else {
+ target = new TypeTarget();
+ }
+
+ target.name = (string) api.Evaluate(apiNameExpression);
+
+ // containing namespace
+ XPathNavigator namespaceNode = api.SelectSingleNode(apiContainingNamespaceExpression);
+ target.containingNamespace = CreateNamespaceReference(namespaceNode);
+
+ // containing type, if any
+ XPathNavigator typeNode = api.SelectSingleNode(apiContainingTypeExpression);
+ if (typeNode == null) {
+ target.containingType = null;
+ } else {
+ target.containingType = CreateSimpleTypeReference(typeNode);
+ }
+
+ // templates
+ target.templates = GetTemplateNames(api);
+
+ return(target);
+ }
+
+ private static string[] GetTemplateNames (XPathNavigator api) {
+ List<string> templates = new List<string>();
+ XPathNodeIterator templateNodes = api.Select(apiTemplatesExpression);
+ foreach (XPathNavigator templateNode in templateNodes) {
+ templates.Add((string)templateNode.Evaluate(templateNameExpression));
+ }
+ return(templates.ToArray());
+ }
+
+ private static EnumerationTarget CreateEnumerationTarget (XPathNavigator api, LinkType2 linkType) {
+
+ EnumerationTarget enumeration = new EnumerationTarget();
+
+ string typeId = (string) api.Evaluate(topicIdExpression);
+ string file = (string) api.Evaluate(topicFileExpression);
+
+ // Create tar
+ List<MemberTarget> members = new List<MemberTarget>();
+ XPathNodeIterator elementNodes = api.Select("elements/element");
+ foreach (XPathNavigator elementNode in elementNodes) {
+ string memberId = elementNode.GetAttribute("api", String.Empty);
+
+ // try to get name from attribute on element node
+ string memberName = elementNode.GetAttribute("name", String.Empty);
+ if (String.IsNullOrEmpty(memberName)) {
+ // if we can't do that, try to get the name by searching the file for the <api> element of that member
+ XPathNavigator memberApi = api.SelectSingleNode(String.Format("following-sibling::api[@id='{0}']", memberId));
+ if (memberApi != null) {
+ memberName = (string) memberApi.Evaluate(apiNameExpression);
+ } else {
+ // if all else fails, get the name by parsing the identifier
+ string arguments;
+ string type;
+ TextReferenceUtilities.DecomposeMemberIdentifier(memberId, out type, out memberName, out arguments);
+ }
+ }
+
+ MemberTarget member = new MemberTarget();
+ member.id = memberId; // get Id from element
+ member.file = file; // get file from type file
+ member.type = linkType;
+ member.name = memberName; // get name from element
+ member.containingType = new SimpleTypeReference(typeId); // get containing type from this type
+ members.Add(member);
+ }
+
+ enumeration.elements = members.ToArray();
+
+ return (enumeration);
+ }
+
+ public static MemberTarget CreateMemberTarget (XPathNavigator api) {
+
+ string subgroup = (string)api.Evaluate(apiSubgroupExpression);
+
+ MemberTarget target;
+ if (subgroup == "method") {
+ target = CreateMethodTarget(api);
+ } else if (subgroup == "property") {
+ target = CreatePropertyTarget(api);
+ } else if (subgroup == "constructor") {
+ target = CreateConstructorTarget(api);
+ } else if (subgroup == "event") {
+ target = CreateEventTarget(api);
+ } else {
+ target = new MemberTarget();
+ }
+
+ target.name = (string) api.Evaluate(apiNameExpression);
+ target.containingType = CreateSimpleTypeReference( api.SelectSingleNode(apiContainingTypeExpression) );
+ target.overload = (string) api.Evaluate(apiOverloadIdExpression);
+
+ return (target);
+ }
+
+ private static MethodTarget CreateMethodTarget (XPathNavigator api) {
+ MethodTarget target = new MethodTarget();
+ target.parameters = CreateParameterList(api);
+ target.returnType = CreateReturnType(api);
+
+ target.conversionOperator = (bool)api.Evaluate(apiIsConversionOperatorExpression);
+
+ if ((bool)api.Evaluate(apiIsExplicitImplementationExpression)) {
+ target.explicitlyImplements = CreateMemberReference(api.SelectSingleNode(apiImplementedMembersExpression));
+ }
+
+ // this selects templates/template or templates/type, because extension methods can have a mix of generic and specialization
+ XPathNodeIterator templateArgNodes = api.Select(methodTemplateArgsExpression);
+ TypeReference[] templateArgumentReferences = null;
+ if (templateArgNodes != null && templateArgNodes.Count > 0)
+ {
+ templateArgumentReferences = new TypeReference[templateArgNodes.Count];
+ int i = 0;
+ foreach (XPathNavigator templateArgNode in templateArgNodes)
+ {
+ templateArgumentReferences[i] = CreateTypeReference(templateArgNode);
+ i++;
+ }
+ }
+ target.templateArgs = templateArgumentReferences;
+
+ // get the short name of each template param
+ target.templates = GetTemplateNames(api);
+
+ return (target);
+ }
+
+ private static PropertyTarget CreatePropertyTarget (XPathNavigator api) {
+ PropertyTarget target = new PropertyTarget();
+ target.parameters = CreateParameterList(api);
+ target.returnType = CreateReturnType(api);
+
+ if ((bool)api.Evaluate(apiIsExplicitImplementationExpression)) {
+ target.explicitlyImplements = CreateMemberReference(api.SelectSingleNode(apiImplementedMembersExpression));
+ }
+
+ return (target);
+ }
+
+ private static EventTarget CreateEventTarget (XPathNavigator api) {
+ EventTarget target = new EventTarget();
+ if ((bool)api.Evaluate(apiIsExplicitImplementationExpression)) {
+ target.explicitlyImplements = CreateMemberReference(api.SelectSingleNode(apiImplementedMembersExpression));
+ }
+ return (target);
+ }
+
+ private static ConstructorTarget CreateConstructorTarget (XPathNavigator api) {
+ ConstructorTarget target = new ConstructorTarget();
+ target.parameters = CreateParameterList(api);
+ return (target);
+ }
+
+ private static Parameter[] CreateParameterList (XPathNavigator api) {
+ List<Parameter> parameters = new List<Parameter>();
+ XPathNodeIterator parameterNodes = api.Select("parameters/parameter");
+ foreach (XPathNavigator parameterNode in parameterNodes) {
+ string name = parameterNode.GetAttribute("name", String.Empty);
+ XPathNavigator type = parameterNode.SelectSingleNode("*[1]");
+ Parameter parameter = new Parameter(name, CreateTypeReference(type));
+ parameters.Add(parameter);
+ }
+ return (parameters.ToArray());
+ }
+
+ private static TypeReference CreateReturnType (XPathNavigator api) {
+ XPathNavigator returnTypeNode = api.SelectSingleNode("returns/*[1]");
+ if (returnTypeNode == null) {
+ return (null);
+ } else {
+ return (CreateTypeReference(returnTypeNode));
+ }
+ }
+
+ // reference factory
+
+ public static Reference CreateReference (XPathNavigator node) {
+ if (node == null) throw new ArgumentNullException("node");
+ if (node.NodeType == XPathNodeType.Element) {
+ string tag = node.LocalName;
+ if (tag == "namespace") return(CreateNamespaceReference(node));
+ if (tag == "member") return (CreateMemberReference(node));
+ return (CreateTypeReference(node));
+ } else {
+ return (null);
+ }
+ }
+
+ public static NamespaceReference CreateNamespaceReference (XPathNavigator namespaceElement) {
+ if (namespaceElement == null) throw new ArgumentNullException("namespaceElement");
+ string api = (string) namespaceElement.Evaluate(referenceApiExpression);
+ NamespaceReference reference = new NamespaceReference(api);
+ return(reference);
+ }
+
+ public static TypeReference CreateTypeReference (XPathNavigator node) {
+ if (node == null) throw new ArgumentNullException("reference");
+ string tag = node.LocalName;
+ if (tag == "type") {
+ bool isSpecialized = (bool)node.Evaluate("boolean(.//specialization)");
+ if (isSpecialized) {
+ return (CreateSpecializedTypeReference(node));
+ } else {
+ return (CreateSimpleTypeReference(node));
+ }
+ } else if (tag == "arrayOf") {
+ string rankValue = node.GetAttribute("rank", String.Empty);
+ XPathNavigator elementNode = node.SelectSingleNode("*[1]");
+ return (new ArrayTypeReference(CreateTypeReference(elementNode), Convert.ToInt32(rankValue)));
+ } else if (tag == "referenceTo") {
+ XPathNavigator referedToNode = node.SelectSingleNode("*[1]");
+ return (new ReferenceTypeReference(CreateTypeReference(referedToNode)));
+ } else if (tag == "pointerTo") {
+ XPathNavigator pointedToNode = node.SelectSingleNode("*[1]");
+ return (new PointerTypeReference(CreateTypeReference(pointedToNode)));
+ } else if (tag == "template") {
+ string nameValue = node.GetAttribute("name", String.Empty);
+ string indexValue = node.GetAttribute("index", String.Empty);
+ string apiValue = node.GetAttribute("api", String.Empty);
+ if ((!String.IsNullOrEmpty(apiValue)) && (!String.IsNullOrEmpty(indexValue))) {
+ return (new IndexedTemplateTypeReference(apiValue, Convert.ToInt32(indexValue)));
+ } else {
+ return (new NamedTemplateTypeReference(nameValue));
+ }
+ }
+
+ throw new InvalidOperationException(String.Format("INVALID '{0}'", tag));
+
+ }
+
+ public static SimpleTypeReference CreateSimpleTypeReference (XPathNavigator node) {
+ if (node == null) throw new ArgumentNullException("node");
+ string api = node.GetAttribute("api", String.Empty);
+ SimpleTypeReference reference = new SimpleTypeReference(api);
+ return(reference);
+ }
+
+
+ private static SpecializedTypeReference CreateSpecializedTypeReference (XPathNavigator node) {
+ Stack<Specialization> specializations = new Stack<Specialization>();
+ XPathNavigator typeNode = node.Clone();
+ while (typeNode != null) {
+ specializations.Push(CreateSpecialization(typeNode));
+ typeNode = typeNode.SelectSingleNode("type");
+ }
+ SpecializedTypeReference reference = new SpecializedTypeReference(specializations.ToArray());
+ return (reference);
+ }
+
+ private static Specialization CreateSpecialization (XPathNavigator node) {
+ SimpleTypeReference template = CreateSimpleTypeReference(node);
+
+ List<TypeReference> arguments = new List<TypeReference>();
+ XPathNodeIterator specializationNodes = node.Select("specialization/*");
+ foreach (XPathNavigator specializationNode in specializationNodes) {
+ arguments.Add(CreateTypeReference(specializationNode));
+ }
+
+ Specialization specialization = new Specialization(template, arguments.ToArray());
+ return(specialization);
+ }
+
+
+ public static MemberReference CreateMemberReference (XPathNavigator node) {
+ string api = node.GetAttribute("api", String.Empty);
+ SimpleMemberReference member = new SimpleMemberReference(api);
+
+ bool isSpecialized = (bool)node.Evaluate("boolean(./type//specialization)");
+ if (isSpecialized) {
+ XPathNavigator typeNode = node.SelectSingleNode("type");
+ SpecializedTypeReference type = CreateSpecializedTypeReference(typeNode);
+ return( new SpecializedMemberReference(member, type) );
+ } else {
+ return(member);
+ }
+
+ }
+
+ /// <summary>
+ /// Create an object to store the information to generate the display string for an extension method
+ /// </summary>
+ /// <param name="node">xml node containing the extension method data</param>
+ /// <returns></returns>
+ public static ExtensionMethodReference CreateExtensionMethodReference(XPathNavigator node)
+ {
+ string methodName = (string)node.Evaluate(apiNameExpression);
+ Parameter[] parameters = CreateParameterList(node);
+ TypeReference[] templateArgumentReferences = null;
+ // List<TemplateName> templateNames = new List<TemplateName>();
+
+ // this selects templates/template or templates/type, because extension methods can have a mix of generic and specialization
+ // get the short name of each template param or template arg
+ XPathNodeIterator templateNodes = node.Select(methodTemplateArgsExpression);
+ if (templateNodes != null && templateNodes.Count > 0)
+ {
+ templateArgumentReferences = new TypeReference[templateNodes.Count];
+ int i = 0;
+ foreach (XPathNavigator templateNode in templateNodes)
+ {
+ templateArgumentReferences[i] = CreateTypeReference(templateNode);
+ i++;
+ }
+ }
+ ExtensionMethodReference extMethod = new ExtensionMethodReference(methodName, parameters, templateArgumentReferences);
+ return extMethod;
+ }
+
+ }
+
+ // ***** Logic for constructing references from code entity reference strings *****
+ // Anything that depends on the specific form the ID strings lives here
+
+ public static class TextReferenceUtilities {
+
+ public static Reference CreateReference (string api) {
+ if (String.IsNullOrEmpty(api)) throw new ArgumentException("api");
+
+ Reference reference = null;
+
+ char start = api[0];
+ if (start == 'N') {
+ reference = CreateNamespaceReference(api);
+ } else if (start == 'T') {
+ reference = CreateTypeReference(api);
+ } else {
+ //Console.WriteLine("Creating member reference");
+ reference = CreateMemberReference(api);
+ }
+
+ if (reference == null) {
+ return (new InvalidReference(api));
+ } else {
+ return (reference);
+ }
+
+ }
+
+ public static NamespaceReference CreateNamespaceReference (string api) {
+ if (ValidNamespace.IsMatch(api)) {
+ return( new NamespaceReference(api) );
+ } else {
+ return(null);
+ }
+ }
+
+ public static TypeReference CreateTypeReference (string api) {
+ if (ValidSimpleType.IsMatch(api)) {
+ // this is a reference to a "normal" simple type
+ return (CreateSimpleTypeReference(api));
+ } else if (ValidSpecializedType.IsMatch(api)) {
+ // this is a reference to a specialized type
+ return (CreateSpecializedTypeReference(api));
+ } else if (ValidDecoratedType.IsMatch(api)) {
+ // this is a reference to a type that is decorated or is a template
+ // process array, reference, and pointer decorations
+ char lastCharacter = api[api.Length-1];
+ if (lastCharacter == ']') {
+ // arrays
+ int lastBracketPosition = api.LastIndexOf('[');
+ int rank = api.Length - lastBracketPosition - 1;
+ string elementApi = api.Substring(0, lastBracketPosition);
+ TypeReference elementReference = CreateTypeReference(elementApi);
+ return( new ArrayTypeReference(elementReference, rank) );
+ } else if (lastCharacter == '@') {
+ // references
+ string referedApi = api.Substring(0, api.Length - 1);
+ TypeReference referedReference = CreateTypeReference(referedApi);
+ return (new ReferenceTypeReference(referedReference));
+ } else if (lastCharacter == '*') {
+ // pointers
+ string pointedApi = api.Substring(0, api.Length - 1);
+ TypeReference pointedReference = CreateTypeReference(pointedApi);
+ return (new PointerTypeReference(pointedReference));
+ }
+
+ // process templates
+ if (api.StartsWith("T:``")) {
+ int position = Convert.ToInt32(api.Substring(4));
+ if (genericTypeContext == null) {
+ return (new NamedTemplateTypeReference("UMP"));
+ } else {
+ return (new IndexedTemplateTypeReference(genericTypeContext.Id, position));
+ }
+ } else if (api.StartsWith("T:`")) {
+ int position = Convert.ToInt32(api.Substring(3));
+ if (genericTypeContext == null) {
+ return (new NamedTemplateTypeReference("UTP"));
+ } else {
+ return (new IndexedTemplateTypeReference(genericTypeContext.Id, position));
+ }
+ }
+
+ // we shouldn't get here, because one of those test should have been satisfied if the regex matched
+ throw new InvalidOperationException("Could not parse valid type expression");
+
+ } else {
+ return (null);
+ }
+ }
+
+ private static SimpleTypeReference CreateSimpleTypeReference (string api) {
+ return (new SimpleTypeReference(api));
+ }
+
+ private static SpecializedTypeReference CreateSpecializedTypeReference (string api) {
+
+ List<Specialization> specializations = new List<Specialization>();
+
+ string text = String.Copy(api);
+
+ // at the moment we are only handling one specialization; need to iterate
+
+ int specializationStart = text.IndexOf('{');
+ int specializationEnd = FindMatchingEndBracket(text, specializationStart);
+ string list = text.Substring(specializationStart + 1, specializationEnd - specializationStart - 1);
+ string[] types = SeperateTypes(list);
+ string template = text.Substring(0, specializationStart) + String.Format("`{0}", types.Length);
+
+
+ SimpleTypeReference templateReference = CreateSimpleTypeReference(template);
+ TypeReference[] argumentReferences = new TypeReference[types.Length];
+ for (int i = 0; i < types.Length; i++) {
+ argumentReferences[i] = CreateTypeReference(types[i]);
+ }
+ Specialization specialization = new Specialization(templateReference, argumentReferences);
+
+ specializations.Add(specialization);
+
+ // end iteration
+
+ return (new SpecializedTypeReference(specializations.ToArray()));
+ }
+
+ //private static Regex tr = new Regex(@"^(M:([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{.+\})?\.)*[_a-zA-Z0-9]+(\{.+\})?\.([_a-zA-Z0-9]+(\{[^\.]+\})?#)*[_a-zA-Z0-9]+(``\d+)?(\((((([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{.+\})?\.)*[_a-zA-Z0-9]+(\{.+\})?)|(`\d+)|(``\d+))(@|\*|(\[\]))*,)*((([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{.+\})?\.)*[_a-zA-Z0-9]+(\{.+\})?)|(`\d+)|(``\d+))(@|\*|(\[\]))*\))?(~((([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{.+\})?\.)*[_a-zA-Z0-9]+(\{.+\})?)|(`\d+)|(``\d+))(@|\*|(\[\]))*)?)$", RegexOptions.Compiled);
+ //private static Regex tr = new Regex(@"^(M:([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?\.)*[_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?\.[_a-zA-Z0-9]+(``\d+)?(\((((([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?\.)*[_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?)|(`\d+)|(``\d+))(@|\*|(\[\]))*,)*((([_a-zA-Z0-9]+\.)*([_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?\.)*[_a-zA-Z0-9]+(\{[^:\(\)\s]+\})?)|(`\d+)|(``\d+))(@|\*|(\[\]))*\))?)$", RegexOptions.Compiled);
+ private static Regex tr = new Regex(@"^(M:([_a-zA-Z0-9]+\.)*[_a-zA-Z0-9]+\.[_a-zA-Z0-9]+(``\d+)?(\((((([_a-zA-Z0-9]+\.)*[_a-zA-Z0-9]+)|(`\d+)|(``\d+))(@|\*|(\[\]))*,)*((([_a-zA-Z0-9]+\.)*[_a-zA-Z0-9]+)|(`\d+)|(``\d+))(@|\*|(\[\]))*\))?)$", RegexOptions.Compiled);
+
+ public static MemberReference CreateMemberReference (string api) {
+ //Console.WriteLine("Testing");
+ //Console.WriteLine(tr.ToString());
+ //Console.WriteLine(api);
+ //Console.WriteLine(tr.IsMatch(api));
+ //Console.WriteLine("Tested");
+ if (ValidSimpleMember.IsMatch(api)) {
+ //Console.WriteLine("Is valid simple member");
+ // this is just a normal member of a simple type
+ return (new SimpleMemberReference(api));
+ } else if (ValidSpecializedMember.IsMatch(api)) {
+ //Console.WriteLine("Is valid specialized member");
+ //Console.WriteLine("cer = {0}", api);
+ // this is a member of a specialized type; we need to extract:
+ // (1) the underlying specialized type, (2) the member name, (3) the arguments
+ //Console.WriteLine("Extracting data");
+
+ // seperate the member prefix
+ int colonPosition = api.IndexOf(':');
+ string prefix = api.Substring(0, colonPosition);
+ string text = api.Substring(colonPosition + 1);
+
+ // get the arguments
+ string arguments = String.Empty;
+ int startParenthesisPosition = text.IndexOf('(');
+ if (startParenthesisPosition > 0) {
+ int endParenthesisPosition = text.LastIndexOf(')');
+ arguments = text.Substring(startParenthesisPosition + 1, endParenthesisPosition - startParenthesisPosition - 1);
+ text = text.Substring(0, startParenthesisPosition);
+ }
+
+ // seperate the type and member name
+ int lastDotPosition;
+ int firstHashPosition = text.IndexOf('#');
+ if (firstHashPosition > 0) {
+ // if this is an EII, the boundry is at the last dot before the hash
+ lastDotPosition = text.LastIndexOf('.', firstHashPosition);
+ } else {
+ // otherwise, the boundry is at the last dot
+ lastDotPosition = text.LastIndexOf('.');
+ }
+ string name = text.Substring(lastDotPosition+1);
+ text = text.Substring(0, lastDotPosition);
+ //Console.WriteLine("type = {0}", "T:" + text);
+
+ // text now contains a specialized generic type; use it to create a reference
+ SpecializedTypeReference type = CreateSpecializedTypeReference("T:" + text);
+
+ // If there are no arguments...
+ // we simply create a reference to a member whoose identifier we construct in the specialized type
+ if (String.IsNullOrEmpty(arguments)) {
+ string typeId = type.Specializations[type.Specializations.Length - 1].TemplateType.Id;
+ string memberId = String.Format("{0}:{1}.{2}", prefix, typeId.Substring(2), name);
+ SimpleMemberReference member = new SimpleMemberReference(memberId);
+ return (new SpecializedMemberReference(member, type));
+ }
+
+ // If there are arguments... life is not so simple. We can't be sure we can identify the
+ // corresponding member of the template type because any particular type that appears in
+ // the argument might have come from the template or it might have come from the specialization.
+ // We need to create a special kind of reference to handle this situation.
+ //Console.WriteLine("Specialized member with arguments '{0}'", api);
+ string[] parameterTypeCers = SeperateTypes(arguments);
+ TypeReference[] parameterTypes = new TypeReference[parameterTypeCers.Length];
+ for (int i = 0; i < parameterTypeCers.Length; i++) {
+ parameterTypes[i] = CreateTypeReference(parameterTypeCers[i]);
+ }
+ return (new SpecializedMemberWithParametersReference(prefix, type, name, parameterTypes));
+
+ } else {
+ //Console.WriteLine("No match");
+ return (null);
+ //throw new InvalidOperationException(String.Format("Invalid member '{0}'", api));
+ }
+
+ }
+
+ // Template context logic
+
+ private static SimpleTypeReference genericTypeContext = null;
+
+ private static SimpleMemberReference genericMemberContext = null;
+
+ public static void SetGenericContext (string cer) {
+ //Console.WriteLine("context = {0}", cer);
+
+ // re-set the context
+ genericTypeContext = null;
+ genericMemberContext = null;
+
+ // get the new context
+ Reference context = CreateReference(cer);
+ if (context == null) return;
+
+ // if it is a type context, set it to be the type context
+ SimpleTypeReference typeContext = context as SimpleTypeReference;
+ if (typeContext != null) {
+ genericTypeContext = typeContext;
+ return;
+ }
+
+ // if it is a member context, set it to be the member context and use it to obtain a type context, too
+ SimpleMemberReference memberContext = context as SimpleMemberReference;
+ if (memberContext != null) {
+ genericMemberContext = memberContext;
+
+ string typeId, memberName, arguments;
+ DecomposeMemberIdentifier(memberContext.Id, out typeId, out memberName, out arguments);
+ genericTypeContext = CreateSimpleTypeReference(typeId);
+ return;
+ }
+
+ }
+
+ public static SimpleTypeReference GenericContext {
+ get {
+ return (genericTypeContext);
+ }
+ }
+
+ // Code entity reference validation logic
+
+ // iterate -> specializedTypePattern -> decoratedTypePattern -> decoratedTypeListPattern
+ // to get a patterns that enforce the contents of specialization brackets
+
+ static TextReferenceUtilities () {
+
+ string namePattern = @"[_a-zA-Z0-9]+";
+
+ // namespace patterns
+
+ string namespacePattern = String.Format(@"({0}\.)*({0})?", namePattern);
+
+ string optionalNamespacePattern = String.Format(@"({0}\.)*", namePattern);
+
+ // type patterns
+
+ string simpleTypePattern = String.Format(@"{0}({1}(`\d+)?\.)*{1}(`\d+)?", optionalNamespacePattern, namePattern);
+
+ //string specializedTypePattern = String.Format(@"{0}({1}(\{{.+\}})?\.)*{1}(\{{.+\}})?", optionalNamespacePattern, namePattern);
+ string specializedTypePattern = String.Format(@"({0}(\{{.+\}})?\.)*{0}(\{{.+\}})?", namePattern);
+
+ string baseTypePattern = String.Format(@"({0})|({1})", simpleTypePattern, specializedTypePattern);
+
+ string decoratedTypePattern = String.Format(@"(({0})|(`\d+)|(``\d+))(@|\*|(\[\]))*", specializedTypePattern);
+
+ string decoratedTypeListPattern = String.Format(@"({0},)*{0}", decoratedTypePattern);
+
+ string explicitInterfacePattern = String.Format(@"({0}(\{{[^\.]+\}})?#)*", namePattern);
+
+ // members of non-specialized types
+
+ string simpleFieldPattern = String.Format(@"{0}\.{1}", simpleTypePattern, namePattern);
+
+ string simpleEventPattern = String.Format(@"{0}\.{1}{2}", simpleTypePattern, explicitInterfacePattern, namePattern);
+
+ string simplePropertyPattern = String.Format(@"{0}\.{1}{2}(\({3}\))?", simpleTypePattern, explicitInterfacePattern, namePattern, decoratedTypeListPattern);
+
+ string simpleMethodPattern = String.Format(@"{0}\.{1}{2}(``\d+)?(\({3}\))?(~{4})?", simpleTypePattern, explicitInterfacePattern, namePattern, decoratedTypeListPattern, decoratedTypePattern);
+
+ string simpleConstructorPattern = String.Format(@"{0}\.#ctor(\({1}\))?", simpleTypePattern, decoratedTypeListPattern);
+
+ string simpleOverloadPattern = String.Format(@"{0}\.{1}{2}", simpleTypePattern, explicitInterfacePattern, namePattern);
+
+ string simpleConstructorOverloadPattern = String.Format(@"{0}\.#ctor", simpleTypePattern);
+
+ // members of specialized types
+
+ string specializedFieldPattern = String.Format(@"{0}\.{1}", specializedTypePattern, namePattern);
+
+ string specializedEventPattern = String.Format(@"{0}\.{1}{2}", specializedTypePattern, explicitInterfacePattern, namePattern);
+
+ string specializedPropertyPattern = String.Format(@"{0}\.{1}{2}(\({3}\))?", specializedTypePattern, explicitInterfacePattern, namePattern, decoratedTypeListPattern);
+
+ string specializedMethodPattern = String.Format(@"{0}\.{1}{2}(``\d+)?(\({3}\))?(~{4})?", specializedTypePattern, explicitInterfacePattern, namePattern, decoratedTypeListPattern, decoratedTypePattern);
+
+ string specializedOverloadPattern = String.Format(@"{0}\.{1}{2}", specializedTypePattern, explicitInterfacePattern, namePattern);
+
+ // create regexes using this patterns
+
+ ValidNamespace = new Regex( String.Format(@"^N:{0}$", namespacePattern), RegexOptions.Compiled );
+
+ ValidSimpleType = new Regex(String.Format(@"^T:{0}$", simpleTypePattern), RegexOptions.Compiled);
+
+ ValidDecoratedType = new Regex(String.Format(@"^T:{0}$", decoratedTypePattern), RegexOptions.Compiled);
+
+ ValidSpecializedType = new Regex(String.Format(@"^T:{0}$", specializedTypePattern), RegexOptions.Compiled);
+
+ ValidSimpleMember = new Regex(String.Format(@"^((M:{0})|(M:{1})|(P:{2})|(F:{3})|(E:{4})|(Overload:{5})|(Overload:{6}))$", simpleMethodPattern, simpleConstructorPattern, simplePropertyPattern, simpleFieldPattern, simpleEventPattern, simpleOverloadPattern, simpleConstructorOverloadPattern));
+
+ ValidSpecializedMember = new Regex(String.Format(@"^((M:{0})|(P:{1})|(F:{2})|(E:{3})|(Overload:{4}))$", specializedMethodPattern, specializedPropertyPattern, specializedFieldPattern, specializedEventPattern, specializedOverloadPattern));
+
+ ValidTest = new Regex(String.Format(@"^M:{0}\.{1}$", simpleTypePattern, namePattern));
+
+ }
+
+ private static Regex ValidNamespace;
+
+ private static Regex ValidSimpleType;
+
+ private static Regex ValidDecoratedType;
+
+ private static Regex ValidSpecializedType;
+
+ private static Regex ValidSimpleMember;
+
+ private static Regex ValidSpecializedMember;
+
+ private static Regex ValidTest;
+
+ // Code entity reference string manipulation utilities
+
+ internal static string[] SeperateTypes (string typelist) {
+ List<string> types = new List<string>();
+
+ int start = 0;
+ int specializationCount = 0;
+ for (int index = 0; index < typelist.Length; index++) {
+ switch (typelist[index]) {
+ case '{':
+ case '[':
+ specializationCount++;
+ break;
+ case '}':
+ case ']':
+ specializationCount--;
+ break;
+ case ',':
+ if (specializationCount == 0) {
+ types.Add("T:" + typelist.Substring(start, index - start).Trim());
+ start = index + 1;
+ }
+ break;
+ }
+ }
+ types.Add("T:" + typelist.Substring(start).Trim());
+ return (types.ToArray());
+ }
+
+ internal static void DecomposeMemberIdentifier (string memberCer, out string typeCer, out string memberName, out string arguments) {
+
+ // drop the member prefix
+ int colonPosition = memberCer.IndexOf(':');
+ string text = memberCer.Substring(colonPosition + 1);
+
+ // get the arguments
+ arguments = String.Empty;
+ int startParenthesisPosition = text.IndexOf('(');
+ if (startParenthesisPosition > 0) {
+ int endParenthesisPosition = text.LastIndexOf(')');
+ arguments = text.Substring(startParenthesisPosition + 1, endParenthesisPosition - startParenthesisPosition - 1);
+ text = text.Substring(0, startParenthesisPosition);
+ }
+
+ // seperate the type and member name
+ int lastDotPosition;
+ int firstHashPosition = text.IndexOf('#');
+ if (firstHashPosition > 0) {
+ // if this is an EII, the boundry is at the last dot before the hash
+ lastDotPosition = text.LastIndexOf('.', firstHashPosition);
+ } else {
+ // otherwise, the boundry is at the last dot
+ lastDotPosition = text.LastIndexOf('.');
+ }
+
+ memberName = text.Substring(lastDotPosition + 1);
+ typeCer = "T:" + text.Substring(0, lastDotPosition);
+ }
+
+ private static int FindMatchingEndBracket (string text, int position) {
+
+ if (text == null) throw new ArgumentNullException("text");
+ if ((position < 0) || (position >= text.Length)) throw new ArgumentOutOfRangeException("position", String.Format("The position {0} is not within the given text string.", position));
+ if (text[position] != '{') throw new InvalidOperationException(String.Format("Position {0} of the string '{1}' does not contain and ending curly bracket.", position, text));
+
+ int count = 1;
+ for (int index = position + 1; index < text.Length; index++) {
+ if (text[index] == '{') {
+ count++;
+ } else if (text[index] == '}') {
+ count--;
+ }
+
+ if (count == 0) return (index);
+ }
+
+ throw new FormatException("No opening brace matches the closing brace.");
+
+ }
+
+ // Writing link text for unresolved simple references
+
+ internal static void WriteNamespaceReference (NamespaceReference space, DisplayOptions options, XmlWriter writer) {
+ writer.WriteString(space.Id.Substring(2));
+ }
+
+ internal static void WriteSimpleTypeReference (SimpleTypeReference type, DisplayOptions options, XmlWriter writer) {
+
+ // this logic won't correctly deal with nested types, but type cer strings simply don't include that
+ // infomation, so this is out best guess under the assumption of a non-nested type
+
+ string cer = type.Id;
+
+ // get the name
+ string name;
+ int lastDotPosition = cer.LastIndexOf('.');
+ if (lastDotPosition > 0) {
+ // usually, the name will start after the last dot
+ name = cer.Substring(lastDotPosition + 1);
+ } else {
+ // but if there is no dot, this is a type in the default namespace and the name is everything after the colon
+ name = cer.Substring(2);
+ }
+
+ // remove any generic tics from the name
+ int tickPosition = name.IndexOf('`');
+ if (tickPosition > 0) name = name.Substring(0, tickPosition);
+
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ // work out namespace
+ }
+
+ writer.WriteString(name);
+
+ if ((options & DisplayOptions.ShowTemplates) > 0) {
+ // work out templates
+ }
+
+ }
+
+ internal static void WriteSimpleMemberReference (SimpleMemberReference member, DisplayOptions options, XmlWriter writer, LinkTextResolver resolver) {
+
+ string cer = member.Id;
+
+ string typeCer, memberName, arguments;
+ DecomposeMemberIdentifier(cer, out typeCer, out memberName, out arguments);
+
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ SimpleTypeReference type = CreateSimpleTypeReference(typeCer);
+ WriteSimpleTypeReference(type, options & ~DisplayOptions.ShowContainer, writer);
+ }
+
+ // change this so that we deal with EII names correctly, too
+ writer.WriteString(memberName);
+
+ if ((options & DisplayOptions.ShowParameters) > 0) {
+ string[] parameterTypeCers;
+ if (String.IsNullOrEmpty(arguments)) {
+ Parameter[] parameters = new Parameter[0];
+ resolver.WriteMethodParameters(parameters, writer);
+ } else {
+ parameterTypeCers = SeperateTypes(arguments);
+ Parameter[] parameters = new Parameter[parameterTypeCers.Length];
+ for (int i = 0; i < parameterTypeCers.Length; i++) {
+ TypeReference parameterType = CreateTypeReference(parameterTypeCers[i]);
+ if (parameterType == null) {
+ parameterType = new NamedTemplateTypeReference("UAT");
+ }
+ parameters[i] = new Parameter(String.Empty, parameterType);
+ }
+ resolver.WriteMethodParameters(parameters, writer);
+ }
+ }
+
+ }
+
+ }
+
+ // ***** Link text writing logic *****
+
+ public class LinkTextResolver {
+
+ public LinkTextResolver (TargetCollection targets) {
+ this.targets = targets;
+ }
+
+ private TargetCollection targets;
+
+ public void WriteTarget (Target target, DisplayOptions options, XmlWriter writer) {
+ if (target == null) throw new ArgumentNullException("target");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ NamespaceTarget space = target as NamespaceTarget;
+ if (space != null) {
+ WriteNamespaceTarget(space, options, writer);
+ return;
+ }
+
+ TypeTarget type = target as TypeTarget;
+ if (type != null) {
+ WriteTypeTarget(type, options, writer);
+ return;
+ }
+
+ MemberTarget member = target as MemberTarget;
+ if (member != null) {
+ WriteMemberTarget(member, options, writer);
+ return;
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ public void WriteNamespaceTarget (NamespaceTarget space, DisplayOptions options, XmlWriter writer) {
+ if (space == null) throw new ArgumentNullException("target");
+ if (writer == null) throw new ArgumentNullException("writer");
+ writer.WriteString(space.Name);
+ }
+
+ public void WriteTypeTarget (TypeTarget type, DisplayOptions options, XmlWriter writer) {
+ if (type == null) throw new ArgumentNullException("type");
+ if (writer == null) throw new ArgumentNullException("writer");
+ WriteTypeTarget(type, options, true, writer);
+ }
+
+ private void WriteTypeTarget (TypeTarget type, DisplayOptions options, bool showOuterType, XmlWriter writer) {
+
+ // write namespace, if containers are requested
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ WriteNamespace(type.Namespace, DisplayOptions.Default, writer);
+ WriteSeperator(writer);
+ }
+
+ // write outer type, if one exists
+ if (showOuterType && (type.OuterType != null)) {
+ WriteSimpleType(type.OuterType, DisplayOptions.Default, writer);
+ WriteSeperator(writer);
+ }
+
+ // write the type name
+ writer.WriteString(type.Name);
+
+ // write if template parameters, if they exist and we are requested
+ if ((options & DisplayOptions.ShowTemplates) > 0) {
+ WriteTemplateParameters(type.Templates, writer);
+ }
+ }
+
+ public void WriteMemberTarget (MemberTarget target, DisplayOptions options, XmlWriter writer) {
+ WriteMemberTarget(target, options, writer, null);
+ }
+
+
+ private void WriteMemberTarget (MemberTarget target, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+ if (target == null) throw new ArgumentNullException("target");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ TypeReference type = target.Type;
+ WriteType(type, options & ~DisplayOptions.ShowContainer, writer);
+ MethodTarget methodTarget = target as MethodTarget;
+ if (methodTarget != null) {
+ if (methodTarget.conversionOperator) {
+ writer.WriteString(" ");
+ } else {
+ WriteSeperator(writer);
+ }
+ } else {
+ WriteSeperator(writer);
+ }
+ }
+
+ // special logic for writing methods
+ MethodTarget method = target as MethodTarget;
+ if (method != null) {
+ WriteMethod(method, options, writer, dictionary);
+ return;
+ }
+
+ // special logic for writing properties
+ PropertyTarget property = target as PropertyTarget;
+ if (property != null) {
+ WriteProperty(property, options, writer);
+ return;
+ }
+
+ // special logic for writing constructors
+ ConstructorTarget constructor = target as ConstructorTarget;
+ if (constructor != null) {
+ WriteConstructor(constructor, options, writer);
+ return;
+ }
+
+ // special logic for writing events
+ EventTarget trigger = target as EventTarget;
+ if (trigger != null) {
+ WriteEvent(trigger, options, writer);
+ return;
+ }
+
+ // by default, just write name
+ writer.WriteString(target.Name);
+ }
+
+ public void WriteReference (Reference reference, DisplayOptions options, XmlWriter writer) {
+ if (reference == null) throw new ArgumentNullException("reference");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ NamespaceReference space = reference as NamespaceReference;
+ if (space != null) {
+ WriteNamespace(space, options, writer);
+ return;
+ }
+
+ TypeReference type = reference as TypeReference;
+ if (type != null) {
+ WriteType(type, options, writer);
+ return;
+ }
+
+ MemberReference member = reference as MemberReference;
+ if (member != null) {
+ WriteMember(member, options, writer);
+ return;
+ }
+
+ ExtensionMethodReference extMethod = reference as ExtensionMethodReference;
+ if (extMethod != null)
+ {
+ WriteExtensionMethod(extMethod, options, writer);
+ return;
+ }
+
+ InvalidReference invalid = reference as InvalidReference;
+ if (invalid != null) {
+ WriteInvalid(invalid, options, writer);
+ return;
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ public void WriteNamespace (NamespaceReference spaceReference, DisplayOptions options, XmlWriter writer) {
+ if (spaceReference == null) throw new ArgumentNullException("spaceReference");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ NamespaceTarget spaceTarget = spaceReference.Resolve(targets) as NamespaceTarget;
+ if (spaceTarget != null) {
+ WriteNamespaceTarget(spaceTarget, options, writer);
+ } else {
+ TextReferenceUtilities.WriteNamespaceReference(spaceReference, options, writer);
+ }
+ }
+
+ public void WriteType (TypeReference type, DisplayOptions options, XmlWriter writer) {
+ WriteType(type, options, writer, null);
+ }
+
+ private void WriteType (TypeReference type, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+
+ if (type == null) throw new ArgumentNullException("type");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ //Console.WriteLine("type {0}", type.GetType().FullName);
+
+ SimpleTypeReference simple = type as SimpleTypeReference;
+ if (simple != null) {
+ WriteSimpleType(simple, options, writer);
+ return;
+ }
+
+ SpecializedTypeReference specialized = type as SpecializedTypeReference;
+ if (specialized != null) {
+ WriteSpecializedType(specialized, options, writer);
+ return;
+ }
+
+ ArrayTypeReference array = type as ArrayTypeReference;
+ if (array != null) {
+ WriteArrayType(array, options, writer, dictionary);
+ return;
+ }
+
+ ReferenceTypeReference reference = type as ReferenceTypeReference;
+ if (reference != null) {
+ WriteReferenceType(reference, options, writer, dictionary);
+ return;
+ }
+
+ PointerTypeReference pointer = type as PointerTypeReference;
+ if (pointer != null) {
+ WritePointerType(pointer, options, writer, dictionary);
+ return;
+ }
+
+ TemplateTypeReference template = type as TemplateTypeReference;
+ if (template != null) {
+ WriteTemplateType(template, options, writer, dictionary);
+ return;
+ }
+
+ throw new InvalidOperationException("Unknown type reference type");
+
+ }
+
+ public void WriteSimpleType (SimpleTypeReference simple, DisplayOptions options, XmlWriter writer) {
+ WriteSimpleType(simple, options, true, writer);
+ }
+
+ private void WriteSimpleType (SimpleTypeReference simple, DisplayOptions options, bool showOuterType, XmlWriter writer) {
+ TypeTarget type = simple.Resolve(targets) as TypeTarget;
+ if (type != null) {
+ WriteTypeTarget(type, options, showOuterType, writer);
+ } else {
+ TextReferenceUtilities.WriteSimpleTypeReference(simple, options, writer);
+ }
+ }
+
+ private static void WriteTemplateParameters (string[] templates, XmlWriter writer) {
+
+ if (templates.Length == 0) return;
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("<");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString("(Of ");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("<");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("(");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString("<'");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ for (int i = 0; i < templates.Length; i++) {
+ if (i > 0) writer.WriteString(", ");
+ writer.WriteString(templates[i]);
+ }
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteSpecializedType (SpecializedTypeReference special, DisplayOptions options, XmlWriter writer) {
+
+ Specialization[] specializations = special.Specializations;
+ for (int i = 0; i < specializations.Length; i++) {
+ if (i == 0) {
+ WriteSpecialization(specializations[0], options, writer);
+ } else {
+ WriteSeperator(writer);
+ WriteSpecialization(specializations[i], options & ~DisplayOptions.ShowContainer, writer);
+ }
+
+ }
+
+ }
+
+ private void WriteSpecialization (Specialization specialization, DisplayOptions options, XmlWriter writer) {
+ // write the type itself (without outer types, because those will be written be other calls to this routine)
+ WriteSimpleType(specialization.TemplateType, (options & ~DisplayOptions.ShowTemplates), false, writer);
+
+ // then write the template arguments
+ WriteTemplateArguments(specialization.Arguments, writer);
+ }
+
+ private void WriteTemplateArguments (TypeReference[] specialization, XmlWriter writer) {
+
+ if (specialization.Length == 0) return;
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("<");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString("(Of ");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("<");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString("<'");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("(");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ for (int i = 0; i < specialization.Length; i++) {
+ if (i > 0) writer.WriteString(", ");
+ WriteType(specialization[i], DisplayOptions.Default, writer);
+ }
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+ writer.WriteEndElement();
+ }
+
+ private void WriteArrayType (ArrayTypeReference reference, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ // C++ array notation (left)
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("array<");
+ writer.WriteEndElement();
+ writer.WriteEndElement(); // end of <span class="languageSpecificText"> element
+
+ // the underlying type
+ WriteType(reference.ElementType, options, writer, dictionary);
+
+ // C++ array notation (right)
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ if (reference.Rank > 1) {
+ writer.WriteString("," + reference.Rank.ToString());
+ }
+ writer.WriteString(">");
+ writer.WriteEndElement();
+
+ // C# array notation
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("[");
+ for (int i = 1; i < reference.Rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ writer.WriteEndElement();
+
+ // VB array notation
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString("(");
+ for (int i = 1; i < reference.Rank; i++) { writer.WriteString(","); }
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ // neutral array notation
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("[");
+ for (int i = 1; i < reference.Rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ writer.WriteEndElement();
+
+ // F# array notation
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString("[");
+ for (int i = 1; i < reference.Rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ writer.WriteEndElement();
+
+
+ writer.WriteEndElement(); // end of <span class="languageSpecificText"> element
+ }
+
+ private static void WriteSeperator (XmlWriter writer) {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ // C# seperator
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString(".");
+ writer.WriteEndElement();
+
+ // VB seperator
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString(".");
+ writer.WriteEndElement();
+
+ // C++ seperator
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("::");
+ writer.WriteEndElement();
+
+ // neutral seperator
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString(".");
+ writer.WriteEndElement();
+
+ // F# seperator
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(".");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+
+ private void WritePointerType (PointerTypeReference pointer, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+ WriteType(pointer.PointedToType, options, writer, dictionary);
+ writer.WriteString("*");
+ }
+
+ private void WriteReferenceType (ReferenceTypeReference reference, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+ WriteType(reference.ReferedToType, options, writer, dictionary);
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ // add % in C++
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("%");
+ writer.WriteEndElement();
+ writer.WriteEndElement();
+ }
+
+ private void WriteTemplateType (TemplateTypeReference template, DisplayOptions options, XmlWriter writer) {
+ WriteTemplateType(template, options, writer, null);
+ }
+
+ private void WriteTemplateType (TemplateTypeReference template, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+
+ /*
+ Console.WriteLine("template type {0}", template.GetType().FullName);
+ if (dictionary != null) {
+ foreach (IndexedTemplateTypeReference it in dictionary.Keys) {
+ Console.WriteLine("index = {0}, api = {1} ({3}) -> {2}", it.Index, it.TemplateId, dictionary[it].GetType().FullName, it.GetHashCode());
+ }
+ }
+ */
+
+ // if we have the name, just write it
+ NamedTemplateTypeReference namedTemplate = template as NamedTemplateTypeReference;
+ if (namedTemplate != null) {
+ writer.WriteString(namedTemplate.Name);
+ return;
+ }
+
+ IndexedTemplateTypeReference indexedTemplate = template as IndexedTemplateTypeReference;
+ if (indexedTemplate != null) {
+ //Console.WriteLine("index = {0}, api = {1} ({2})", indexedTemplate.Index, indexedTemplate.TemplateId, indexedTemplate.GetHashCode());
+ //if ((dictionary != null) && (!dictionary.ContainsKey(indexedTemplate))) Console.WriteLine("not in dictionary");
+ if ((dictionary != null) && (dictionary.ContainsKey(indexedTemplate))) {
+ //Console.WriteLine("Substituted {0}", dictionary[indexedTemplate].GetType().FullName);
+ WriteType(dictionary[indexedTemplate], options, writer);
+ } else {
+ //Console.WriteLine("Getting name for id='{0}' and index={1}", indexedTemplate.TemplateId, indexedTemplate.Index);
+ writer.WriteString(GetTemplateName(indexedTemplate.TemplateId, indexedTemplate.Index));
+ }
+ return;
+ }
+
+ TypeTemplateTypeReference typeTemplate = template as TypeTemplateTypeReference;
+ if (typeTemplate != null) {
+
+ TypeReference value = null;
+ if (dictionary != null) {
+ IndexedTemplateTypeReference key = new IndexedTemplateTypeReference(typeTemplate.TemplateType.Id, typeTemplate.Position);
+ if (dictionary.ContainsKey(key)) value = dictionary[key];
+ }
+
+ if (value == null) {
+ writer.WriteString(GetTypeTemplateName(typeTemplate.TemplateType, typeTemplate.Position));
+ } else {
+ WriteType(value, options, writer);
+ }
+
+ return;
+
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ private string GetTemplateName (string templateId, int position) {
+ Target target = targets[templateId];
+
+ if (target == null) {
+ return ("UTT");
+ } else {
+
+ TypeTarget type = target as TypeTarget;
+ if (type != null) {
+ string[] templates = type.Templates;
+ if (templates.Length > position) {
+ return(templates[position]);
+ } else {
+ return ("UTT");
+ }
+ }
+
+ MethodTarget method = target as MethodTarget;
+ if (method != null) {
+ string[] templates = method.Templates;
+ if (templates.Length > position) {
+ return (templates[position]);
+ } else {
+ return ("UTT");
+ }
+ }
+
+ return ("UTT");
+ }
+ }
+
+ private string GetTypeTemplateName (SimpleTypeReference type, int position) {
+ TypeTarget target = type.Resolve(targets) as TypeTarget;
+ if (target != null) {
+ string[] templates = target.Templates;
+ if (templates.Length > position) {
+ return (templates[position]);
+ } else if (target.OuterType != null) {
+ return (GetTypeTemplateName(target.OuterType, position));
+ } else {
+ return ("UTT");
+ }
+ } else {
+ throw new InvalidOperationException(String.Format("Unknown type reference '{0}'", type.Id));
+ }
+ }
+
+ public void WriteExtensionMethod(ExtensionMethodReference extMethod, DisplayOptions options, XmlWriter writer)
+ {
+ if (extMethod == null) throw new ArgumentNullException("extMethod");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ // write the unqualified method name
+ writer.WriteString(extMethod.Name);
+
+ // if this is a generic method, write any template params or args
+ if (extMethod.TemplateArgs != null && extMethod.TemplateArgs.Length > 0)
+ {
+ WriteTemplateArguments(extMethod.TemplateArgs, writer);
+ }
+
+ // write parameters
+ if ((options & DisplayOptions.ShowParameters) > 0)
+ {
+ Parameter[] parameters = extMethod.Parameters;
+ WriteMethodParameters(extMethod.Parameters, writer);
+ }
+ }
+
+ public void WriteMember (MemberReference member, DisplayOptions options, XmlWriter writer) {
+
+ if (member == null) throw new ArgumentNullException("member");
+ if (writer == null) throw new ArgumentNullException("writer");
+
+ SimpleMemberReference simple = member as SimpleMemberReference;
+ if (simple != null) {
+ WriteSimpleMember(simple, options, writer);
+ return;
+ }
+
+ SpecializedMemberReference special = member as SpecializedMemberReference;
+ if (special != null) {
+ WriteSpecializedMember(special, options, writer);
+ return;
+ }
+
+ SpecializedMemberWithParametersReference ugly = member as SpecializedMemberWithParametersReference;
+ if (ugly != null) {
+ WriteSpecializedMemberWithParameters(ugly, options, writer);
+ return;
+ }
+
+ throw new InvalidOperationException();
+
+ }
+
+ private void WriteSpecializedMember (SpecializedMemberReference member, DisplayOptions options, XmlWriter writer) {
+
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ WriteType(member.SpecializedType, options & ~DisplayOptions.ShowContainer, writer);
+ WriteSeperator(writer);
+ }
+
+ Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary = member.SpecializedType.GetSpecializationDictionary();
+ WriteSimpleMember(member.TemplateMember, options & ~DisplayOptions.ShowContainer, writer, dictionary);
+
+ }
+
+ private void WriteSimpleMember (SimpleMemberReference member, DisplayOptions options, XmlWriter writer) {
+ WriteSimpleMember(member, options, writer, null);
+ }
+
+ private void WriteSimpleMember (SimpleMemberReference member, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+ MemberTarget target = member.Resolve(targets) as MemberTarget;
+ if (target != null) {
+ WriteMemberTarget(target, options, writer, dictionary);
+ } else {
+ TextReferenceUtilities.WriteSimpleMemberReference(member, options, writer, this);
+ //throw new InvalidOperationException(String.Format("Unknown member target '{0}'", member.Id));
+ }
+
+ }
+
+ private void WriteProcedureName (ProcedureTarget target, DisplayOptions options, XmlWriter writer) {
+ MemberReference implements = target.ExplicitlyImplements;
+ if (implements == null) {
+ if (target.conversionOperator) {
+ WriteConversionOperator(target, writer);
+ } else {
+ writer.WriteString(target.Name);
+ }
+ } else {
+ WriteMember(implements, DisplayOptions.ShowContainer, writer);
+ }
+ }
+
+ private void WriteMethod (MethodTarget target, DisplayOptions options, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+
+ WriteProcedureName(target, options, writer);
+
+ if ((options & DisplayOptions.ShowTemplates) > 0) {
+ // if this is a generic method, write any template params or args
+ if (target.TemplateArgs != null && target.TemplateArgs.Length > 0)
+ {
+ WriteTemplateArguments(target.TemplateArgs, writer);
+ }
+ }
+
+ if ((options & DisplayOptions.ShowParameters) > 0) {
+ Parameter[] parameters = target.Parameters;
+
+ if (target.ConversionOperator) {
+ TypeReference returns = target.returnType;
+ WriteConversionOperatorParameters(parameters, returns, writer, dictionary);
+ } else {
+ WriteMethodParameters(parameters, writer, dictionary);
+ }
+ }
+
+ }
+
+ private void WriteConversionOperator(ProcedureTarget target, XmlWriter writer)
+ {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString(target.Name);
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ if (target.name == "Explicit") {
+ writer.WriteString("Narrowing");
+ } else if (target.name == "Implicit") {
+ writer.WriteString("Widening");
+ }
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString(target.name);
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString(target.name);
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(target.name);
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+
+ internal void WriteMethodParameters (Parameter[] parameters, XmlWriter writer) {
+ WriteMethodParameters(parameters, writer, null);
+ }
+
+
+ private void WriteMethodParameters (Parameter[] parameters, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary) {
+ if (parameters.Length > 0) {
+ writer.WriteString("(");
+
+ // show parameters
+ // we need to deal with type template substitutions!
+ for (int i = 0; i < parameters.Length; i++) {
+ if (i > 0) writer.WriteString(", ");
+ WriteType(parameters[i].Type, DisplayOptions.Default, writer, dictionary);
+ }
+
+ writer.WriteString(")");
+ } else {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ // when there are no parameters, VB shows no parenthesis
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ }
+ }
+
+ private void WriteConversionOperatorParameters(Parameter[] parameters, TypeReference returns, XmlWriter writer, Dictionary<IndexedTemplateTypeReference, TypeReference> dictionary)
+ {
+ if (parameters.Length > 0 || returns != null) writer.WriteString("(");
+
+ if (parameters.Length > 0) WriteType(parameters[0].Type, DisplayOptions.Default, writer, dictionary);
+
+ if (parameters.Length > 0 && returns != null) writer.WriteString(" to ");
+
+ if (returns != null) WriteType(returns, DisplayOptions.Default, writer, dictionary);
+
+ if (parameters.Length > 0 || returns != null) writer.WriteString(")");
+
+ if (parameters.Length == 0 && returns == null)
+ {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ // when there are no parameters, VB shows no parenthesis
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString("()");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+ }
+
+ private void WriteProperty (PropertyTarget target, DisplayOptions options, XmlWriter writer) {
+
+ WriteProcedureName(target, options, writer);
+
+ if ((options & DisplayOptions.ShowParameters) > 0) {
+
+ Parameter[] parameters = target.Parameters;
+
+ // VB only shows parenthesis when there are parameters
+ if (parameters.Length > 0) {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("[");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString("(");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("[");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString("(");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(" ");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ // show parameters
+ // we need to deal with type template substitutions!
+ for (int i = 0; i < parameters.Length; i++) {
+ if (i > 0) writer.WriteString(", ");
+ WriteType(parameters[i].Type, DisplayOptions.Default, writer);
+ }
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "languageSpecificText");
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cs");
+ writer.WriteString("]");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "vb");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "cpp");
+ writer.WriteString("]");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nu");
+ writer.WriteString(")");
+ writer.WriteEndElement();
+
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "fs");
+ writer.WriteString(" ");
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+ }
+
+ }
+
+ }
+
+ private void WriteEvent (EventTarget trigger, DisplayOptions options, XmlWriter writer) {
+ WriteProcedureName(trigger, options, writer);
+ }
+
+ private void WriteConstructor (ConstructorTarget constructor, DisplayOptions options, XmlWriter writer) {
+
+
+ WriteType(constructor.Type, options & ~DisplayOptions.ShowContainer, writer);
+
+ if ((options & DisplayOptions.ShowParameters) > 0) {
+ Parameter[] parameters = constructor.Parameters;
+ WriteMethodParameters(parameters, writer);
+ }
+
+ }
+
+ private void WriteSpecializedMemberWithParameters (SpecializedMemberWithParametersReference ugly, DisplayOptions options, XmlWriter writer) {
+
+ if ((options & DisplayOptions.ShowContainer) > 0) {
+ WriteSpecializedType(ugly.SpecializedType, options & ~DisplayOptions.ShowContainer, writer);
+ WriteSeperator(writer);
+ }
+
+ writer.WriteString(ugly.MemberName);
+
+ if ((options & DisplayOptions.ShowParameters) > 0) {
+
+ writer.WriteString("(");
+
+ TypeReference[] parameterTypes = ugly.ParameterTypes;
+ for (int i = 0; i < parameterTypes.Length; i++) {
+ //Console.WriteLine("i = {0}, type = {1}", i, parameterTypes[i].GetType().FullName);
+ if (i > 0) writer.WriteString(", ");
+ WriteType(parameterTypes[i], DisplayOptions.Default, writer);
+ }
+
+ writer.WriteString(")");
+ }
+
+ }
+
+ private static void WriteInvalid (InvalidReference invalid, DisplayOptions options, XmlWriter writer) {
+ writer.WriteString("[" + invalid.Id + "]");
+ }
+
+ }
+
+ [Flags]
+ public enum DisplayOptions {
+
+ ShowContainer = 1,
+ ShowTemplates = 2,
+ ShowParameters = 4,
+
+ Default = 6
+
+ }
+
+ public enum LinkType2 {
+ None,
+ Self,
+ Local,
+ Index,
+ LocalOrIndex,
+ Msdn
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Targets.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Targets.cs
new file mode 100644
index 0000000..656da13
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/Targets.cs
@@ -0,0 +1,156 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using System.Xml;
+using System.Xml.XPath;
+
+namespace BuildComponents {
+
+ public partial class Target {
+
+ internal string id;
+
+ public string Id {
+ get {
+ return (id);
+ }
+ }
+ }
+
+ // Namespace
+
+ public partial class NamespaceTarget : Target {
+
+ internal string name;
+
+ public string Name {
+ get {
+ return (name);
+ }
+ }
+
+ }
+
+ // Type
+
+ public partial class TypeTarget : Target {
+
+ // apidata
+
+ protected string subgroup;
+
+ // containers
+
+ protected NamespaceReference containingNamespace;
+
+ protected SimpleTypeReference containingType;
+
+ protected string containingAssembly;
+
+ // other
+
+ public NamespaceReference Namespace {
+ get {
+ return (containingNamespace);
+ }
+ }
+
+ public SimpleTypeReference OuterType {
+ get {
+ return (containingType);
+ }
+ }
+
+ }
+
+ // Construction of targets from Xml
+
+ public partial class Target {
+
+ public static Target Create (XmlReader api) {
+
+ string id = api.GetAttribute("id");
+
+ Target target = null;
+ api.ReadToFollowing("apidata");
+ string group = api.GetAttribute("group");
+ switch (group) {
+ case "namespace":
+ target = NamespaceTarget.Create(api);
+ break;
+ }
+
+ target.id = id;
+
+ return (target);
+ }
+
+ protected static XPathExpression apiNameExpression = XPathExpression.Compile("string(apidata/@name)");
+
+
+ }
+
+ public partial class NamespaceTarget {
+
+ public static new NamespaceTarget Create (XmlReader apidata) {
+ NamespaceTarget target = new NamespaceTarget();
+ string name = apidata.GetAttribute("name");
+
+ // This is not locale-independent.
+ if (String.IsNullOrEmpty(target.name)) name = "(Default Namespace)";
+
+ target.name = name;
+
+ return (target);
+ }
+
+ public static NamespaceTarget Create (XPathNavigator api) {
+
+ NamespaceTarget target = new NamespaceTarget();
+ target.name = (string)api.Evaluate(apiNameExpression);
+
+ // This is not locale-independent.
+ if (String.IsNullOrEmpty(target.name)) target.name = "(Default Namespace)";
+
+ return (target);
+ }
+
+ }
+
+
+ public partial class TypeTarget {
+
+ public static new TypeTarget Create (XmlReader api) {
+
+ api.ReadToFollowing("apidata");
+ //string subgroup = api.GetAttribute("subgroup");
+
+ api.ReadToFollowing("typedata");
+ //string visibilityValue = api.GetAttribute("visibility");
+ //string abstractValue = api.GetAttribute("abstract");
+ //string sealedValue = api.GetAttribute("sealed");
+ //string serializableValue = api.GetAttribute("serealizable");
+
+ api.ReadToFollowing("library");
+ string containingAssemblyValue = api.GetAttribute("assembly");
+
+ api.ReadToFollowing("namespace");
+ NamespaceReference containingNamespace = NamespaceReference.Create(api);
+
+ TypeTarget target = new TypeTarget();
+ target.containingAssembly = containingAssemblyValue;
+ target.containingNamespace = containingNamespace;
+
+ return (target);
+
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TaskGrabberComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TaskGrabberComponent.cs
new file mode 100644
index 0000000..d03fa15
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TaskGrabberComponent.cs
@@ -0,0 +1,371 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Xml;
+using System.Xml.XPath;
+using System.IO;
+
+// still have problems with spaces
+
+namespace Microsoft.Ddue.Tools {
+
+ public class TaskGrabberComponent : BuildComponent {
+
+ private XmlNamespaceManager nsManager = new XmlNamespaceManager(new NameTable());
+
+ private XPathExpression valueQuery = null;
+ private XPathExpression keyQuery = null;
+
+ private string xpathFromConfig = string.Empty;
+
+ private Dictionary<string, List<string>> bKeywordMap = new Dictionary<string, List<string>>();
+
+ private Dictionary<string, string> index = new Dictionary<string, string>();
+
+ // what to copy
+ private List<CopySet> copySets = new List<CopySet>();
+
+ public TaskGrabberComponent(BuildAssembler assembler, XPathNavigator configuration)
+ : base(assembler, configuration)
+ {
+ XPathNavigator keywordsNode = configuration.SelectSingleNode("keywords");
+ if (keywordsNode == null)
+ return;
+
+ string filespec = keywordsNode.GetAttribute("files", String.Empty);
+ filespec = Environment.ExpandEnvironmentVariables(filespec);
+ string keywordXPath = keywordsNode.GetAttribute("keyword", String.Empty);
+ string topicXPath = keywordsNode.GetAttribute("topic", String.Empty);
+ if (String.IsNullOrEmpty(keywordXPath) || String.IsNullOrEmpty(topicXPath) || String.IsNullOrEmpty(filespec))
+ return;
+
+ xpathFromConfig = keywordXPath;
+
+ string[] keywordFiles = null;
+ if (File.Exists(filespec))
+ {
+ // we're loading a single file
+ AddBKeywords(filespec, topicXPath, keywordXPath);
+ }
+ else
+ {
+ // must be loading a set of files
+ if (Directory.Exists(filespec))
+ {
+ // if they specified a directory, transform all the files in the directory
+ keywordFiles = Directory.GetFiles(filespec);
+ }
+ else
+ {
+ // it's not a file or a directory, maybe it's a path with wildcards
+ string directoryPath = Path.GetDirectoryName(filespec);
+ string filePath = Path.GetFileName(filespec);
+ keywordFiles = Directory.GetFiles(directoryPath, filePath);
+ }
+ foreach (string file in keywordFiles)
+ {
+ // load targets from each file
+ AddBKeywords(file, topicXPath, keywordXPath);
+ }
+ }
+
+ // set up the context
+ // put in a default entry for ddue
+ nsManager.AddNamespace("ddue", "http://ddue.schemas.microsoft.com/authoring/2003/6");
+ // look for context nodes, which could override the default
+ XPathNodeIterator contextNodes = configuration.Select("context");
+ foreach (XPathNavigator contextNode in contextNodes)
+ {
+ string prefix = contextNode.GetAttribute("prefix", String.Empty);
+ string uri = contextNode.GetAttribute("name", String.Empty);
+ nsManager.AddNamespace(prefix, uri);
+ }
+
+
+ // set up the index of source files
+ XPathNodeIterator sourceNodes = configuration.Select("source");
+ foreach (XPathNavigator sourceNode in sourceNodes)
+ {
+ string valueXPath = sourceNode.GetAttribute("value", String.Empty);
+ string keyXPath = sourceNode.GetAttribute("key", String.Empty);
+ if (String.IsNullOrEmpty(valueXPath) || String.IsNullOrEmpty(keyXPath))
+ {
+ WriteMessage(MessageLevel.Error, "@key and @value must be set in the 'source' node.");
+ return;
+ }
+
+ keyQuery = XPathExpression.Compile(keyXPath);
+ valueQuery = XPathExpression.Compile(valueXPath);
+
+ // search the data directories for entries
+ XPathNodeIterator dataNodes = sourceNode.Select("data");
+ foreach (XPathNavigator dataNode in dataNodes)
+ {
+ string dataFiles = dataNode.GetAttribute("files", String.Empty);
+ dataFiles = Environment.ExpandEnvironmentVariables(dataFiles);
+ if ((dataFiles == null) || (dataFiles.Length == 0)) throw new ConfigurationErrorsException("When instantiating a CopyFromDirectory component, you must specify a directory path using the files attribute.");
+ WriteMessage(MessageLevel.Info, String.Format("Searching for files that match '{0}'.", dataFiles));
+ int fileCount = ParseDocuments(dataFiles);
+ WriteMessage(MessageLevel.Info, String.Format("Found {0} files.", fileCount));
+ }
+ WriteMessage(MessageLevel.Info, String.Format("Indexed {0} elements.", index.Count));
+
+ }
+
+ // get the copy commands
+ XPathNodeIterator copyNodes = configuration.Select("copy");
+ foreach (XPathNavigator copyNode in copyNodes)
+ {
+ string sourceXPath = copyNode.GetAttribute("source", String.Empty);
+ string targetXPath = copyNode.GetAttribute("target", String.Empty);
+ if (String.IsNullOrEmpty(sourceXPath) || String.IsNullOrEmpty(targetXPath))
+ {
+ WriteMessage(MessageLevel.Error, "@source and @target must be set in the 'copy' node.");
+ return;
+ }
+
+ copySets.Add(new CopySet(sourceXPath, targetXPath, nsManager));
+ }
+
+ }
+
+ private string currentKey = string.Empty;
+
+ public override void Apply (XmlDocument document, string key) {
+ currentKey = key;
+
+ XPathNavigator targetDoc = document.CreateNavigator();
+ foreach (CopySet copySet in copySets)
+ {
+ XPathExpression targetExpression = copySet.GetTargetExpression(targetDoc, key);
+
+ // get the target nodes in the document
+ XPathNavigator targetNode = targetDoc.SelectSingleNode(targetExpression);
+ while (targetNode != null)
+ {
+ string targetId = targetNode.Value;
+ int pound = (string.IsNullOrEmpty(targetId)) ? -1 : targetId.IndexOf("#");
+ string bkeyword = (pound == -1) ? "" : targetId.Substring(pound + 1);
+ if (bkeyword == "")
+ {
+ WriteMessage(MessageLevel.Warn, string.Format("Invalid id '{0}' in topic '{1}'.", targetId, currentKey));
+ // delete this target and get the next target node
+ targetNode.DeleteSelf();
+ targetNode = targetDoc.SelectSingleNode(targetExpression);
+ continue;
+ }
+
+ List<string> idList;
+ if (!bKeywordMap.TryGetValue(bkeyword, out idList))
+ {
+ WriteMessage(MessageLevel.Warn, string.Format("B-keyword not found '{0}' in topic '{1}'.", targetId, currentKey));
+ // delete this target and get the next target node
+ targetNode.DeleteSelf();
+ targetNode = targetDoc.SelectSingleNode(targetExpression);
+ continue;
+ }
+ if (idList.Count > 1)
+ Console.Write("");
+
+ // create a 'tasks' node to replace the target
+ XPathNavigator tasksNode = document.CreateElement("tasks").CreateNavigator();
+ tasksNode.CreateAttribute(string.Empty, "bkeyword", string.Empty, bkeyword);
+ foreach (string topicId in idList)
+ {
+ //create a task node for this source topic
+ XPathNavigator taskNode = document.CreateElement("task").CreateNavigator();
+ taskNode.CreateAttribute(string.Empty, "topicId", string.Empty, topicId);
+
+ // get the source document for the topic id
+ string filepath;
+ if (!index.TryGetValue(topicId, out filepath))
+ {
+ WriteMessage(MessageLevel.Warn, string.Format("No file found for topicId '{0}' for B-keyword '{1}'. Source topic: '{2}'.", topicId, bkeyword, currentKey));
+ continue;
+ }
+
+ XPathNavigator sourceDoc = new XPathDocument(filepath).CreateNavigator();
+ XPathNavigator sourceNode = sourceDoc.SelectSingleNode(valueQuery);
+
+ if (sourceNode == null) continue;
+ XPathNodeIterator sources = sourceNode.Select(copySet.SourceExpression);
+
+ // append the source nodes to the target node
+ if (sources.Count > 0)
+ {
+ foreach (XPathNavigator source in sources)
+ taskNode.AppendChild(source);
+ }
+ tasksNode.AppendChild(taskNode);
+ }
+ targetNode.ReplaceSelf(tasksNode);
+ // get the next target node
+ targetNode = targetDoc.SelectSingleNode(targetExpression);
+ }
+ }
+ }
+
+ public int ParseDocuments(string wildcardPath)
+ {
+ string directoryPart = Path.GetDirectoryName(wildcardPath);
+ if (String.IsNullOrEmpty(directoryPart)) directoryPart = Environment.CurrentDirectory;
+ directoryPart = Path.GetFullPath(directoryPart);
+ string filePart = Path.GetFileName(wildcardPath);
+ string[] files = Directory.GetFiles(directoryPart, filePart);
+ foreach (string file in files)
+ ParseDocument(file);
+ return (files.Length);
+ }
+
+ private void ParseDocument(string file)
+ {
+ try
+ {
+ XPathDocument document = new XPathDocument(file);
+
+ // set context for the xpath expression
+ valueQuery.SetContext(nsManager);
+ keyQuery.SetContext(nsManager);
+
+ XPathNodeIterator valueNodes = document.CreateNavigator().Select(valueQuery);
+ foreach (XPathNavigator valueNode in valueNodes)
+ {
+ XPathNavigator keyNode = valueNode.SelectSingleNode(keyQuery);
+ if (keyNode == null) continue;
+ string key = keyNode.Value;
+
+ // log multiple occurences of a single id
+ if (index.ContainsKey(key))
+ {
+ WriteMessage(MessageLevel.Warn, String.Format("Entries for the key '{0}' occur in both '{1}' and '{2}'. The first entry will be used.", key, index[key], file));
+ }
+ else
+ {
+ index[key] = file;
+ }
+
+ }
+ }
+ catch (Exception e)
+ {
+ WriteMessage(MessageLevel.Error, e.Message);
+ }
+ }
+
+ private XPathDocument GetDocument(string identifier)
+ {
+ string file = index[identifier];
+ XPathDocument document = new XPathDocument(file);
+ return (document);
+ }
+
+ private void AddBKeywords(string file, string topicXPath, string keywordXPath)
+ {
+ XPathDocument document = new XPathDocument(file);
+ XPathNodeIterator targetNodes = document.CreateNavigator().Select(topicXPath);
+ foreach (XPathNavigator targetNode in targetNodes)
+ {
+ string topicId = targetNode.GetAttribute("id", string.Empty);
+ if (string.IsNullOrEmpty(topicId))
+ continue;
+ foreach (XPathNavigator keywordNode in targetNode.Select(keywordXPath))
+ {
+ string keyword = keywordNode.Value;
+ if (string.IsNullOrEmpty(keyword))
+ continue;
+ AddValueToListDictionary(bKeywordMap, keyword, topicId);
+ }
+ }
+ }
+
+ public static void AddValueToListDictionary<K, V>(Dictionary<K, List<V>> dict, K key, V value)
+ {
+ List<V> list;
+ try
+ {
+ if (!dict.TryGetValue(key, out list))
+ {
+ list = new List<V>();
+ dict.Add(key, list);
+ }
+ list.Add(value);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Exception adding to dictionary {0}", key);
+ Console.WriteLine(e);
+ throw;
+ }
+ }
+
+ }
+
+ internal class CopySet
+ {
+
+ public CopySet(string sourceXPath, string targetXPath, XmlNamespaceManager nsMgr)
+ : this(null, sourceXPath, targetXPath, nsMgr)
+ {
+ }
+
+ public CopySet(IndexedFileCache cache, string sourceXPath, string targXPath, XmlNamespaceManager nsMgr)
+ {
+ this.fileCache = cache;
+ this.namespaceMgr = nsMgr;
+ source = XPathExpression.Compile(sourceXPath);
+ source.SetContext(nsMgr);
+ if (targXPath.Contains("{0}"))
+ {
+ targetXPath = targXPath;
+ }
+ else
+ {
+ target = XPathExpression.Compile(targXPath);
+ target.SetContext(nsMgr);
+ }
+ }
+
+ private IndexedFileCache fileCache;
+ public IndexedFileCache FileCache
+ {
+ get
+ {
+ return (fileCache);
+ }
+ }
+
+ private XPathExpression source;
+ public XPathExpression SourceExpression
+ {
+ get
+ {
+ return (source);
+ }
+ }
+
+ private XmlNamespaceManager namespaceMgr;
+
+ private string targetXPath = string.Empty;
+ private XPathExpression target = null;
+ public XPathExpression GetTargetExpression(XPathNavigator targetDoc, string key)
+ {
+ if (target == null)
+ {
+ XPathExpression keyedTargetExpression = targetDoc.Compile(string.Format(targetXPath, key));
+ keyedTargetExpression.SetContext(namespaceMgr);
+ return keyedTargetExpression;
+ }
+
+ return target;
+ }
+
+
+ }
+
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TransformComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TransformComponent.cs
new file mode 100644
index 0000000..712ceb1
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/TransformComponent.cs
@@ -0,0 +1,153 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class TransformComponent : BuildComponent {
+
+ public TransformComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ // load the transforms
+ XPathNodeIterator transform_nodes = configuration.Select("transform");
+ foreach (XPathNavigator transform_node in transform_nodes) {
+
+ // load the transform
+ string file = transform_node.GetAttribute("file", String.Empty);
+ if (String.IsNullOrEmpty(file)) WriteMessage(MessageLevel.Error, "Each transform element must specify a file attribute.");
+ file = Environment.ExpandEnvironmentVariables(file);
+
+ Transform transform = null;
+ try {
+ transform = new Transform(file);
+ } catch (IOException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The transform file '{0}' is not a valid XML file. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ } catch (XsltException e) {
+ WriteMessage(MessageLevel.Error, String.Format("The XSL transform '{0}' contains an error. The error message is: {1}", file, BuildComponentUtilities.GetExceptionMessage(e)));
+ }
+
+
+ transforms.Add(transform);
+
+
+ // load any arguments
+ XPathNodeIterator argument_nodes = transform_node.Select("argument");
+ foreach (XPathNavigator argument_node in argument_nodes) {
+ string key = argument_node.GetAttribute("key", String.Empty);
+ if ((key == null) || (key.Length == 0)) WriteMessage(MessageLevel.Error, "When creating a transform argument, you must specify a key using the key attribute");
+
+ // set "expand-value" attribute to true to expand environment variables embedded in "value".
+ string expand_attr = argument_node.GetAttribute("expand-value", String.Empty);
+ bool expand_value = String.IsNullOrEmpty(expand_attr) ? false : Convert.ToBoolean(expand_attr);
+
+ string value = argument_node.GetAttribute("value", String.Empty);
+ if ((value != null) && (value.Length > 0)) {
+ transform.Arguments.AddParam(key, String.Empty, expand_value ? Environment.ExpandEnvironmentVariables(value) : value);
+ }
+ else {
+ transform.Arguments.AddParam(key, String.Empty, argument_node.Clone());
+ }
+ }
+
+ }
+
+ }
+
+ // the stored transforms
+
+ private List<Transform> transforms = new List<Transform>();
+
+ // the action of the component
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // iterate over transforms
+ foreach (Transform transform in transforms) {
+
+ // add the key as a parameter to the arguments
+ transform.Arguments.RemoveParam("key", String.Empty);
+ transform.Arguments.AddParam("key", String.Empty, key);
+
+ // create a buffer into which output can be written
+ using (MemoryStream buffer = new MemoryStream()) {
+
+
+ // do the transform, routing output to the buffer
+ XmlWriterSettings settings = transform.Xslt.OutputSettings;
+ XmlWriter writer = XmlWriter.Create(buffer, settings);
+ try {
+ transform.Xslt.Transform(document, transform.Arguments, writer);
+ } catch (XsltException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A error ocurred while executing the transform '{0}', on line {1}, at position {2}. The error message was: {3}", e.SourceUri, e.LineNumber, e.LinePosition, (e.InnerException == null) ? e.Message : e.InnerException.Message));
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A error ocurred while executing the transform '{0}', on line {1}, at position {2}. The error message was: {3}", e.SourceUri, e.LineNumber, e.LinePosition, (e.InnerException == null) ? e.Message : e.InnerException.Message));
+ } finally {
+ writer.Close();
+ }
+
+ // replace the document by the contents of the buffer
+ buffer.Seek(0, SeekOrigin.Begin);
+
+ // some settings to ensure that we don't try to go get, parse, and validate using any referenced schemas or DTDs
+ XmlReaderSettings readerSettings = new XmlReaderSettings();
+ readerSettings.ProhibitDtd = false;
+ readerSettings.XmlResolver = null;
+
+ XmlReader reader = XmlReader.Create(buffer, readerSettings);
+ try {
+ document.Load(reader);
+ } catch (XmlException e) {
+ WriteMessage(MessageLevel.Error, String.Format("A error ocurred while executing the transform '{0}', on line {1}, at position {2}. The error message was: {3}", e.SourceUri, e.LineNumber, e.LinePosition, (e.InnerException == null) ? e.Message : e.InnerException.Message));
+ } finally {
+ reader.Close();
+ }
+
+ }
+ }
+
+ }
+
+ }
+
+
+ // a represenataion of a transform action
+
+ internal class Transform {
+
+ public Transform (string file) {
+ // The transforms presumably come from a trusted source, so there's no reason
+ // not to enable scripting and the document function. The latter is used to read topic
+ // info files for the conceptual WebDocs build.
+ xslt.Load(file, new XsltSettings(true, true), new XmlUrlResolver());
+ }
+
+ private XslCompiledTransform xslt = new XslCompiledTransform();
+
+ private XsltArgumentList arguments = new XsltArgumentList();
+
+ public XslCompiledTransform Xslt {
+ get {
+ return(xslt);
+ }
+ }
+
+ public XsltArgumentList Arguments {
+ get {
+ return(arguments);
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ValidateComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ValidateComponent.cs
new file mode 100644
index 0000000..aeb8854
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/ValidateComponent.cs
@@ -0,0 +1,47 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Xml;
+using System.Xml.Schema;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class ValidateComponent : BuildComponent {
+
+ private XmlSchemaSet schemas = new XmlSchemaSet();
+
+ public ValidateComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+
+ XPathNodeIterator schema_nodes = configuration.Select("schema");
+ foreach (XPathNavigator schema_node in schema_nodes) {
+ string file = schema_node.GetAttribute("file", String.Empty);
+ schemas.Add(null, file);
+ }
+
+ }
+
+ public override void Apply (XmlDocument document, string key) {
+
+ // set the validate schema
+ document.Schemas = schemas;
+
+ // create a validation handler
+ ValidationEventHandler handler = new ValidationEventHandler(LogValidationError);
+
+ // validate the document
+ document.Validate(handler);
+
+ }
+
+ private void LogValidationError (Object o, ValidationEventArgs e) {
+ string message = String.Format("ValidationError: {0}", e.Message);
+ WriteMessage(MessageLevel.Warn, message);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/BuildComponents/WdxResolveConceptualLinksComponent.cs b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/WdxResolveConceptualLinksComponent.cs
new file mode 100644
index 0000000..a827164
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/BuildComponents/WdxResolveConceptualLinksComponent.cs
@@ -0,0 +1,299 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using System.Text.RegularExpressions;
+using System.Web;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ /// <summary>
+ /// WdxResolveConceptualLinksComponent handles conceptual links where the target is a GUID. All other kinds
+ /// of targets are considered invalid. NOTE: This is an experimental version for WebDocs.
+ /// </summary>
+ public class WdxResolveConceptualLinksComponent : BuildComponent {
+
+ const int MaxTargetCacheSize = 1000;
+
+ TargetSetList targetSets = new TargetSetList();
+ XPathExpression baseUrl;
+ string invalidLinkFormat = "<span class='nolink'>{1}</span>";
+ string brokenLinkFormat = "<a href='http://msdn2.microsoft.com/en-us/library/{0}'>{1}</a>";
+ string defaultFormat = "<a href='{0}'>{1}</a>";
+
+ public WdxResolveConceptualLinksComponent (BuildAssembler assembler, XPathNavigator configuration) : base(assembler, configuration) {
+ //System.Diagnostics.Debugger.Break();
+
+ string av; // temporary attribute values
+
+ // base-url is an xpath expression that is used to lookup the url that relative links need to be
+ // relative to. The lookup is done against the current document. This attribute is needed only if
+ // one of the targets uses relative links that are not in the current directory. If not specified,
+ // the target uses the url from the meta data unchanged.
+ av = configuration.GetAttribute("base-url", String.Empty);
+ if (!String.IsNullOrEmpty(av))
+ baseUrl = CompileXPathExpression(av);
+
+ // invalid-link-format specifies a string format to be used for invalid (target is not a valid GUID)
+ // links. The string formatter is called with parameter {0} set to the target attribute of the link,
+ // and parameter {1} set to the tag content from the source document. A reasonable default is used
+ // if the value is not specified.
+ av = configuration.GetAttribute("invalid-link-format", String.Empty);
+ if (!String.IsNullOrEmpty(av))
+ invalidLinkFormat = av;
+
+ // broken-link-format specifies a string format to be used for broken links (target GUID lookup
+ // failed in all targets). The string formatter is called with parameter {0} set to the target attribute
+ // of the link, and parameter {1} set to the tag content from the source document. A reasonable
+ // default is used if the value is not specified.
+ av = configuration.GetAttribute("broken-link-format", String.Empty);
+ if (!String.IsNullOrEmpty(av))
+ brokenLinkFormat = av;
+
+ // <targets> specifies a lookup solution for each possible set of link targets. Each target must
+ // specify either a lookup file or error condition (invalid-link, broken-link).
+ XPathNodeIterator targetsNodes = configuration.Select("targets");
+ foreach (XPathNavigator targetsNode in targetsNodes) {
+
+ // lookup-file specifies the meta data file used for looking up URLs and titles. The value will
+ // go through environment variable expansion during setup and then through string formatting after
+ // computing the url, with parameter {0} set to the link target GUID. This attribute is required.
+ string lookupFile = targetsNode.GetAttribute("lookup-file", String.Empty);
+ if (string.IsNullOrEmpty(lookupFile))
+ WriteMessage(MessageLevel.Error, "Each target must have a lookup-file attribute.");
+ else
+ lookupFile = Environment.ExpandEnvironmentVariables(lookupFile);
+
+ // check-file-exists if specified ensures that the link target file exists; if it doesn't exist we
+ // take the broken link action.
+ string checkFileExists = targetsNode.GetAttribute("check-file-exists", String.Empty);
+ if (!String.IsNullOrEmpty(checkFileExists))
+ checkFileExists = Environment.ExpandEnvironmentVariables(checkFileExists);
+
+ // url is an xpath expression that is used to lookup the link url in the meta data file. The default
+ // value can be used to lookup the url in .cmp.xml files.
+ av = targetsNode.GetAttribute("url", String.Empty);
+ XPathExpression url = String.IsNullOrEmpty(av) ?
+ XPathExpression.Compile("concat(/metadata/topic/@id,'.htm')") :
+ XPathExpression.Compile(av);
+
+ // text is an xpath expression that is used to lookup the link text in the meta data file. The default
+ // value can be used to lookup the link text in .cmp.xml files.
+ av = targetsNode.GetAttribute("text", string.Empty);
+ XPathExpression text = String.IsNullOrEmpty(av) ?
+ XPathExpression.Compile("string(/metadata/topic/title)") :
+ XPathExpression.Compile(av);
+
+ // relative-url determines whether the links from this target set are relative to the current page
+ // and need to be adjusted to the base directory.
+ av = targetsNode.GetAttribute("relative-url", String.Empty);
+ bool relativeUrl = String.IsNullOrEmpty(av) ? false : Convert.ToBoolean(av);;
+
+ // format is a format string that is used to generate the link. Parameter {0} is the url;
+ // parameter {1} is the text. The default creates a standard HTML link.
+ string format = targetsNode.GetAttribute("format", String.Empty);
+ if (String.IsNullOrEmpty(format))
+ format = defaultFormat;
+
+ // target looks OK
+ targetSets.Add(new TargetSet(lookupFile, checkFileExists, url, text, relativeUrl, format));
+ }
+
+ WriteMessage(MessageLevel.Info, String.Format("Collected {0} targets directories.", targetSets.Count));
+ }
+
+ public override void Apply(XmlDocument document, string key) {
+ // Run through all conceptual nodes, make sure the target is a valid GUID, attempt to resolve the target
+ // to a link using one of the TargetSet definitions, and then replace the node with the result. Errors
+ // will be dealt with as follows: 1) bad target (GUID) -> output invalidLinkFormat; 2) broken link (cannot
+ // resolve target or the URL is empty) -> output brokenLinkFormat; 3) missing text -> just delete the node
+ // and don't output anything (presumably there's no point in creating a link that nobody can see). In all
+ // three cases we'll log the problem as a warning.
+ string docBaseUrl = baseUrl == null ? null : BuildComponentUtilities.EvalXPathExpr(document, baseUrl, "key", key);
+ XPathNavigator[] linkNodes = BuildComponentUtilities.ConvertNodeIteratorToArray(document.CreateNavigator().Select(conceptualLinks));
+ foreach (XPathNavigator node in linkNodes) {
+ string targetGuid = node.GetAttribute("target", String.Empty);
+ string url = targetGuid;
+ string text = node.ToString();
+ string format;
+ if (validGuid.IsMatch(url)) {
+ format = brokenLinkFormat;
+ Target t = targetSets.Lookup(targetGuid);
+ if (t == null) {
+ WriteMessage(MessageLevel.Warn, String.Format("Conceptual link not found in target sets; target={0}", targetGuid));
+ }
+ else {
+ if (!String.IsNullOrEmpty(t.Url)) {
+ format = t.TargetSet.Format;
+ url = (docBaseUrl != null && t.TargetSet.RelativeUrl) ?
+ BuildComponentUtilities.GetRelativePath(t.Url, docBaseUrl) : t.Url;
+ if (!String.IsNullOrEmpty(t.Text))
+ text = t.Text;
+ }
+ else
+ WriteMessage(MessageLevel.Warn, String.Format("Conceptual link found in target set, but meta data does not specify a url; target={0}", targetGuid));
+ }
+ }
+ else
+ format = invalidLinkFormat;
+
+ if (String.IsNullOrEmpty(text)) {
+ node.DeleteSelf();
+ WriteMessage(MessageLevel.Warn, String.Format("Skipping conceptual link without text; target={0}", url));
+ }
+ else {
+ node.OuterXml = String.Format(format, url, text);
+ }
+ }
+ }
+
+ private static XPathExpression conceptualLinks = XPathExpression.Compile("//conceptualLink");
+ private static Regex validGuid = new Regex(@"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", RegexOptions.Compiled);
+
+
+ #region HelperFunctions
+
+ public XPathExpression CompileXPathExpression(string xpath) {
+ XPathExpression expression = null;
+ try {
+ expression = XPathExpression.Compile(xpath);
+ }
+ catch (ArgumentException e) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a valid XPath expression. The error message is: {1}", xpath, e.Message));
+ }
+ catch (XPathException e) {
+ WriteMessage(MessageLevel.Error, String.Format("'{0}' is not a valid XPath expression. The error message is: {1}", xpath, e.Message));
+ }
+ return (expression);
+ }
+
+ #endregion HelperFunctions
+
+
+ #region DataStructures
+
+ //
+ // Internal data structures to support WdxResolveConceptualLinksComponent
+ //
+
+ class TargetSet {
+ string lookupFile;
+ string checkFileExists;
+ XPathExpression url;
+ XPathExpression text;
+
+ bool relativeUrl;
+ public bool RelativeUrl {
+ get { return relativeUrl; }
+ }
+
+ string format;
+ public string Format {
+ get { return format; }
+ }
+
+ public TargetSet(string lookupFile, string checkFileExists, XPathExpression url, XPathExpression text, bool relativeUrl, string format) {
+ if (lookupFile == null)
+ throw new ArgumentNullException("lookupFile");
+ this.lookupFile = lookupFile;
+
+ this.checkFileExists = checkFileExists;
+
+ if (url == null)
+ throw new ArgumentNullException("url");
+ this.url = url;
+
+ if (text == null)
+ throw new ArgumentNullException("text");
+ this.text = text;
+
+ this.relativeUrl = relativeUrl;
+
+ if (format == null)
+ throw new ArgumentNullException("format");
+ this.format = format;
+ }
+
+ public Target Lookup(string targetGuid) {
+ string lookupFilePathName = String.Format(lookupFile, targetGuid);
+ if (File.Exists(lookupFilePathName) &&
+ (checkFileExists == null || File.Exists(String.Format(checkFileExists, targetGuid)))) {
+ XPathDocument document = new XPathDocument(lookupFilePathName);
+ return new Target(this,
+ (string)document.CreateNavigator().Evaluate(url),
+ (string)document.CreateNavigator().Evaluate(text));
+ }
+ return null;
+ }
+ }
+
+ class TargetSetList {
+ List<TargetSet> targetSets = new List<TargetSet>();
+ Dictionary<string, Target> targetCache = new Dictionary<string, Target>();
+
+ public TargetSetList() {
+ }
+
+ public void Add(TargetSet targetSet) {
+ if (targetSet == null)
+ throw new ArgumentNullException("targetSet");
+ this.targetSets.Add(targetSet);
+ }
+
+ public int Count {
+ get { return targetSets.Count; }
+ }
+
+ public Target Lookup(string targetGuid) {
+ Target t = null;
+ if (!targetCache.TryGetValue(targetGuid, out t)) {
+ foreach (TargetSet ts in targetSets) {
+ t = ts.Lookup(targetGuid);
+ if (t != null) {
+ if (targetCache.Count >= MaxTargetCacheSize)
+ targetCache.Clear();
+ targetCache.Add(targetGuid, t);
+ break;
+ }
+ }
+ }
+ return t;
+ }
+ }
+
+ class Target {
+ TargetSet targetSet;
+ public TargetSet TargetSet {
+ get { return targetSet; }
+ }
+
+ string url;
+ public string Url {
+ get { return url; }
+ }
+
+ string text;
+ public string Text {
+ get { return text; }
+ }
+
+ public Target(TargetSet targetSet, string url, string text) {
+ if (targetSet == null)
+ throw new ArgumentNullException("targetSet");
+ this.targetSet = targetSet;
+ this.url = url;
+ this.text = text;
+ }
+ }
+
+ #endregion DataStructures
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/CopyComponents/CopyComponents.csproj b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/CopyComponents.csproj
new file mode 100644
index 0000000..7cf0bb0
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/CopyComponents.csproj
@@ -0,0 +1,80 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E64725D7-2208-4C28-922D-B6543C0BC483}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CopyComponents</RootNamespace>
+ <AssemblyName>CopyComponents</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>
+ </AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="InheritDocumentationComponent.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BuildAssemblerLibrary\BuildAssemblerLibrary.csproj">
+ <Project>{399E78F8-4954-409E-991A-37DA9D0579CC}</Project>
+ <Name>BuildAssemblerLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\BuildComponents\BuildComponents.csproj">
+ <Project>{30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}</Project>
+ <Name>BuildComponents</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/CopyComponents/GlobalSuppressions.cs b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/GlobalSuppressions.cs
new file mode 100644
index 0000000..210bf57
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/GlobalSuppressions.cs
@@ -0,0 +1,17 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/CopyComponents/InheritDocumentationComponent.cs b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/InheritDocumentationComponent.cs
new file mode 100644
index 0000000..9df1282
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/InheritDocumentationComponent.cs
@@ -0,0 +1,373 @@
+// ------------------------------------------------------------------------------------------------
+// <copyright file="InheritDocumentationComponent.cs" company="Microsoft">
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+// </copyright>
+// <summary>Contains code that indexes XML comments files for <inheritdoc /> tags, reflection files
+// for API information and produces a new XML comments file containing the inherited documentation
+// for use by Sandcastle.
+// </summary>
+// ------------------------------------------------------------------------------------------------
+namespace Microsoft.Ddue.Tools
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using System.Xml;
+ using System.Xml.XPath;
+ using System.Configuration;
+ using System.Globalization;
+ using Microsoft.Ddue.Tools.CommandLine;
+
+ /// <summary>
+ /// InheritDocumentationComponent class.
+ /// </summary>
+ public class InheritDocumentationComponent : CopyComponent
+ {
+ #region private members
+ /// <summary>
+ /// XPathExpression for API name.
+ /// </summary>
+ private static XPathExpression apiNameExpression = XPathExpression.Compile("string(apidata/@name)");
+
+ /// <summary>
+ /// XPathExpression for API group.
+ /// </summary>
+ private static XPathExpression apiGroupExpression = XPathExpression.Compile("string(apidata/@group)");
+
+ /// <summary>
+ /// XPathExpression for API subgroup.
+ /// </summary>
+ private static XPathExpression apiSubgroupExpression = XPathExpression.Compile("string(apidata/@subgroup)");
+
+ /// <summary>
+ /// XPathExpression for API ancestors.
+ /// </summary>
+ private static XPathExpression typeExpression = XPathExpression.Compile("family/ancestors/type/@api");
+
+ /// <summary>
+ /// XPathExpression for API type interface implementations.
+ /// </summary>
+ private static XPathExpression interfaceImplementationExpression = XPathExpression.Compile("implements/type/@api");
+
+ /// <summary>
+ /// XPathExpression for API containers.
+ /// </summary>
+ private static XPathExpression containerTypeExpression = XPathExpression.Compile("string(containers/type/@api)");
+
+ /// <summary>
+ /// XPathExpression for override members.
+ /// </summary>
+ private static XPathExpression overrideMemberExpression = XPathExpression.Compile("overrides/member/@api");
+
+ /// <summary>
+ /// XPathExpression for API member interface implementaions.
+ /// </summary>
+ private static XPathExpression interfaceImplementationMemberExpression = XPathExpression.Compile("implements/member/@api");
+
+ /// <summary>
+ /// XPathExpression for <inheritdoc /> nodes.
+ /// </summary>
+ private static XPathExpression inheritDocExpression = XPathExpression.Compile("//inheritdoc");
+
+ /// <summary>
+ /// XPathExpression that looks for example, filterpriority, preliminary, remarks, returns, summary, threadsafety and value nodes.
+ /// </summary>
+ private static XPathExpression tagsExpression = XPathExpression.Compile("example|filterpriority|preliminary|remarks|returns|summary|threadsafety|value");
+
+ /// <summary>
+ /// XPathExpression for source nodes.
+ /// </summary>
+ private static XPathExpression sourceExpression;
+
+ /// <summary>
+ /// Document to be parsed.
+ /// </summary>
+ private XmlDocument sourceDocument;
+
+ /// <summary>
+ /// A cache for comment files.
+ /// </summary>
+ private IndexedDocumentCache index;
+
+ /// <summary>
+ /// A cache for reflection files.
+ /// </summary>
+ private IndexedDocumentCache reflectionIndex;
+ #endregion
+
+ #region constructor
+ /// <summary>
+ /// Creates an instance of InheritDocumentationComponent class.
+ /// </summary>
+ /// <param name="configuration">Configuration section to be parsed.</param>
+ /// <param name="data">A dictionary object with string as key and object as value.</param>
+ public InheritDocumentationComponent(XPathNavigator configuration, Dictionary<string, object> data)
+ : base(configuration, data)
+ {
+ // get the copy commands
+ XPathNodeIterator copy_nodes = configuration.Select("copy");
+ foreach (XPathNavigator copy_node in copy_nodes)
+ {
+ // get the comments info
+ string source_name = copy_node.GetAttribute("name", string.Empty);
+ if (String.IsNullOrEmpty(source_name))
+ {
+ throw new ConfigurationErrorsException("Each copy command must specify an index to copy from.");
+ }
+
+ // get the reflection info
+ string reflection_name = copy_node.GetAttribute("use", String.Empty);
+ if (String.IsNullOrEmpty(reflection_name))
+ {
+ throw new ConfigurationErrorsException("Each copy command must specify an index to get reflection information from.");
+ }
+
+ this.index = (IndexedDocumentCache)data[source_name];
+ this.reflectionIndex = (IndexedDocumentCache)data[reflection_name];
+ }
+ }
+ #endregion
+
+ #region methods
+ /// <summary>
+ /// Deletes the specified node and logs the message.
+ /// </summary>
+ /// <param name="inheritDocNodeNavigator">navigator for inheritdoc node</param>
+ /// <param name="key">Id of the topic specified</param>
+ public static void DeleteNode(XPathNavigator inheritDocNodeNavigator, string key)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Info, string.Format(CultureInfo.InvariantCulture, "Comments are not found for topic:{0}", key));
+ inheritDocNodeNavigator.DeleteSelf();
+ }
+
+ /// <summary>
+ /// Implement inheritDocumentation.
+ /// </summary>
+ /// <param name="document">document to be parsed</param>
+ /// <param name="key">Id pf the topic specified</param>
+ public override void Apply(XmlDocument document, string key)
+ {
+ // default selection filter set not to inherit <overloads>.
+ sourceExpression = XPathExpression.Compile("*[not(local-name()='overloads')]");
+ this.sourceDocument = document;
+ this.InheritDocumentation(key);
+ }
+
+ /// <summary>
+ /// Inherit the documentation.
+ /// </summary>
+ /// <param name="key">Id of the topic specified</param>
+ public void InheritDocumentation(string key)
+ {
+ foreach (XPathNavigator inheritDocNodeNavigator in this.sourceDocument.CreateNavigator().Select(inheritDocExpression))
+ {
+ inheritDocNodeNavigator.MoveToParent();
+
+ XPathNodeIterator iterator = (XPathNodeIterator) inheritDocNodeNavigator.CreateNavigator().Evaluate(tagsExpression);
+
+ // do not inherit the comments if the tags specified in tagsExpression are already present.
+ if (iterator.Count != 0)
+ {
+ inheritDocNodeNavigator.MoveTo(this.sourceDocument.CreateNavigator().SelectSingleNode(inheritDocExpression));
+ inheritDocNodeNavigator.DeleteSelf();
+ continue;
+ }
+
+ inheritDocNodeNavigator.MoveTo(this.sourceDocument.CreateNavigator().SelectSingleNode(inheritDocExpression));
+
+ // Inherit from the specified API [id=cref].
+ string cref = inheritDocNodeNavigator.GetAttribute("cref", string.Empty);
+
+ if (!string.IsNullOrEmpty(cref))
+ {
+ XPathNavigator contentNodeNavigator = this.index.GetContent(cref);
+
+ // if no comments were found for the specified api, delete the <inheritdoc /> node,
+ // otherwise update the <inheritdoc /> node with the comments from the specified api.
+ if (contentNodeNavigator == null)
+ {
+ DeleteNode(inheritDocNodeNavigator, cref);
+ }
+ else
+ {
+ this.UpdateNode(inheritDocNodeNavigator, contentNodeNavigator);
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count != 0)
+ {
+ this.InheritDocumentation(cref);
+ }
+ }
+ }
+ else
+ {
+ XPathNavigator reflectionNodeNavigator = this.reflectionIndex.GetContent(key);
+
+ // no reflection information was found for the api, so delete <inheritdoc /> node.
+ if (reflectionNodeNavigator == null)
+ {
+ DeleteNode(inheritDocNodeNavigator, key);
+ continue;
+ }
+
+ string group = (string)reflectionNodeNavigator.Evaluate(apiGroupExpression);
+ string subgroup = (string)reflectionNodeNavigator.Evaluate(apiSubgroupExpression);
+
+ if (group == "type")
+ {
+ // Inherit from base types
+ XPathNodeIterator typeNodeIterator = (XPathNodeIterator)reflectionNodeNavigator.Evaluate(typeExpression);
+ this.GetComments(typeNodeIterator, inheritDocNodeNavigator);
+
+ // no <inheritdoc /> nodes were found, so continue with next iteration. Otherwise inherit from interface implementation types.
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count == 0)
+ {
+ continue;
+ }
+
+ // Inherit from interface implementation types
+ XPathNodeIterator interfaceNodeIterator = (XPathNodeIterator)reflectionNodeNavigator.Evaluate(interfaceImplementationExpression);
+ this.GetComments(interfaceNodeIterator, inheritDocNodeNavigator);
+ }
+ else if (group == "member")
+ {
+ // constructors do not have override member information in reflection files, so search all the base types for a matching signature.
+ if (subgroup == "constructor")
+ {
+ string name = (string)reflectionNodeNavigator.Evaluate(apiNameExpression);
+ string typeApi = (string) reflectionNodeNavigator.Evaluate(containerTypeExpression);
+
+ // no container type api was found, so delete <inheritdoc /> node.
+ if (string.IsNullOrEmpty(typeApi))
+ {
+ DeleteNode(inheritDocNodeNavigator, key);
+ continue;
+ }
+
+ reflectionNodeNavigator = this.reflectionIndex.GetContent(typeApi);
+
+ // no reflection information for container type api was found, so delete <inheritdoc /> node.
+ if (reflectionNodeNavigator == null)
+ {
+ DeleteNode(inheritDocNodeNavigator, key);
+ continue;
+ }
+
+ XPathNodeIterator containerIterator = reflectionNodeNavigator.Select(typeExpression);
+
+ foreach (XPathNavigator containerNavigator in containerIterator)
+ {
+ string constructorId = string.Format(CultureInfo.InvariantCulture, "M:{0}.{1}", containerNavigator.Value.Substring(2), name.Replace('.', '#'));
+ XPathNavigator contentNodeNavigator = this.index.GetContent(constructorId);
+
+ if (contentNodeNavigator == null)
+ {
+ continue;
+ }
+
+ this.UpdateNode(inheritDocNodeNavigator, contentNodeNavigator);
+
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count == 0)
+ {
+ break;
+ }
+ else
+ {
+ inheritDocNodeNavigator.MoveTo(this.sourceDocument.CreateNavigator().SelectSingleNode(inheritDocExpression));
+ }
+ }
+ }
+ else
+ {
+ // Inherit from override members.
+ XPathNodeIterator memberNodeIterator = (XPathNodeIterator)reflectionNodeNavigator.Evaluate(overrideMemberExpression);
+ this.GetComments(memberNodeIterator, inheritDocNodeNavigator);
+
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count == 0)
+ {
+ continue;
+ }
+
+ // Inherit from interface implementations members.
+ XPathNodeIterator interfaceNodeIterator = (XPathNodeIterator)reflectionNodeNavigator.Evaluate(interfaceImplementationMemberExpression);
+ this.GetComments(interfaceNodeIterator, inheritDocNodeNavigator);
+ }
+ }
+
+ // no comments were found, so delete <iheritdoc /> node.
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count != 0)
+ {
+ DeleteNode(inheritDocNodeNavigator, key);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Updates the node replacing inheritdoc node with comments found.
+ /// </summary>
+ /// <param name="inheritDocNodeNavigator">Navigator for inheritdoc node</param>
+ /// <param name="contentNodeNavigator">Navigator for content</param>
+ public void UpdateNode(XPathNavigator inheritDocNodeNavigator, XPathNavigator contentNodeNavigator)
+ {
+ // retrieve the selection filter if specified.
+ string selectValue = inheritDocNodeNavigator.GetAttribute("select", string.Empty);
+
+ if (!string.IsNullOrEmpty(selectValue))
+ {
+ sourceExpression = XPathExpression.Compile(selectValue);
+ }
+
+ inheritDocNodeNavigator.MoveToParent();
+
+ if (inheritDocNodeNavigator.LocalName != "comments" && inheritDocNodeNavigator.LocalName != "element")
+ {
+ sourceExpression = XPathExpression.Compile(inheritDocNodeNavigator.LocalName);
+ }
+ else
+ {
+ inheritDocNodeNavigator.MoveTo(this.sourceDocument.CreateNavigator().SelectSingleNode(inheritDocExpression));
+ }
+
+ XPathNodeIterator sources = (XPathNodeIterator) contentNodeNavigator.CreateNavigator().Evaluate(sourceExpression);
+ inheritDocNodeNavigator.DeleteSelf();
+
+ // append the source nodes to the target node
+ foreach (XPathNavigator source in sources)
+ {
+ inheritDocNodeNavigator.AppendChild(source);
+ }
+ }
+
+ /// <summary>
+ /// Gets the comments for inheritdoc node.
+ /// </summary>
+ /// <param name="iterator">Iterator for API information</param>
+ /// <param name="inheritDocNodeNavigator">Navigator for inheritdoc node</param>
+ public void GetComments(XPathNodeIterator iterator, XPathNavigator inheritDocNodeNavigator)
+ {
+ foreach (XPathNavigator navigator in iterator)
+ {
+ XPathNavigator contentNodeNavigator = this.index.GetContent(navigator.Value);
+
+ if (contentNodeNavigator == null)
+ {
+ continue;
+ }
+
+ this.UpdateNode(inheritDocNodeNavigator, contentNodeNavigator);
+
+ if (this.sourceDocument.CreateNavigator().Select(inheritDocExpression).Count == 0)
+ {
+ break;
+ }
+ else
+ {
+ inheritDocNodeNavigator.MoveTo(this.sourceDocument.CreateNavigator().SelectSingleNode(inheritDocExpression));
+ }
+ }
+ }
+ #endregion
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/CopyComponents/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c834f96
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/CopyComponents/Properties/AssemblyInfo.cs
@@ -0,0 +1,46 @@
+//--------------------------------------------------------------------------
+// <copyright file="AssemblyInfo.cs" company="Microsoft">
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+// </copyright>
+// <summary>Contains metadata information for the assembly.</summary>
+//--------------------------------------------------------------------------
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CopyComponents")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CopyComponents")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b14061be-8075-4418-a99f-432362137031")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/AspNetSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/AspNetSyntax.cs
new file mode 100644
index 0000000..8f25f1b
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/AspNetSyntax.cs
@@ -0,0 +1,210 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class AspNetSyntaxGenerator : SyntaxGenerator {
+
+ public AspNetSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ }
+
+ protected static XPathExpression nameExpression = XPathExpression.Compile("string(apidata/@name)");
+ protected static XPathExpression groupExpression = XPathExpression.Compile("string(apidata/@group)");
+ protected static XPathExpression subgroupExpression = XPathExpression.Compile("string(apidata/@subgroup)");
+
+ protected static XPathExpression containingTypeExpression = XPathExpression.Compile("containers/type");
+ protected static XPathExpression declaringTypeExpression = XPathExpression.Compile("string(containers/type/@api)");
+ protected static XPathExpression propertyTypeExpression = XPathExpression.Compile("string(returns/type/@api)");
+ protected static XPathExpression propertyIsSettable = XPathExpression.Compile("boolean(propertydata/@set='true')");
+ protected static XPathExpression eventHandlerTypeExpression = XPathExpression.Compile("string(eventhandler/type/@api)");
+
+ protected static XPathExpression typeIsWebControl = XPathExpression.Compile("boolean(family/ancestors/type[@api='T:System.Web.UI.Control'])");
+
+ protected static XPathExpression propertyIsInnerProperty = XPathExpression.Compile("boolean(attributes/attribute[type/@api='T:System.Web.UI.PersistenceModeAttribute' and argument/enumValue/field/@name='InnerProperty'])");
+
+ protected static XPathExpression containingNamespaceExpression = XPathExpression.Compile("string(containers/namespace/@api)");
+
+ private string language = "AspNet";
+
+ public string Language {
+ get {
+ return (language);
+ }
+ }
+
+ public override void WriteSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string group = (string)reflection.Evaluate(groupExpression);
+ string subgroup = (string)reflection.Evaluate(subgroupExpression);
+
+ if (group == "type" && subgroup == "class") {
+ string prefix = WebControlPrefix(reflection);
+ if (!String.IsNullOrEmpty(prefix)) {
+ WriteClassSyntax(reflection, writer, prefix);
+ }
+ }
+
+ if (group == "member") {
+
+ string prefix = null;
+ XPathNavigator containingType = reflection.SelectSingleNode(containingTypeExpression);
+ if (containingType != null) prefix = WebControlPrefix(containingType);
+
+ if (!String.IsNullOrEmpty(prefix)) {
+ if (subgroup == "property") {
+ WritePropertySyntax(reflection, writer, prefix);
+ } else if (subgroup == "event") {
+ WriteEventSyntax(reflection, writer, prefix);
+ }
+ }
+ }
+
+
+ }
+
+ private string WebControlPrefix (XPathNavigator reflection) {
+ if ((bool)reflection.Evaluate(typeIsWebControl)) {
+ string name = (string)reflection.Evaluate(nameExpression);
+ string space = (string)reflection.Evaluate(containingNamespaceExpression);
+ if ((space == "N:System.Web.UI") && ((name == "Page") || (name == "ScriptControl") || (name == "UserControl"))) {
+ return (null);
+ } else {
+ if (space == "N:System.Web.UI.MobileControls") {
+ return ("mobile");
+ } else {
+ return ("asp");
+ }
+ }
+ } else {
+ return (null);
+ }
+ }
+
+ private void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer, string prefix) {
+
+ string name = (string)reflection.Evaluate(nameExpression);
+
+ writer.WriteStartBlock(Language);
+
+ writer.WriteString("<");
+ writer.WriteString(prefix);
+ writer.WriteString(":");
+ writer.WriteString(name);
+ writer.WriteString(" />");
+
+ writer.WriteEndBlock();
+
+ }
+
+ private void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer, string prefix) {
+
+ bool set = (bool) reflection.Evaluate(propertyIsSettable);
+ if (!set) return;
+
+ string name = (string) reflection.Evaluate(nameExpression);
+ string declaringType = (string) reflection.Evaluate(declaringTypeExpression);
+ string propertyType = (string) reflection.Evaluate(propertyTypeExpression);
+
+ bool isInnerProperty = (bool)reflection.Evaluate(propertyIsInnerProperty);
+
+ writer.WriteStartBlock(Language);
+
+ if (isInnerProperty) {
+
+ // inner property logic
+
+ writer.WriteString("<");
+ writer.WriteString(prefix);
+ writer.WriteString(":");
+ writer.WriteReferenceLink(declaringType);
+ writer.WriteString(">");
+
+ writer.WriteLine();
+ writer.WriteString("\t");
+
+ writer.WriteString("<");
+ writer.WriteString(name);
+ writer.WriteString(">");
+ if (String.IsNullOrEmpty(propertyType)) {
+ writer.WriteParameter("value");
+ } else {
+ if (propertyType == "T:System.Boolean") {
+ writer.WriteString("True|False");
+ } else {
+ writer.WriteReferenceLink(propertyType);
+ }
+ }
+ writer.WriteString("</");
+ writer.WriteString(name);
+ writer.WriteString(">");
+
+ writer.WriteLine();
+
+ writer.WriteString("</");
+ writer.WriteString(prefix);
+ writer.WriteString(":");
+ writer.WriteReferenceLink(declaringType);
+ writer.WriteString(">");
+
+ } else {
+
+ // normal property logic
+
+ writer.WriteString("<");
+ writer.WriteString(prefix);
+ writer.WriteString(":");
+ writer.WriteReferenceLink(declaringType);
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ writer.WriteString("=\"");
+ if (String.IsNullOrEmpty(propertyType)) {
+ writer.WriteParameter("value");
+ } else {
+ if (propertyType == "T:System.Boolean") {
+ writer.WriteString("True|False");
+ } else {
+ writer.WriteReferenceLink(propertyType);
+ }
+ }
+ writer.WriteString("\" />");
+
+ }
+
+ writer.WriteEndBlock();
+
+ }
+
+ private void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer, string prefix) {
+
+ string name = (string)reflection.Evaluate(nameExpression);
+ string declaringType = (string)reflection.Evaluate(declaringTypeExpression);
+ string handlerType = (string)reflection.Evaluate(eventHandlerTypeExpression);
+
+ writer.WriteStartBlock(Language);
+
+ writer.WriteString("<");
+ writer.WriteString(prefix);
+ writer.WriteString(":");
+ writer.WriteReferenceLink(declaringType);
+ writer.WriteString(" ");
+ writer.WriteString("On");
+ writer.WriteString(name);
+ writer.WriteString("=\"");
+ writer.WriteReferenceLink(handlerType);
+ writer.WriteString("\" />");
+
+ writer.WriteEndBlock();
+
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CPlusPlusDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CPlusPlusDeclarationSyntax.cs
new file mode 100644
index 0000000..56c6316
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CPlusPlusDeclarationSyntax.cs
@@ -0,0 +1,1065 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class CPlusPlusDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+
+ public CPlusPlusDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "ManagedCPlusPlus";
+ }
+
+ // namespace: done
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteKeyword("namespace");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool) reflection.Evaluate(apiIsSealedTypeExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer);
+ WriteAttributes(reflection, writer);
+
+ WriteGenericTemplates(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("ref class");
+ writer.WriteString(" ");
+
+ writer.WriteIdentifier(name);
+
+ if (isAbstract) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("abstract");
+ }
+ if (isSealed) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("sealed");
+ }
+
+ WriteBaseClassAndImplementedInterfaces(reflection, writer);
+
+ }
+
+ // structure: add base type declaration
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer);
+ WriteAttributes(reflection, writer);
+
+ WriteGenericTemplates(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("value class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteImplementedInterfaces(reflection, writer);
+
+ }
+
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteAttributes(reflection, writer);
+
+ WriteGenericTemplates(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("interface class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteImplementedInterfaces(reflection, writer);
+
+ }
+
+ // delegate: done
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer);
+ WriteAttributes(reflection, writer);
+
+ WriteGenericTemplates(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("delegate");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", true, writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("enum class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ // *** ENUM BASE ***
+
+ }
+
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+
+ WriteAttributes(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(":");
+ writer.WriteLine();
+
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ writer.WriteIdentifier(name);
+
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+
+ WriteAttributes(reflection, writer);
+
+ if (typeSubgroup == "interface") {
+ WriteGenericTemplates(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+ } else {
+ WriteProcedureVisibility(reflection, writer);
+ WriteGenericTemplates(reflection, writer);
+ WritePrefixProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+ WritePostfixProcedureModifiers(reflection, writer);
+ }
+ WriteExplicitImplementations(reflection, writer);
+
+ }
+
+ private void WriteExplicitImplementations (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ if (isExplicit) {
+ writer.WriteString(" = ");
+
+ XPathNodeIterator implements = reflection.Select(apiImplementedMembersExpression);
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ //string id = (string)implement.GetAttribute("api", String.Empty);
+ XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression);
+
+ if (implements.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(contract, false, writer);
+ writer.WriteString("::");
+ WriteMemberReference(implement, writer);
+ // writer.WriteReferenceLink(id);
+ }
+ }
+ }
+
+ public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ string identifier;
+ switch (name) {
+ case "UnaryPlus":
+ identifier = "+";
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ break;
+ case "Increment":
+ identifier = "++";
+ break;
+ case "Decrement":
+ identifier = "--";
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "!";
+ break;
+ // binary comparison operators
+ case "Equality":
+ identifier = "==";
+ break;
+ case "Inequality":
+ identifier = "!=";
+ break;
+ case "LessThan":
+ identifier = "<";
+ break;
+ case "GreaterThan":
+ identifier = ">";
+ break;
+ case "LessThanOrEqual":
+ identifier = "<=";
+ break;
+ case "GreaterThanOrEqual":
+ identifier = ">=";
+ break;
+ // binary math operators
+ case "Addition":
+ identifier = "+";
+ break;
+ case "Subtraction":
+ identifier = "-";
+ break;
+ case "Multiply":
+ identifier = "*";
+ break;
+ case "Division":
+ identifier = "/";
+ break;
+ case "Modulus":
+ identifier = "%";
+ break;
+ // binary logical operators
+ case "BitwiseAnd":
+ identifier = "&";
+ break;
+ case "BitwiseOr":
+ identifier = "|";
+ break;
+ case "ExclusiveOr":
+ identifier = "^";
+ break;
+ // bit-array operators
+ case "OnesComplement":
+ identifier = "~";
+ break;
+ case "LeftShift":
+ identifier = "<<";
+ break;
+ case "RightShift":
+ identifier = ">>";
+ break;
+ // others
+ case "Comma":
+ identifier = ",";
+ break;
+ case "MemberSelection":
+ identifier = "->";
+ break;
+ case "AddressOf":
+ identifier = "&";
+ break;
+ case "PointerDereference":
+ identifier = "*";
+ break;
+ case "Assign":
+ identifier = "=";
+ break;
+ // unrecognized operator
+ default:
+ identifier = null;
+ break;
+ }
+
+ if (identifier == null) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ } else {
+
+ WriteProcedureVisibility(reflection, writer);
+ WritePrefixProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("operator");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(identifier);
+ WriteMethodParameters(reflection, writer);
+ }
+
+ }
+
+ public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ WritePrefixProcedureModifiers(reflection, writer);
+ if (name == "Implicit") {
+ writer.WriteKeyword("implicit operator");
+ } else if (name == "Explicit") {
+ writer.WriteKeyword("explicit operator");
+ } else {
+ throw new InvalidOperationException("invalid cast type: " + name);
+ }
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+ public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ bool isDefault = (bool)reflection.Evaluate(apiIsDefaultMemberExpression);
+ bool hasGetter = (bool) reflection.Evaluate(apiIsReadPropertyExpression);
+ bool hasSetter = (bool) reflection.Evaluate(apiIsWritePropertyExpression);
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureVisibility(reflection, writer);
+ WritePrefixProcedureModifiers(reflection, writer);
+ writer.WriteKeyword("property");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+
+ // if is default member, write default, otherwise write name
+ if (isDefault) {
+ writer.WriteKeyword("default");
+ } else {
+ writer.WriteIdentifier(name);
+ }
+
+ if (parameters.Count > 0) {
+ writer.WriteString("[");
+ WriteParameters(parameters.Clone(), false, writer);
+ writer.WriteString("]");
+ }
+
+ writer.WriteString(" {");
+ writer.WriteLine();
+
+ if (hasGetter) {
+ writer.WriteString("\t");
+
+ //write the get visibility
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ writer.WriteString(":");
+ writer.WriteString(" ");
+ }
+
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("get");
+ writer.WriteString(" ");
+
+ writer.WriteString("(");
+ WriteParameters(parameters.Clone(), false, writer);
+ writer.WriteString(")");
+
+ WritePostfixProcedureModifiers(reflection, writer);
+ if (isExplicit) {
+ XPathNavigator implement = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression);
+ //string id = (string) implement.GetAttribute("api", String.Empty);
+
+ writer.WriteString(" = ");
+ WriteTypeReference(contract, false, writer);
+ writer.WriteString("::");
+ WriteMemberReference(implement, writer);
+ //writer.WriteReferenceLink(id);
+ writer.WriteString("::");
+ writer.WriteKeyword("get");
+ }
+ writer.WriteString(";");
+ writer.WriteLine();
+ }
+
+ if (hasSetter) {
+ writer.WriteString("\t");
+
+ // write the set visibility
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ writer.WriteString(":");
+ writer.WriteString(" ");
+ }
+
+ writer.WriteKeyword("void");
+ writer.WriteString(" ");
+ writer.WriteKeyword("set");
+ writer.WriteString(" ");
+
+ writer.WriteString("(");
+ if (parameters.Count > 0) {
+ WriteParameters(parameters.Clone(), false, writer);
+ writer.WriteString(", ");
+ }
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+
+ WritePostfixProcedureModifiers(reflection, writer);
+ if (isExplicit) {
+ XPathNavigator implement = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ XPathNavigator contract = implement.SelectSingleNode(memberDeclaringTypeExpression);
+ //string id = (string) implement.GetAttribute("api", String.Empty);
+
+ writer.WriteString(" = ");
+ WriteTypeReference(contract, false, writer);
+ writer.WriteString("::");
+ WriteMemberReference(implement, writer);
+ //writer.WriteReferenceLink(id);
+ writer.WriteString("::");
+ writer.WriteKeyword("set");
+ }
+ writer.WriteString(";");
+ writer.WriteLine();
+ }
+
+
+ writer.WriteString("}");
+ }
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureVisibility(reflection, writer);
+ WritePrefixProcedureModifiers(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("event");
+ writer.WriteString(" ");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" {");
+ writer.WriteLine();
+
+ writer.WriteString("\t");
+ writer.WriteKeyword("void");
+ writer.WriteString(" ");
+ writer.WriteKeyword("add");
+ writer.WriteString(" (");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+ writer.WriteString(";");
+ writer.WriteLine();
+
+ writer.WriteString("\t");
+ writer.WriteKeyword("void");
+ writer.WriteString(" ");
+ writer.WriteKeyword("remove");
+ writer.WriteString(" (");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+ writer.WriteString(";");
+ writer.WriteLine();
+
+
+ writer.WriteString("}");
+
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool) reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool) reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool) reflection.Evaluate(apiIsSerializedFieldExpression);
+
+ if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", true, writer);
+ WriteAttributes(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(":");
+ writer.WriteLine();
+ if (isStatic) {
+ if (isLiteral) {
+ writer.WriteKeyword("literal");
+ } else {
+ writer.WriteKeyword("static");
+ }
+ writer.WriteString(" ");
+ }
+ if (isInitOnly) {
+ writer.WriteKeyword("initonly");
+ writer.WriteString(" ");
+ }
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ private void WritePrefixProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression);
+
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ } else if (isVirtual) {
+ writer.WriteKeyword("virtual");
+ writer.WriteString(" ");
+ }
+
+ }
+
+ private void WritePostfixProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression);
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractProcedureExpression);
+ bool isFinal = (bool) reflection.Evaluate(apiIsFinalExpression);
+ bool isOverride = (bool) reflection.Evaluate(apiIsOverrideExpression);
+
+ if (isVirtual) {
+ if (isAbstract) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("abstract");
+ }
+ if (isOverride) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("override");
+ }
+ if (isFinal) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("sealed");
+ }
+ }
+ }
+
+ // Visibility
+
+ private void WriteProcedureVisibility (XPathNavigator reflection, SyntaxWriter writer) {
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup != "interface") {
+ WriteVisibility(reflection, writer);
+ writer.WriteString(":");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteVisibility(XPathNavigator reflection, SyntaxWriter writer) {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+ WriteVisibility(visibility, writer);
+ }
+
+ private void WriteVisibility (string visibility, SyntaxWriter writer) {
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("public");
+ break;
+ case "family":
+ writer.WriteKeyword("protected");
+ break;
+ case "family or assembly":
+ writer.WriteKeyword("protected public");
+ break;
+ case "family and assembly":
+ writer.WriteKeyword("protected private");
+ break;
+ case "assembly":
+ writer.WriteKeyword("internal");
+ break;
+ case "private":
+ writer.WriteKeyword("private");
+ break;
+ }
+
+ }
+
+ // Generics
+
+ private void WriteGenericTemplates (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator templateNodes = (XPathNodeIterator) reflection.Evaluate(apiTemplatesExpression);
+ if (templateNodes.Count == 0) return;
+ XPathNavigator[] templates = ConvertIteratorToArray(templateNodes);
+ if (templates.Length == 0) return;
+
+ // generic declaration
+ writer.WriteKeyword("generic");
+ writer.WriteString("<");
+ for (int i=0; i<templates.Length; i++) {
+ XPathNavigator template = templates[i];
+ string name = (string) template.Evaluate(templateNameExpression);
+ if (i> 0) writer.WriteString(", ");
+ writer.WriteKeyword("typename");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ }
+ writer.WriteString(">");
+ writer.WriteLine();
+
+ // generic constraints
+ foreach (XPathNavigator template in templates) {
+ bool constrained = (bool) template.Evaluate(templateIsConstrainedExpression);
+ if (!constrained) continue;
+
+ string name = (string) template.Evaluate(templateNameExpression);
+
+ writer.WriteKeyword("where");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ writer.WriteString(" : ");
+
+ bool value = (bool) template.Evaluate(templateIsValueTypeExpression);
+ bool reference = (bool) template.Evaluate(templateIsReferenceTypeExpression);
+ bool constructor = (bool) template.Evaluate(templateIsConstructableExpression);
+ XPathNodeIterator constraints = template.Select(templateConstraintsExpression);
+
+ // keep track of whether there is a previous constraint, so we know whether to put a comma
+ bool previous = false;
+
+ if (value) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("value class");
+ previous = true;
+ }
+
+ if (reference) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("ref class");
+ previous = true;
+ }
+
+ if (constructor) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("gcnew");
+ writer.WriteString("()");
+ previous = true;
+ }
+
+ foreach (XPathNavigator constraint in constraints) {
+ if (previous) writer.WriteString(", ");
+ WriteTypeReference(constraint, false, writer);
+ previous = true;
+ }
+
+ writer.WriteLine();
+
+ }
+
+ }
+
+ // Interfaces
+
+ private void WriteImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ if (implements.Count == 0) return;
+ writer.WriteString(" : ");
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, false, writer);
+ if (implements.CurrentPosition < implements.Count) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ }
+
+ private void WriteBaseClassAndImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ bool hasBaseClass = (baseClass != null) && !((bool) baseClass.Evaluate(typeIsObjectExpression));
+ bool hasImplementedInterfaces = (implements.Count > 0);
+
+ if (hasBaseClass || hasImplementedInterfaces) {
+
+ writer.WriteString(" : ");
+ if (hasBaseClass) {
+ writer.WriteKeyword("public");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, false, writer);
+ if (hasImplementedInterfaces) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, false, writer);
+ if (implements.CurrentPosition < implements.Count) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // Return Value
+
+ private void WriteReturnValue (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (type == null) {
+ writer.WriteKeyword("void");
+ } else {
+ WriteTypeReference(type, writer);
+ }
+ }
+
+
+ private void WriteMethodParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ writer.WriteString("(");
+ if (parameters.Count > 0) {
+ writer.WriteLine();
+ WriteParameters(parameters, true, writer);
+ }
+ writer.WriteString(")");
+
+ }
+
+ private void WriteParameters (XPathNodeIterator parameters, bool multiline, SyntaxWriter writer) {
+
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ string name = (string) parameter.Evaluate(parameterNameExpression);
+ bool isIn = (bool) parameter.Evaluate(parameterIsInExpression);
+ bool isOut = (bool) parameter.Evaluate(parameterIsOutExpression);
+ bool isParamArray = (bool) parameter.Evaluate(parameterIsParamArrayExpression);
+
+ if (multiline) {
+ writer.WriteString("\t");
+ }
+ if (isIn) {
+ WriteAttribute("T:System.Runtime.InteropServices.InAttribute", false, writer);
+ writer.WriteString(" ");
+ }
+ if (isOut) {
+ WriteAttribute("T:System.Runtime.InteropServices.OutAttribute", false, writer);
+ writer.WriteString(" ");
+ }
+ if (isParamArray) writer.WriteString("... ");
+ WriteTypeReference(type, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+
+ if (parameters.CurrentPosition < parameters.Count) writer.WriteString(", ");
+ if (multiline) writer.WriteLine();
+ }
+
+ }
+
+ // Type references
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ WriteTypeReference(reference, true, writer);
+ }
+
+ private void WriteTypeReference (XPathNavigator reference, bool handle, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ int rank = Convert.ToInt32( reference.GetAttribute("rank",String.Empty) );
+ writer.WriteKeyword("array");
+ writer.WriteString("<");
+ WriteTypeReference(element, writer);
+ if (rank > 1) {
+ writer.WriteString(",");
+ writer.WriteString(rank.ToString());
+ }
+ writer.WriteString(">");
+ if (handle) writer.WriteString("^");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ writer.WriteString("%");
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ bool isRef = (reference.GetAttribute("ref", String.Empty) == "true");
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ if (handle && isRef) writer.WriteString("^");
+
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string reference, SyntaxWriter writer) {
+ switch (reference) {
+ case "T:System.Void":
+ writer.WriteReferenceLink(reference, "void");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(reference, "bool");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(reference, "unsigned char");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(reference, "signed char");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(reference, "wchar_t");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(reference, "short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(reference, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(reference, "long long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(reference, "unsigned short");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(reference, "unsigned int");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(reference, "unsigned long long");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(reference, "float");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(reference, "double");
+ break;
+ default:
+ writer.WriteReferenceLink(reference);
+ break;
+ }
+ }
+
+ // Attributes
+
+ private void WriteAttribute (string reference, bool newline, SyntaxWriter writer) {
+ writer.WriteString("[");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString("]");
+ if (newline) writer.WriteLine();
+ }
+
+ private void WriteAttributes (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator attributes = (XPathNodeIterator) reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes) {
+
+ XPathNavigator type = attribute.SelectSingleNode(typeExpression);
+
+ writer.WriteString("[");
+ WriteTypeReference(type, false, writer);
+
+
+ XPathNodeIterator arguments = (XPathNodeIterator) attribute.Select(attributeArgumentsExpression);
+ XPathNodeIterator assignments = (XPathNodeIterator) attribute.Select(attributeAssignmentsExpression);
+
+ if ((arguments.Count > 0) || (assignments.Count > 0)) {
+ writer.WriteString("(");
+ while (arguments.MoveNext()) {
+ XPathNavigator argument = arguments.Current;
+ if (arguments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ WriteValue(argument, writer);
+ }
+ if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", ");
+ while (assignments.MoveNext()) {
+ XPathNavigator assignment = assignments.Current;
+ if (assignments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ writer.WriteString((string) assignment.Evaluate(assignmentNameExpression));
+ writer.WriteString(" = ");
+ WriteValue(assignment, writer);
+
+ }
+ writer.WriteString(")");
+ }
+
+ writer.WriteString("]");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteValue (XPathNavigator parent, SyntaxWriter writer) {
+
+ XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression);
+ XPathNavigator value = parent.SelectSingleNode(valueExpression);
+ if (value == null) Console.WriteLine("null value");
+
+ switch (value.LocalName) {
+ case "nullValue":
+ writer.WriteKeyword("nullptr");
+ break;
+ case "typeValue":
+ writer.WriteKeyword("typeof");
+ writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), false, writer);
+ writer.WriteString(")");
+ break;
+ case "enumValue":
+ XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element);
+ while (fields.MoveNext()) {
+ string name = fields.Current.GetAttribute("name", String.Empty);
+ if (fields.CurrentPosition > 1) writer.WriteString("|");
+ WriteTypeReference(type, writer);
+ writer.WriteString("::");
+ writer.WriteString(name);
+ }
+ break;
+ case "value":
+ string text = value.Value;
+ string typeId = type.GetAttribute("api", String.Empty);
+ switch (typeId) {
+ case "T:System.String":
+ writer.WriteString("L\"");
+ writer.WriteString(text);
+ writer.WriteString("\"");
+ break;
+ case "T:System.Boolean":
+ bool bool_value = Convert.ToBoolean(text);
+ if (bool_value) {
+ writer.WriteKeyword("true");
+ } else {
+ writer.WriteKeyword("false");
+ }
+ break;
+ case "T:System.Char":
+ writer.WriteString(@"L'");
+ writer.WriteString(text);
+ writer.WriteString(@"'");
+ break;
+ }
+ break;
+ }
+
+ }
+
+ private void WriteMemberReference (XPathNavigator member, SyntaxWriter writer) {
+ string api = member.GetAttribute("api", String.Empty);
+ writer.WriteReferenceLink(api);
+ }
+
+ private static XPathNavigator[] ConvertIteratorToArray (XPathNodeIterator iterator) {
+ XPathNavigator[] result = new XPathNavigator[iterator.Count];
+ for (int i=0; i<result.Length; i++) {
+ iterator.MoveNext();
+ result[i] = iterator.Current.Clone();
+ }
+ return(result);
+ }
+
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..3b5922d
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/CSharpDeclarationSyntax.cs
@@ -0,0 +1,982 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class CSharpDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+
+ public CSharpDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "CSharp";
+ }
+
+ // namespace: done
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteKeyword("namespace");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ // class: done
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool) reflection.Evaluate(apiIsSealedTypeExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isAbstract) {
+ if (isSealed) {
+ writer.WriteKeyword("static");
+ } else {
+ writer.WriteKeyword("abstract");
+ }
+ writer.WriteString(" ");
+ } else {
+ if (isSealed) {
+ writer.WriteKeyword("sealed");
+ writer.WriteString(" ");
+ }
+ }
+ writer.WriteKeyword("class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ WriteBaseClassAndImplementedInterfaces(reflection, writer);
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ }
+
+
+ // structure: done
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("struct");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ WriteImplementedInterfaces(reflection, writer);
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ }
+
+ // interface: done
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("interface");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer, true); // interfaces need co/contravariance info
+ WriteImplementedInterfaces(reflection, writer);
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ }
+
+ // delegate: done
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("delegate");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer, true); // delegates need co/contravariance info
+ WriteMethodParameters(reflection, writer);
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ }
+
+ // enumeration: still need to handle non-standard base
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("enum");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ // constructor: done
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+
+ WriteAttributes(reflection, writer);
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ } else {
+ WriteVisibility(reflection, writer);
+ }
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+ // normal method: done
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+
+ WriteAttributes(reflection, writer);
+ if (!isExplicit) WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+
+ if (isExplicit) {
+ XPathNavigator member = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ //string memberName = (string) member.Evaluate(nameExpression);
+ //string id = member.GetAttribute("api", String.Empty);
+ XPathNavigator contract = member.SelectSingleNode(memberDeclaringTypeExpression);
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ WriteMemberReference(member, writer);
+ //writer.WriteReferenceLink(id);
+ } else {
+ writer.WriteIdentifier(name);
+ }
+ WriteGenericTemplates(reflection, writer);
+ WriteMethodParameters(reflection, writer);
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ }
+
+ // operator: done
+ public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ string identifier;
+ switch (name) {
+ // unary math operators
+ case "UnaryPlus":
+ identifier = "+";
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ break;
+ case "Increment":
+ identifier = "++";
+ break;
+ case "Decrement":
+ identifier = "--";
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "!";
+ break;
+ case "True":
+ identifier = "true";
+ break;
+ case "False":
+ identifier = "false";
+ break;
+ // binary comparison operators
+ case "Equality":
+ identifier = "==";
+ break;
+ case "Inequality":
+ identifier = "!=";
+ break;
+ case "LessThan":
+ identifier = "<";
+ break;
+ case "GreaterThan":
+ identifier = ">";
+ break;
+ case "LessThanOrEqual":
+ identifier = "<=";
+ break;
+ case "GreaterThanOrEqual":
+ identifier = ">=";
+ break;
+ // binary math operators
+ case "Addition":
+ identifier = "+";
+ break;
+ case "Subtraction":
+ identifier = "-";
+ break;
+ case "Multiply":
+ identifier = "*";
+ break;
+ case "Division":
+ identifier = "/";
+ break;
+ case "Modulus":
+ identifier = "%";
+ break;
+ // binary logical operators
+ case "BitwiseAnd":
+ identifier = "&";
+ break;
+ case "BitwiseOr":
+ identifier = "|";
+ break;
+ case "ExclusiveOr":
+ identifier = "^";
+ break;
+ // bit-array operators
+ case "OnesComplement":
+ identifier = "~";
+ break;
+ case "LeftShift":
+ identifier = "<<";
+ break;
+ case "RightShift":
+ identifier = ">>";
+ break;
+ // unrecognized operator
+ default:
+ identifier = null;
+ break;
+ }
+ if (identifier == null) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ } else {
+ WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("operator");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(identifier);
+ WriteMethodParameters(reflection, writer);
+ }
+ }
+
+ // cast: done
+ public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteProcedureModifiers(reflection, writer);
+ if (name == "Implicit") {
+ writer.WriteKeyword("implicit operator");
+ } else if (name == "Explicit") {
+ writer.WriteKeyword("explicit operator");
+ } else {
+ throw new InvalidCastException("Invalid cast.");
+ }
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isDefault = (bool)reflection.Evaluate(apiIsDefaultMemberExpression);
+ bool isGettable = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+ bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ WriteAttributes(reflection, writer);
+ if (!isExplicit) WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+
+ if (isExplicit)
+ {
+ XPathNavigator member = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ XPathNavigator contract = member.SelectSingleNode(memberDeclaringTypeExpression);
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ if (parameters.Count > 0)
+ {
+ // In C#, EII property with parameters is an indexer; use 'this' instead of the property's name
+ writer.WriteKeyword("this");
+ }
+ else
+ {
+ WriteMemberReference(member, writer);
+ }
+ }
+ else
+ {
+ // In C#, any property with parameters is an indexer, which is declared using 'this' instead of the property's name
+ if (isDefault || parameters.Count > 0)
+ {
+ writer.WriteKeyword("this");
+ }
+ else
+ {
+ writer.WriteIdentifier(name);
+ }
+ }
+
+ WritePropertyParameters(reflection, writer);
+ writer.WriteString(" {");
+ if (isGettable)
+ {
+ writer.WriteString(" ");
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("get");
+ writer.WriteString(";");
+ }
+ if (isSettable)
+ {
+ writer.WriteString(" ");
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("set");
+ writer.WriteString(";");
+ }
+ writer.WriteString(" }");
+ }
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+
+ WriteAttributes(reflection, writer);
+ if (!isExplicit) WriteProcedureModifiers(reflection, writer);
+ writer.WriteString("event");
+ writer.WriteString(" ");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+
+ if (isExplicit) {
+ XPathNavigator member = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ //string id = (string) member.GetAttribute("api", String.Empty);
+ XPathNavigator contract = member.SelectSingleNode(memberDeclaringTypeExpression);
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ WriteMemberReference(member, writer);
+ //writer.WriteReferenceLink(id);
+ // writer.WriteIdentifier(memberName);
+ } else {
+ writer.WriteIdentifier(name);
+ }
+ }
+
+ private void WriteProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression);
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractProcedureExpression);
+ bool isFinal = (bool) reflection.Evaluate(apiIsFinalExpression);
+ bool isOverride = (bool) reflection.Evaluate(apiIsOverrideExpression);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ } else {
+ if (isVirtual) {
+ if (isAbstract) {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ } else if (isOverride) {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ if (isFinal) {
+ writer.WriteKeyword("sealed");
+ writer.WriteString(" ");
+ }
+ } else {
+ if (!isFinal) {
+ writer.WriteKeyword("virtual");
+ writer.WriteString(" ");
+ }
+ }
+ }
+ }
+
+
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool) reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool) reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool) reflection.Evaluate(apiIsSerializedFieldExpression);
+
+ if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isStatic) {
+ if (isLiteral) {
+ writer.WriteKeyword("const");
+ } else {
+ writer.WriteKeyword("static");
+ }
+ writer.WriteString(" ");
+ }
+ if (isInitOnly) {
+ writer.WriteKeyword("readonly");
+ writer.WriteString(" ");
+ }
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ // Visibility
+
+ private void WriteVisibility (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+ WriteVisibility(visibility, writer);
+ }
+
+ private void WriteVisibility (string visibility, SyntaxWriter writer) {
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("public");
+ break;
+ case "family":
+ writer.WriteKeyword("protected");
+ break;
+ case "family or assembly":
+ writer.WriteKeyword("protected internal");
+ break;
+ case "assembly":
+ writer.WriteKeyword("internal");
+ break;
+ case "private":
+ writer.WriteKeyword("private");
+ break;
+ case "family and assembly":
+ // this isn't handled in C#
+ break;
+ }
+
+ }
+
+
+ // Attributes
+
+ private void WriteAttribute (string reference, SyntaxWriter writer) {
+ writer.WriteString("[");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString("]");
+ writer.WriteLine();
+ }
+
+
+ private void WriteAttributes (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator attributes = (XPathNodeIterator) reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes) {
+
+ XPathNavigator type = attribute.SelectSingleNode(attributeTypeExpression);
+ if (type.GetAttribute("api", String.Empty) == "T:System.Runtime.CompilerServices.ExtensionAttribute") continue;
+
+ writer.WriteString("[");
+ WriteTypeReference(type, writer);
+
+ XPathNodeIterator arguments = (XPathNodeIterator) attribute.Select(attributeArgumentsExpression);
+ XPathNodeIterator assignments = (XPathNodeIterator) attribute.Select(attributeAssignmentsExpression);
+
+ if ((arguments.Count > 0) || (assignments.Count > 0)) {
+ writer.WriteString("(");
+ while (arguments.MoveNext()) {
+ XPathNavigator argument = arguments.Current;
+ if (arguments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ WriteValue(argument, writer);
+ }
+ if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", ");
+ while (assignments.MoveNext()) {
+ XPathNavigator assignment = assignments.Current;
+ if (assignments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ writer.WriteString((string) assignment.Evaluate(assignmentNameExpression));
+ writer.WriteString(" = ");
+ WriteValue(assignment, writer);
+
+ }
+ writer.WriteString(")");
+ }
+
+ writer.WriteString("]");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteValue (XPathNavigator parent, SyntaxWriter writer) {
+
+ XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression);
+ XPathNavigator value = parent.SelectSingleNode(valueExpression);
+ if (value == null) Console.WriteLine("null value");
+
+ switch (value.LocalName) {
+ case "nullValue":
+ writer.WriteKeyword("null");
+ break;
+ case "typeValue":
+ writer.WriteKeyword("typeof");
+ writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), writer);
+ writer.WriteString(")");
+ break;
+ case "enumValue":
+ XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element);
+ while (fields.MoveNext()) {
+ string name = fields.Current.GetAttribute("name", String.Empty);
+ if (fields.CurrentPosition > 1) writer.WriteString("|");
+ WriteTypeReference(type, writer);
+ writer.WriteString(".");
+ writer.WriteString(name);
+ }
+ break;
+ case "value":
+ string text = value.Value;
+ string typeId = type.GetAttribute("api", String.Empty);
+ switch (typeId) {
+ case "T:System.String":
+ writer.WriteString("\"");
+ writer.WriteString(text);
+ writer.WriteString("\"");
+ break;
+ case "T:System.Boolean":
+ bool bool_value = Convert.ToBoolean(text);
+ if (bool_value) {
+ writer.WriteKeyword("true");
+ } else {
+ writer.WriteKeyword("false");
+ }
+ break;
+ case "T:System.Char":
+ writer.WriteString("'");
+ writer.WriteString(text);
+ writer.WriteString("'");
+ break;
+ }
+ break;
+ }
+
+ }
+
+ // Interfaces
+
+ private void WriteImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ if (implements.Count == 0) return;
+ writer.WriteString(" : ");
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, writer);
+ if (implements.CurrentPosition < implements.Count) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ }
+
+ private void WriteBaseClassAndImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ bool hasBaseClass = (baseClass != null) && !((bool) baseClass.Evaluate(typeIsObjectExpression));
+ bool hasImplementedInterfaces = (implements.Count > 0);
+
+ if (hasBaseClass || hasImplementedInterfaces) {
+
+ writer.WriteString(" : ");
+ if (hasBaseClass) {
+ WriteTypeReference(baseClass, writer);
+ if (hasImplementedInterfaces)
+ {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition)
+ {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, writer);
+ if (implements.CurrentPosition < implements.Count) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // Generics
+
+ private void WriteGenericTemplates (XPathNavigator reflection, SyntaxWriter writer) {
+
+ WriteGenericTemplates(reflection, writer, false);
+ }
+
+ private void WriteGenericTemplates(XPathNavigator reflection, SyntaxWriter writer, bool writeVariance)
+ {
+ XPathNodeIterator templates = (XPathNodeIterator)reflection.Evaluate(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+ writer.WriteString("<");
+ while (templates.MoveNext())
+ {
+ XPathNavigator template = templates.Current;
+ if (writeVariance)
+ {
+ bool contravariant = (bool)template.Evaluate(templateIsContravariantExpression);
+ bool covariant = (bool)template.Evaluate(templateIsCovariantExpression);
+
+ if (contravariant)
+ {
+ writer.WriteKeyword("in");
+ writer.WriteString(" ");
+ }
+ if (covariant)
+ {
+ writer.WriteKeyword("out");
+ writer.WriteString(" ");
+ }
+ }
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ if (templates.CurrentPosition < templates.Count) writer.WriteString(", ");
+ }
+ writer.WriteString(">");
+
+ }
+
+ private void WriteGenericTemplateConstraints (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator templates = reflection.Select(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+
+ writer.WriteLine();
+ foreach (XPathNavigator template in templates) {
+
+ bool constrained = (bool) template.Evaluate(templateIsConstrainedExpression);
+ if (constrained) {
+ string name = (string) template.Evaluate(templateNameExpression);
+
+ writer.WriteKeyword("where");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ writer.WriteString(" : ");
+ } else {
+ continue;
+ }
+
+ bool value = (bool) template.Evaluate(templateIsValueTypeExpression);
+ bool reference = (bool) template.Evaluate(templateIsReferenceTypeExpression);
+ bool constructor = (bool) template.Evaluate(templateIsConstructableExpression);
+ XPathNodeIterator constraints = template.Select(templateConstraintsExpression);
+
+ // keep track of whether there is a previous constraint, so we know whether to put a comma
+ bool previous = false;
+
+ if (value) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("struct");
+ previous = true;
+ }
+
+ if (reference) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("class");
+ previous = true;
+ }
+
+ if (constructor) {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("new");
+ writer.WriteString("()");
+ previous = true;
+ }
+
+ foreach (XPathNavigator constraint in constraints) {
+ if (previous) writer.WriteString(", ");
+ WriteTypeReference(constraint, writer);
+ previous = true;
+ }
+ writer.WriteLine();
+ }
+
+ }
+
+ // Parameters
+
+ private void WriteMethodParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ writer.WriteString("(");
+ if (parameters.Count > 0) {
+ writer.WriteLine();
+ WriteParameters(parameters, reflection, writer);
+ }
+ writer.WriteString(")");
+
+ }
+
+ private void WritePropertyParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ if (parameters.Count == 0) return;
+
+ writer.WriteString("[");
+ writer.WriteLine();
+ WriteParameters(parameters, reflection, writer);
+ writer.WriteString("]");
+
+ }
+
+
+ private void WriteParameters (XPathNodeIterator parameters, XPathNavigator reflection, SyntaxWriter writer) {
+
+ bool isExtension = (bool) reflection.Evaluate(apiIsExtensionMethod);
+
+
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+
+ string name = (string) parameter.Evaluate(parameterNameExpression);
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ bool isIn = (bool) parameter.Evaluate(parameterIsInExpression);
+ bool isOut = (bool) parameter.Evaluate(parameterIsOutExpression);
+ bool isRef = (bool) parameter.Evaluate(parameterIsRefExpression);
+ bool isParamArray = (bool) parameter.Evaluate(parameterIsParamArrayExpression);
+
+ writer.WriteString("\t");
+
+ if (isExtension && parameters.CurrentPosition == 1) {
+ writer.WriteKeyword("this");
+ writer.WriteString(" ");
+ }
+
+ if (isRef) {
+ if (isOut) {
+ writer.WriteKeyword("out");
+ } else {
+ writer.WriteKeyword("ref");
+ }
+ writer.WriteString(" ");
+ }
+
+ if (isParamArray) {
+ writer.WriteKeyword("params");
+ writer.WriteString(" ");
+ }
+
+ WriteTypeReference(type, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+
+ if (parameters.CurrentPosition < parameters.Count) writer.WriteString(",");
+ writer.WriteLine();
+ }
+
+ }
+
+ // Return Value
+
+ private void WriteReturnValue (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (type == null) {
+ writer.WriteKeyword("void");
+ } else {
+ WriteTypeReference(type, writer);
+ }
+ }
+
+ // References
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ int rank = Convert.ToInt32( reference.GetAttribute("rank",String.Empty) );
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i=1; i<rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string api, SyntaxWriter writer) {
+ switch (api) {
+ case "T:System.Void":
+ writer.WriteReferenceLink(api, "void");
+ break;
+ case "T:System.String":
+ writer.WriteReferenceLink(api, "string");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "bool");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "byte");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "sbyte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "ushort");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "uint");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "ulong");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "float");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "double");
+ break;
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "decimal");
+ break;
+ default:
+ writer.WriteReferenceLink(api);
+ break;
+ }
+ }
+
+ private void WriteMemberReference (XPathNavigator member, SyntaxWriter writer) {
+ string api = member.GetAttribute("api", String.Empty);
+ writer.WriteReferenceLink(api);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..7f10807
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/FSharpDeclarationSyntax.cs
@@ -0,0 +1,988 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools
+{
+
+ public class FSharpDeclarationSyntaxGenerator : SyntaxGeneratorTemplate
+ {
+
+ public FSharpDeclarationSyntaxGenerator(XPathNavigator configuration)
+ : base(configuration)
+ {
+ if (String.IsNullOrEmpty(Language)) Language = "FSharp";
+ }
+
+ // namespace: done
+ public override void WriteNamespaceSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteKeyword("namespace");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ public override void WriteClassSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ WriteDotNetObject(reflection, writer, "class");
+ }
+
+ // TODO: Use apiContainingTypeSubgroupExpression instead of passing in class, struct, interface
+ public override void WriteStructureSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteDotNetObject(reflection, writer, "struct");
+ }
+
+ public override void WriteInterfaceSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteDotNetObject(reflection, writer, "interface");
+ }
+
+
+ public override void WriteDelegateSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool)reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" = ");
+ writer.WriteLine();
+ writer.WriteString(" ");
+ writer.WriteKeyword("delegate");
+ writer.WriteString(" ");
+ writer.WriteKeyword("of");
+ writer.WriteString(" ");
+
+ WriteParameters(reflection, writer);
+
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+
+ }
+
+ public override void WriteEnumerationSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool)reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ WriteVisibility(reflection, writer);
+ writer.WriteIdentifier(name);
+ }
+
+ public override void WriteConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("new");
+ writer.WriteString(" : ");
+ WriteParameters(reflection, writer);
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ public override void WriteNormalMethodSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isOverride = (bool)reflection.Evaluate(apiIsOverrideExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+
+ WriteAttributes(reflection, writer);
+
+ WriteVisibility(reflection, writer);
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ WriteParameters(reflection, writer);
+ writer.WriteKeyword("->");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ WriteGenericTemplateConstraints(reflection, writer);
+
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+ public override void WriteOperatorSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ string identifier;
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ switch (name)
+ {
+ // unary math operators
+ case "UnaryPlus":
+ identifier = "+";
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ break;
+ case "Increment":
+ identifier = "++";
+ break;
+ case "Decrement":
+ identifier = "--";
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "not";
+ break;
+ case "True":
+ identifier = "true";
+ break;
+ case "False":
+ identifier = "false";
+ break;
+ // binary comparison operators
+ case "Equality":
+ identifier = "=";
+ break;
+ case "Inequality":
+ identifier = "<>";
+ break;
+ case "LessThan":
+ identifier = "<";
+ break;
+ case "GreaterThan":
+ identifier = ">";
+ break;
+ case "LessThanOrEqual":
+ identifier = "<=";
+ break;
+ case "GreaterThanOrEqual":
+ identifier = ">=";
+ break;
+ // binary math operators
+ case "Addition":
+ identifier = "+";
+ break;
+ case "Subtraction":
+ identifier = "-";
+ break;
+ case "Multiply":
+ identifier = "*";
+ break;
+ case "Division":
+ identifier = "/";
+ break;
+ case "Modulus":
+ identifier = "%";
+ break;
+ // binary logical operators
+ case "BitwiseAnd":
+ identifier = "&&&";
+ break;
+ case "BitwiseOr":
+ identifier = "|||";
+ break;
+ case "ExclusiveOr":
+ identifier = "^^^";
+ break;
+ // bit-array operators
+ case "OnesComplement":
+ identifier = null; // No F# equiv.
+ break;
+ case "LeftShift":
+ identifier = "<<<";
+ break;
+ case "RightShift":
+ identifier = ">>>";
+ break;
+ // unrecognized operator
+ default:
+ identifier = null;
+ break;
+ }
+ if (identifier == null)
+ {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ }
+ else
+ {
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ writer.WriteKeyword("let");
+ writer.WriteString(" ");
+ writer.WriteKeyword("inline");
+ writer.WriteKeyword(" ");
+
+ writer.WriteString("(");
+ writer.WriteIdentifier(identifier);
+ writer.WriteString(")");
+
+ WriteParameters(reflection, writer);
+ writer.WriteString(" : ");
+ WriteReturnValue(reflection, writer);
+
+ }
+ }
+
+ public override void WriteCastSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ writer.WriteMessage("UnsupportedCast_" + Language);
+ }
+
+ // DONE
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isGettable = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ WriteReturnValue(reflection, writer);
+
+ if (isSettable)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("with");
+ writer.WriteString(" ");
+
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ }
+
+ writer.WriteKeyword("get");
+ writer.WriteString(", ");
+
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ }
+
+ writer.WriteKeyword("set");
+ }
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+ public override void WriteEventSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+ XPathNavigator args = reflection.SelectSingleNode(apiEventArgsExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression) && !(bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ int iterations = isVirtual ? 2 : 1;
+
+ for (int i = 0; i < iterations; i++)
+ {
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ if (isVirtual)
+ if (i == 0)
+ {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ else
+ {
+ WriteMemberKeyword(reflection, writer);
+ }
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ writer.WriteReferenceLink("T:Microsoft.FSharp.Control.IEvent");
+
+ writer.WriteString("<");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(",");
+ writer.WriteLine();
+ writer.WriteString(" ");
+ if (args == null)
+ {
+ writer.WriteReferenceLink("T:System.EventArgs");
+ }
+ else
+ {
+ WriteTypeReference(args, writer);
+ }
+ writer.WriteString(">");
+ if (i == 0)
+ writer.WriteLine();
+ }
+ }
+
+
+ public override void WriteFieldSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool)reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool)reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool)reflection.Evaluate(apiIsSerializedFieldExpression);
+
+ if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", writer);
+ WriteAttributes(reflection, writer);
+
+
+ if (isStatic)
+ {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("val");
+ writer.WriteString(" ");
+
+ if (!isInitOnly)
+ {
+ writer.WriteKeyword("mutable");
+ writer.WriteString(" ");
+ }
+
+ WriteVisibility(reflection, writer);
+
+ writer.WriteIdentifier(name);
+
+ writer.WriteString(": ");
+ WriteReturnValue(reflection, writer);
+
+ }
+
+
+ private void WriteDotNetObject(XPathNavigator reflection, SyntaxWriter writer,
+ string kind)
+ {
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isSerializable = (bool)reflection.Evaluate(apiIsSerializableTypeExpression);
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+ bool hasBaseClass = (baseClass != null) && !((bool)baseClass.Evaluate(typeIsObjectExpression));
+
+ // CLR considers interfaces abstract.
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractTypeExpression) && kind != "interface";
+ bool isSealed = (bool)reflection.Evaluate(apiIsSealedTypeExpression);
+
+ if (isAbstract)
+ WriteAttribute("T:Microsoft.FSharp.Core.AbstractClassAttribute", writer);
+ if (isSealed)
+ WriteAttribute("T:Microsoft.FSharp.Core.SealedAttribute", writer);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+
+ writer.WriteKeyword("type");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ writer.WriteString(" = ");
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteLine();
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword(kind);
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteLine();
+ }
+
+ if (hasBaseClass)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("inherit");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, writer);
+ writer.WriteLine();
+ }
+
+
+ while (implements.MoveNext())
+ {
+ XPathNavigator implement = implements.Current;
+ writer.WriteString(" ");
+ writer.WriteKeyword("interface");
+ writer.WriteString(" ");
+ WriteTypeReference(implement, writer);
+ writer.WriteLine();
+ }
+
+ if (hasBaseClass || implements.Count != 0)
+ {
+ writer.WriteString(" ");
+ }
+ else
+ {
+ writer.WriteString(" ");
+ }
+
+ writer.WriteKeyword("end");
+
+ }
+
+ // Visibility
+
+ private void WriteVisibility(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+ WriteVisibility(visibility, writer);
+ }
+
+
+ private Dictionary<string, string> visibilityDictionary = new Dictionary<string, string>()
+ {
+ { "public", null }, // Default in F#, so unnecessary.
+ { "family", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "family or assembly", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "family and assembly", null }, // Not supported in F#, section 8.8 in F# spec.
+ { "assembly", "internal" },
+ { "private", "private" },
+ };
+
+ // DONE
+ private void WriteVisibility(string visibility, SyntaxWriter writer)
+ {
+
+ if(visibilityDictionary.ContainsKey(visibility) && visibilityDictionary[visibility] != null)
+ {
+ writer.WriteKeyword(visibilityDictionary[visibility]);
+ writer.WriteString(" ");
+ }
+
+ }
+
+ // Write member | abstract | override
+ private void WriteMemberKeyword(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ bool isOverride = (bool)reflection.Evaluate(apiIsOverrideExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+
+ if (isOverride)
+ {
+ writer.WriteKeyword("override");
+ }
+ else if (isAbstract)
+ {
+ writer.WriteKeyword("abstract");
+ }
+ else
+ {
+ writer.WriteKeyword("member");
+ }
+ writer.WriteString(" ");
+
+ return;
+ }
+
+ // Attributes
+
+ private void WriteAttribute(string reference, SyntaxWriter writer)
+ {
+ writer.WriteString("[<");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString(">]");
+ writer.WriteLine();
+ }
+
+
+ // Initial version
+ private void WriteAttributes(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator attributes = (XPathNodeIterator)reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes)
+ {
+
+ XPathNavigator type = attribute.SelectSingleNode(attributeTypeExpression);
+ if (type.GetAttribute("api", String.Empty) == "T:System.Runtime.CompilerServices.ExtensionAttribute") continue;
+
+ writer.WriteString("[<");
+ WriteTypeReference(type, writer);
+
+ XPathNodeIterator arguments = (XPathNodeIterator)attribute.Select(attributeArgumentsExpression);
+ XPathNodeIterator assignments = (XPathNodeIterator)attribute.Select(attributeAssignmentsExpression);
+
+ if ((arguments.Count > 0) || (assignments.Count > 0))
+ {
+ writer.WriteString("(");
+ while (arguments.MoveNext())
+ {
+ XPathNavigator argument = arguments.Current;
+ if (arguments.CurrentPosition > 1)
+ {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition)
+ {
+ writer.WriteLine();
+ writer.WriteString(" ");
+ }
+ }
+ WriteValue(argument, writer);
+ }
+ if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", ");
+ while (assignments.MoveNext())
+ {
+ XPathNavigator assignment = assignments.Current;
+ if (assignments.CurrentPosition > 1)
+ {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition)
+ {
+ writer.WriteLine();
+ writer.WriteString(" ");
+ }
+ }
+ writer.WriteString((string)assignment.Evaluate(assignmentNameExpression));
+ writer.WriteString(" = ");
+ WriteValue(assignment, writer);
+
+ }
+ writer.WriteString(")");
+ }
+
+ writer.WriteString(">]");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteValue(XPathNavigator parent, SyntaxWriter writer)
+ {
+
+ XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression);
+ XPathNavigator value = parent.SelectSingleNode(valueExpression);
+ if (value == null) Console.WriteLine("null value");
+
+ switch (value.LocalName)
+ {
+ case "nullValue":
+ writer.WriteKeyword("null");
+ break;
+ case "typeValue":
+ writer.WriteKeyword("typeof");
+ writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), writer);
+ writer.WriteString(")");
+ break;
+ case "enumValue":
+ XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element);
+ while (fields.MoveNext())
+ {
+ string name = fields.Current.GetAttribute("name", String.Empty);
+ if (fields.CurrentPosition > 1) writer.WriteString("|");
+ WriteTypeReference(type, writer);
+ writer.WriteString(".");
+ writer.WriteString(name);
+ }
+ break;
+ case "value":
+ string text = value.Value;
+ string typeId = type.GetAttribute("api", String.Empty);
+ switch (typeId)
+ {
+ case "T:System.String":
+ writer.WriteString("\"");
+ writer.WriteString(text);
+ writer.WriteString("\"");
+ break;
+ case "T:System.Boolean":
+ bool bool_value = Convert.ToBoolean(text);
+ if (bool_value)
+ {
+ writer.WriteKeyword("true");
+ }
+ else
+ {
+ writer.WriteKeyword("false");
+ }
+ break;
+ case "T:System.Char":
+ writer.WriteString("'");
+ writer.WriteString(text);
+ writer.WriteString("'");
+ break;
+ }
+ break;
+ }
+ }
+
+
+ // Generics
+
+ private void WriteGenericTemplates(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator templates = (XPathNodeIterator)reflection.Evaluate(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+ writer.WriteString("<");
+ while (templates.MoveNext())
+ {
+ XPathNavigator template = templates.Current;
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString("'");
+ writer.WriteString(name);
+ if (templates.CurrentPosition < templates.Count) writer.WriteString(", ");
+ }
+ WriteGenericTemplateConstraints(reflection, writer);
+ writer.WriteString(">");
+ }
+
+ private void WriteGenericTemplateConstraints(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator templates = reflection.Select(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+
+ foreach (XPathNavigator template in templates)
+ {
+
+ bool constrained = (bool)template.Evaluate(templateIsConstrainedExpression);
+ if (constrained)
+ {
+ string name = (string)template.Evaluate(templateNameExpression);
+
+ writer.WriteString(" ");
+ writer.WriteKeyword("when");
+ writer.WriteString(" '");
+ writer.WriteString(name);
+ writer.WriteString(" : ");
+ }
+ else
+ {
+ continue;
+ }
+
+ bool value = (bool)template.Evaluate(templateIsValueTypeExpression);
+ bool reference = (bool)template.Evaluate(templateIsReferenceTypeExpression);
+ bool constructor = (bool)template.Evaluate(templateIsConstructableExpression);
+ XPathNodeIterator constraints = template.Select(templateConstraintsExpression);
+
+ // keep track of whether there is a previous constraint, so we know whether to put a comma
+ bool previous = false;
+
+ if (value)
+ {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("struct");
+ previous = true;
+ }
+
+ if (reference)
+ {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("not struct");
+ previous = true;
+ }
+
+ if (constructor)
+ {
+ if (previous) writer.WriteString(", ");
+ writer.WriteKeyword("new");
+ writer.WriteString("()");
+ previous = true;
+ }
+
+ foreach (XPathNavigator constraint in constraints)
+ {
+ if (previous) writer.WriteString(" and ");
+ WriteTypeReference(constraint, writer);
+ previous = true;
+ }
+
+ }
+
+ }
+
+ // Parameters
+
+ private void WriteParameters(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ if (parameters.Count > 0)
+ {
+ WriteParameters(parameters, reflection, writer);
+ }
+ else
+ {
+ writer.WriteKeyword("unit");
+ writer.WriteString(" ");
+ }
+ return;
+ }
+
+
+
+ private void WriteParameters(XPathNodeIterator parameters, XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ bool isExtension = (bool)reflection.Evaluate(apiIsExtensionMethod);
+ writer.WriteLine();
+
+
+ while (parameters.MoveNext())
+ {
+ XPathNavigator parameter = parameters.Current;
+
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+ bool isOut = (bool)parameter.Evaluate(parameterIsOutExpression);
+ bool isRef = (bool)parameter.Evaluate(parameterIsRefExpression);
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+ writer.WriteString(":");
+ WriteTypeReference(type, writer);
+ if (isOut || isRef)
+ {
+ writer.WriteString(" ");
+ writer.WriteKeyword("byref");
+ }
+ if (parameters.CurrentPosition != parameters.Count)
+ {
+ writer.WriteString(" * ");
+ writer.WriteLine();
+ }
+ else
+ {
+ writer.WriteString(" ");
+ }
+ }
+
+ }
+
+ // Return Value
+
+ private void WriteReturnValue(XPathNavigator reflection, SyntaxWriter writer)
+ {
+
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (type == null)
+ {
+ writer.WriteKeyword("unit");
+ }
+ else
+ {
+ WriteTypeReference(type, writer);
+ }
+ }
+
+ // References
+
+ private void WriteTypeReference(XPathNavigator reference, SyntaxWriter writer)
+ {
+ switch (reference.LocalName)
+ {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", String.Empty));
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ writer.WriteKeyword("nativeptr");
+ writer.WriteString("<");
+ WriteTypeReference(pointee, writer);
+ writer.WriteString(">");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext())
+ {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString("'");
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext())
+ {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext())
+ {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ // DONE
+ private void WriteNormalTypeReference(string api, SyntaxWriter writer)
+ {
+ switch (api)
+ {
+ case "T:System.Void":
+ writer.WriteReferenceLink(api, "unit");
+ break;
+ case "T:System.String":
+ writer.WriteReferenceLink(api, "string");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "bool");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "byte");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "sbyte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "int16");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "int64");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "uint16");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "uint32");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "uint64");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "float32");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "float");
+ break;
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "decimal");
+ break;
+ default:
+ writer.WriteReferenceLink(api);
+ break;
+ }
+ }
+
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/GlobalSuppressions.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/GlobalSuppressions.cs
new file mode 100644
index 0000000..e8a0676
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/GlobalSuppressions.cs
@@ -0,0 +1,301 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#containingNamespaceExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#containingTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#declaringTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#eventHandlerTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#groupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#nameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#propertyIsSettable")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#propertyTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#subgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#typeIsWebControl")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#propertyIsInnerProperty")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.AspNetSyntaxGenerator.#WebControlPrefix(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1722:IdentifiersShouldNotHaveIncorrectPrefix", Scope = "type", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteAttribute(System.String,System.Boolean,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteMemberReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isExplicit", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteNormalMethodSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteOperatorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WritePostfixProcedureModifiers(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WritePrefixProcedureModifiers(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "typeSubgroup", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WritePropertySyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#LoadConfiguration(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteXamlXmlnsUri(System.String,System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteValue(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteValue(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteValue(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteValue(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,System.Boolean,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.DeclarationSyntaxGeneratorTemplate.#GetTemplateParameterName(System.String,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,System.Boolean,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.DeclarationSyntaxGeneratorTemplate.#GetTemplateParameterName(System.String,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#ReadFullContainingTypeName(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#ReadFullTypeName(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteAttachedPropertySyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteAttachedEventSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#ParseDocument(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.DeclarationSyntaxGeneratorTemplate.#GetTemplateParameterName(System.String,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#CreateCamelCaseName(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "parentIs", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "parentIs", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SubClass", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_excludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SubClass", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "SubClass", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Constructable", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsConstructableExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtorWithTypeConverter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtor")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterIsParamArrayExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Seperate", Scope = "member", Target = "Microsoft.Ddue.Tools.DeclarationSyntaxGeneratorTemplate.#SeperateTypes(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Subsubgroup", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiSubsubgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "typelist", Scope = "member", Target = "Microsoft.Ddue.Tools.DeclarationSyntaxGeneratorTemplate.#SeperateTypes(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_excludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtor")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtorWithTypeConverter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstractType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_readOnly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_attributeUsage")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1708:IdentifiersShouldDifferByMoreThanCase", Scope = "type", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "abstract", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "abstract", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "abstract", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "abstract", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstractType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "attribute", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_attributeUsage")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "class", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "class", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_excludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "class", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtor")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "class", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtorWithTypeConverter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "constructor", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#constructorOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "delegate", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#delegateOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "enumeration", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#enumerationOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "event", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "excluded", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_excludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "field", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#fieldOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Scope = "type", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID", Scope = "type", Target = "Microsoft.Ddue.Tools.XamlHeadingID")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "interface", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#interfaceOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "method", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#methodOverviewXamlSyntax")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "no", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtor")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "no", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#classXamlSyntax_noDefaultCtorWithTypeConverter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "no", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "no", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#nonXamlAssemblyBoilerplate")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "non", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "not", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "not", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "parent", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#eventXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "parent", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstract")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_abstractType")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_nonXamlParent")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_notPublic")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_noXamlSyntaxForInterfaceMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_parentIsExcludedSubClass")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "property", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_readOnly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "read", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#propertyXamlSyntax_readOnly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "struct", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_attributeUsage")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "struct", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlBoilerplateID.#structXamlSyntax_nonXaml")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "xaml", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlHeadingID.#xamlAttributeUsageHeading")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "xaml", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlHeadingID.#xamlContentElementUsageHeading")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "xaml", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlHeadingID.#xamlObjectElementUsageHeading")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "xaml", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlHeadingID.#xamlPropertyElementUsageHeading")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "xaml", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlHeadingID.#xamlSyntaxBoilerplateHeading")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteVisibility(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteAttribute(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteMemberReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteGenericTemplates(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteVisibility(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteAttributeList(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteAccessModifier(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#excludedAncestorList")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteOperatorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isIn", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNodeIterator,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "reflection", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteAttributeList(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "writer", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteAttributeList(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isSerialized", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteFieldSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteAttribute(System.String,Microsoft.Ddue.Tools.SyntaxWriter,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNamedNormalMethodSyntax(System.String,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNamedNormalMethodSyntax(System.String,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "name", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNamedNormalMethodSyntax(System.String,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "reflection", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNamedNormalMethodSyntax(System.String,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "writer", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNamedNormalMethodSyntax(System.String,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "reflection", Scope = "member", Target = "Microsoft.Ddue.Tools.JSharpDeclarationSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNodeIterator,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#HasAttribute(System.Xml.XPath.XPathNavigator,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#ReadContainingTypeName(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#ReadNamespaceName(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteIndentedNewLine(Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteParameter(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#ReadTypeName(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "reference", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WriteParameter(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "reference", Scope = "member", Target = "Microsoft.Ddue.Tools.ScriptSharpDeclarationSyntaxGenerator.#WritePropertySyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiAncestorsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiAttributesExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiBaseClassExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingAssemblyExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingNamespaceIdExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingNamespaceNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingTypeNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiContainingTypeSubgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiGetVisibilityExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiGroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiHandlerOfEventExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiImplementedInterfacesExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiImplementedMembersExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsAbstractProcedureExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsAbstractTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsDefaultMemberExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsExplicitImplementationExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsExtensionMethod")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsFamilyMemberExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsFinalExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsGenericExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsInitOnlyFieldExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsLiteralFieldExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsOverrideExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsReadPropertyExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsSealedTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsSerializableTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsSerializedFieldExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsSpecialExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsStaticExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsUnsafeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsVirtualExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsVolatileFieldExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiIsWritePropertyExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiOverridesMemberExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiParametersExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiReturnTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiSetVisibilityExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiSubgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiSubsubgroupExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiTemplatesExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiVisibilityExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiVisibilityOfMemberExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiVisibilityOfTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#assignmentNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attachedEventAdderExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attachedEventRemoverExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attachedPropertyGetterExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attachedPropertySetterExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attributeArgumentsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attributeAssignmentsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#attributeTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#maxPosition")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#memberDeclaringTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#nameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterIsInExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterIsOutExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterIsParamArrayExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterIsRefExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#parameterTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#specializationArgumentsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateConstraintsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsConstrainedExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsConstructableExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsReferenceTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsValueTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#typeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#typeIdExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#typeIsObjectExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#typeModifiersExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#typeOuterTypeExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#valueExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteAttribute(System.String,System.Boolean,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteMemberReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteOperatorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isIn", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteVisibility(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#.cctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteGenericTemplates(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteMemberReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteOperatorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNodeIterator,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "reflection", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNodeIterator,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#contentPropertyNameExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#excludedAncestorList")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#IsPrimitiveType(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#ObjectElementUsageForClassStruct(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isSerializable", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteClassSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "name", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteClassSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "name", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WriteStructureSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "propertyName", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlUsageSyntaxGenerator.#WritePropertySyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CPlusPlusDeclarationSyntaxGenerator.#WriteVisibility(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.CSharpDeclarationSyntaxGenerator.#WriteGenericTemplates(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteAttribute(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteConstructorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isLiteral", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteFieldSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteMemberKeyword(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isOverride", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteNormalMethodSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteNormalTypeReference(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteOperatorSyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isExtension", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteParameters(System.Xml.XPath.XPathNodeIterator,System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isGettable", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WritePropertySyntax(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteTypeReference(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.FSharpDeclarationSyntaxGenerator.#WriteValue(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#apiEventArgsExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsContravariantExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2211:NonConstantFieldsShouldNotBeVisible", Scope = "member", Target = "Microsoft.Ddue.Tools.SyntaxGeneratorTemplate.#templateIsCovariantExpression")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicDeclarationSyntaxGenerator.#WriteVisibility(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteGenericTemplates(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.VisualBasicUsageSyntaxGenerator.#WriteGenericTemplates(System.Xml.XPath.XPathNavigator,Microsoft.Ddue.Tools.SyntaxWriter,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.JScriptDeclarationSyntaxGenerator.#WriteVisibility(System.String,Microsoft.Ddue.Tools.SyntaxWriter)")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JScriptDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JScriptDeclarationSyntax.cs
new file mode 100644
index 0000000..27ac11d
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JScriptDeclarationSyntax.cs
@@ -0,0 +1,475 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Xml.XPath;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ public class JScriptDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+
+ public JScriptDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "JScript";
+ }
+
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ writer.WriteKeyword("package");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool)reflection.Evaluate(apiIsSealedTypeExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteAccessModifier(reflection, writer);
+ if (isSealed) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ } else if (isAbstract) {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("class");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ WriteBaseClass(reflection, writer);
+ WriteInterfaceList(reflection, writer);
+ }
+
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+ writer.WriteMessage("UnsupportedStructure_" + Language);
+ }
+
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteAccessModifier(reflection, writer);
+ writer.WriteKeyword("interface");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ WriteInterfaceList("extends", reflection, writer);
+ }
+
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+ writer.WriteMessage("UnsupportedDelegate_" + Language);
+ }
+
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteAccessModifier(reflection, writer);
+ writer.WriteKeyword("enum");
+ writer.WriteString(" ");
+ writer.WriteString(name);
+ // no JScript support for underlying types
+ }
+
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ if (isStatic) {
+ writer.WriteMessage("UnsupportedStaticConstructor_" + Language);
+ } else {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteAccessModifier(reflection, writer);
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+ WriteTypeReference(declaringType, writer);
+ WriteParameterList(reflection, writer);
+ }
+ }
+
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+ if (IsUnsupportedExplicit(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteParameterList(reflection, writer);
+ if (returnType != null) {
+ writer.WriteString(" : ");
+ WriteTypeReference(returnType, writer);
+ }
+ }
+
+ public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ if (IsUnsupportedExplicit(reflection, writer)) return;
+
+ if (reflection.Select(apiParametersExpression).Count > 0) {
+ writer.WriteMessage("UnsupportedIndex_" + Language);
+ return;
+ }
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isGettable = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (isGettable) {
+ WriteAttributeList(reflection, writer);
+
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ writer.WriteString(" ");
+ }
+
+ WriteProcedureModifiers(reflection, writer);
+ writer.WriteKeyword("function get");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" () : ");
+ WriteTypeReference(type, writer);
+ writer.WriteLine();
+ }
+
+ if (isSettable) {
+ WriteAttributeList(reflection, writer);
+
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ writer.WriteString(" ");
+ }
+
+ WriteProcedureModifiers(reflection, writer);
+ writer.WriteKeyword("function set");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" (");
+ writer.WriteParameter("value");
+ writer.WriteString(" : ");
+ WriteTypeReference(type, writer);
+ writer.WriteString(")");
+ }
+
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool)reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool)reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool)reflection.Evaluate(apiIsSerializedFieldExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ WriteAttributeList(reflection, writer);
+ WriteAccessModifier(reflection, writer);
+ if (isStatic) {
+ if (isLiteral) {
+ writer.WriteKeyword("const");
+ } else {
+ writer.WriteKeyword("static");
+ }
+ writer.WriteString(" ");
+ }
+ if (isInitOnly) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("var");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" : ");
+ WriteTypeReference(type, writer);
+ }
+
+ public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ }
+
+ public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedCast_" + Language);
+ }
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedEvent_" + Language);
+ }
+
+ private void WriteBaseClass (XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+
+ if ((baseClass != null) && !((bool)baseClass.Evaluate(typeIsObjectExpression))) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("extends");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, writer);
+ }
+ }
+
+ private void WriteInterfaceList (XPathNavigator reflection, SyntaxWriter writer) {
+ WriteInterfaceList("implements", reflection, writer);
+ }
+
+ private void WriteInterfaceList (string keyword, XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ if (implements.Count == 0) return;
+ writer.WriteString(" ");
+ writer.WriteKeyword(keyword);
+ writer.WriteString(" ");
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, writer);
+ if (implements.CurrentPosition < implements.Count) writer.WriteString(", ");
+ }
+ }
+
+ private void WriteProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string)reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ string subgroup = (string)reflection.Evaluate(apiSubgroupExpression);
+ if (subgroup != "property") {
+ WriteAccessModifier(reflection, writer);
+ }
+
+ // instance or virtual, static or abstract, etc.
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool)reflection.Evaluate(apiIsVirtualExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ bool isFinal = (bool)reflection.Evaluate(apiIsFinalExpression);
+ bool isOverride = (bool)reflection.Evaluate(apiIsOverrideExpression);
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ } else {
+ // all members are virtual in JScript, so no virtual keyword is required
+ if (isVirtual) {
+ if (isAbstract) {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ } else {
+ if (isOverride) {
+ writer.WriteKeyword("override");
+ writer.WriteString(" ");
+ }
+ if (isFinal) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ }
+ }
+ }
+ }
+ }
+
+ private void WriteParameterList (XPathNavigator reflection, SyntaxWriter writer) {
+ WriteParameterList(reflection, writer, true);
+ }
+
+ private void WriteParameterList (XPathNavigator reflection, SyntaxWriter writer, bool newlines) {
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ writer.WriteString("(");
+ if (newlines && (parameters.Count > 0)) writer.WriteLine();
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+ if (newlines) writer.WriteString("\t");
+ WriteParameter(parameter, writer);
+ if (parameters.CurrentPosition < parameters.Count) writer.WriteString(", ");
+ if (newlines) writer.WriteLine();
+ }
+ writer.WriteString(")");
+ }
+
+ // JScript has no in, out, optional, or reference parameters
+ private void WriteParameter (XPathNavigator parameter, SyntaxWriter writer) {
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ bool isParamArray = (bool)parameter.Evaluate(parameterIsParamArrayExpression);
+
+ if (isParamArray) {
+ writer.WriteString("... ");
+ }
+
+ writer.WriteParameter(name);
+ writer.WriteString(" : ");
+ WriteTypeReference(type, writer);
+ }
+
+ private void WriteAccessModifier (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("public");
+ break;
+ case "family":
+ writer.WriteKeyword("protected");
+ break;
+ case "family or assembly":
+ // this isn't handled in JScript
+ break;
+ case "assembly":
+ writer.WriteKeyword("internal");
+ break;
+ case "private":
+ writer.WriteKeyword("private");
+ break;
+ case "family and assembly":
+ // this isn't handled in JScript
+ break;
+ }
+
+ writer.WriteString(" ");
+
+ }
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", String.Empty));
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string api, SyntaxWriter writer) {
+ switch (api) {
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "boolean");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "byte");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "sbyte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "ushort");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "uint");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "ulong");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "float");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "double");
+ break;
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "decimal");
+ break;
+ default:
+ writer.WriteReferenceLink(api);
+ break;
+ }
+ }
+
+ private void WriteAttributeList (XPathNavigator reflection, SyntaxWriter writer) {
+ // fill in this logic
+ }
+
+ private void WriteVisibility(string visibility, SyntaxWriter writer) {
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("public");
+ break;
+ case "family":
+ writer.WriteKeyword("protected");
+ break;
+ case "family or assembly":
+ // this isn't handled in JScript
+ break;
+ case "assembly":
+ writer.WriteKeyword("internal");
+ break;
+ case "private":
+ writer.WriteKeyword("private");
+ break;
+ case "family and assembly":
+ // this isn't handled in JScript
+ break;
+ }
+
+ }
+
+ }
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..c6e3b0d
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/JSharpDeclarationSyntax.cs
@@ -0,0 +1,648 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ public class JSharpDeclarationSyntaxGenerator : DeclarationSyntaxGeneratorTemplate {
+
+ public JSharpDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "JSharp";
+ }
+
+ // private static string unsupportedGeneric = "UnsupportedGeneric_JSharp";
+
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteKeyword("package");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool) reflection.Evaluate(apiIsSealedTypeExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isSealed) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ } else if (isAbstract) {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+ if ((baseClass != null) && !((bool) baseClass.Evaluate(typeIsObjectExpression))) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("extends");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, writer);
+ }
+
+ WriteImplementedInterfaces(reflection, writer);
+
+ }
+
+
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ writer.WriteKeyword("class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ writer.WriteString(" ");
+ writer.WriteKeyword("extends");
+ writer.WriteString(" ");
+ writer.WriteReferenceLink("T:System.ValueType");
+
+ WriteImplementedInterfaces(reflection, writer);
+ }
+
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("interface");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteImplementedInterfaces("extends", reflection, writer);
+ }
+
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ writer.WriteString("/** @delegate */");
+ writer.WriteLine();
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("delegate");
+ writer.WriteString(" ");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("enum");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+
+ if (isStatic) {
+ // no static constructors in Java
+ writer.WriteMessage("UnsupportedStaticConstructor_" + Language);
+ return;
+ }
+
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+
+ }
+
+ public override void WriteMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isSpecialName = (bool) reflection.Evaluate(apiIsSpecialExpression);
+
+ if (isSpecialName) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ } else {
+ WriteNormalMethodSyntax(reflection, writer);
+ }
+ }
+
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ if (IsUnsupportedGeneric(reflection, writer)) return;
+ if (IsUnsupportedExplicit(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteMethodParameters(reflection, writer);
+ }
+
+ private void WriteNamedNormalMethodSyntax (string name, XPathNavigator reflection, SyntaxWriter writer) {
+
+
+ }
+
+ public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ if (IsUnsupportedExplicit(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isGettable = (bool) reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSettable = (bool) reflection.Evaluate(apiIsWritePropertyExpression);
+
+ if (isGettable) {
+ writer.WriteString("/** @property */");
+ writer.WriteLine();
+ // write getter method
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier("get_" + name);
+ WriteMethodParameters(reflection, writer);
+ writer.WriteLine();
+ }
+
+ if (isSettable) {
+ writer.WriteString("/** @property */");
+ writer.WriteLine();
+ // write setter method
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("void");
+ writer.WriteString(" ");
+ writer.WriteIdentifier("set_" + name);
+ // parameters
+ writer.WriteString("(");
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+ // end parameters
+ writer.WriteLine();
+ }
+
+ }
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ writer.WriteString("/** @event */");
+ writer.WriteLine();
+ // add_ method declaration
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier("add_" + name);
+ writer.WriteString(" (");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+ writer.WriteLine();
+
+ writer.WriteString("/** @event */");
+ writer.WriteLine();
+ // remove_ method declaration
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier("remove_" + name);
+ writer.WriteString(" (");
+ WriteTypeReference(handler, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter("value");
+ writer.WriteString(")");
+ writer.WriteLine();
+
+ }
+
+ private void WriteProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression);
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractProcedureExpression);
+ bool isFinal = (bool) reflection.Evaluate(apiIsFinalExpression);
+ // bool isOverride = (bool) reflection.Evaluate(apiIsOverrideExpression);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ } else {
+ if (isVirtual) {
+ if (isAbstract) {
+ writer.WriteKeyword("abstract");
+ writer.WriteString(" ");
+ } else if (isFinal) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ }
+ }
+ }
+
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool) reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool) reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool) reflection.Evaluate(apiIsSerializedFieldExpression);
+
+ if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ // Java doesn't support literals as distinct from static initonly
+ if (isStatic) {
+ writer.WriteKeyword("static");
+ writer.WriteString(" ");
+ }
+ if (isLiteral || isInitOnly) {
+ writer.WriteKeyword("final");
+ writer.WriteString(" ");
+ }
+ WriteReturnValue(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+
+ }
+
+ // Visibility
+
+ protected override void WriteVisibility (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string visibility = reflection.Evaluate(apiVisibilityExpression).ToString();
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("public");
+ break;
+ case "family":
+ // in Java, protected = family or assembly
+ writer.WriteKeyword("protected");
+ break;
+ case "family or assembly":
+ writer.WriteKeyword("protected");
+ break;
+ case "assembly":
+ // no assembly-only access in Java
+ break;
+ case "private":
+ writer.WriteKeyword("private");
+ break;
+ }
+
+ }
+
+ // Attributes
+
+ private void WriteAttribute (string reference, SyntaxWriter writer) {
+ WriteAttribute(reference, writer, true);
+ }
+
+ private void WriteAttribute (string reference, SyntaxWriter writer, bool newline) {
+ writer.WriteString("/** @attribute ");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString(" */ ");
+ if (newline) writer.WriteLine();
+ }
+
+
+ private void WriteAttributes (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator attributes = (XPathNodeIterator) reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes) {
+
+ XPathNavigator type = attribute.SelectSingleNode(attributeTypeExpression);
+
+ writer.WriteString("/** @attribute ");
+ WriteTypeReference(type, writer);
+
+ XPathNodeIterator arguments = (XPathNodeIterator) attribute.Select(attributeArgumentsExpression);
+ XPathNodeIterator assignments = (XPathNodeIterator) attribute.Select(attributeAssignmentsExpression);
+
+ if ((arguments.Count > 0) || (assignments.Count > 0)) {
+ writer.WriteString("(");
+ while (arguments.MoveNext()) {
+ XPathNavigator argument = arguments.Current;
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteValue(argument, writer);
+ }
+ if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", ");
+ while (assignments.MoveNext()) {
+ XPathNavigator assignment = assignments.Current;
+ if (assignments.CurrentPosition > 1) writer.WriteString(", ");
+ writer.WriteString((string) assignment.Evaluate(assignmentNameExpression));
+ writer.WriteString(" = ");
+ WriteValue(assignment, writer);
+ }
+ writer.WriteString(")");
+ }
+
+ writer.WriteString(" */");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteValue (XPathNavigator parent, SyntaxWriter writer) {
+
+ XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression);
+ XPathNavigator value = parent.SelectSingleNode(valueExpression);
+ // if (value == null) Console.WriteLine("null value");
+
+ switch (value.LocalName) {
+ case "nullValue":
+ writer.WriteKeyword("null");
+ break;
+ case "typeValue":
+ // this isn't really supported in J#; there is no compile-time way to get a type representation
+ // writer.WriteKeyword("typeof");
+ // writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), writer);
+ // writer.WriteString(")");
+ break;
+ case "enumValue":
+ XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element);
+ while (fields.MoveNext()) {
+ string name = fields.Current.GetAttribute("name", String.Empty);
+ if (fields.CurrentPosition > 1) writer.WriteString("|");
+ WriteTypeReference(type, writer);
+ writer.WriteString(".");
+ writer.WriteString(name);
+ }
+ break;
+ case "value":
+ string text = value.Value;
+ string typeId = type.GetAttribute("api", String.Empty);
+ switch (typeId) {
+ case "T:System.String":
+ writer.WriteString("\"");
+ writer.WriteString(text);
+ writer.WriteString("\"");
+ break;
+ case "T:System.Boolean":
+ bool bool_value = Convert.ToBoolean(text);
+ if (bool_value) {
+ writer.WriteKeyword("true");
+ } else {
+ writer.WriteKeyword("false");
+ }
+ break;
+ case "T:System.Char":
+ writer.WriteString("'");
+ writer.WriteString(text);
+ writer.WriteString("'");
+ break;
+ }
+ break;
+ }
+
+ }
+
+ // Interfaces
+
+ private void WriteImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+ WriteImplementedInterfaces("implements", reflection, writer);
+ }
+
+ private void WriteImplementedInterfaces (string keyword, XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ if (implements.Count == 0) return;
+
+ writer.WriteString(" ");
+ writer.WriteKeyword(keyword);
+ writer.WriteString(" ");
+
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ WriteTypeReference(implement, writer);
+ if (implements.CurrentPosition < implements.Count) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+
+ }
+ // Parameters
+
+ private void WriteMethodParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ writer.WriteString("(");
+ if (parameters.Count > 0) {
+ writer.WriteLine();
+ WriteParameters(parameters, reflection, writer);
+ }
+ writer.WriteString(")");
+
+ }
+
+
+ private void WriteParameters (XPathNodeIterator parameters, XPathNavigator reflection, SyntaxWriter writer) {
+
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+
+ string name = (string) parameter.Evaluate(parameterNameExpression);
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ bool isIn = (bool) parameter.Evaluate(parameterIsInExpression);
+ bool isOut = (bool) parameter.Evaluate(parameterIsOutExpression);
+ bool isRef = (bool) parameter.Evaluate(parameterIsRefExpression);
+ // bool isParamArray = (bool) parameter.Evaluate(parameterIsParamArrayExpression);
+
+ writer.WriteString("\t");
+
+ if (isIn) WriteAttribute("T:System.Runtime.InteropServices.InAttribute", writer, false);
+ if (isOut) WriteAttribute("T:System.Runtime.InteropServices.OutAttribute", writer, false);
+ if (isRef) {
+ writer.WriteString("/** @ref */");
+ }
+
+ WriteTypeReference(type, writer);
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+
+ if (parameters.CurrentPosition < parameters.Count) writer.WriteString(",");
+ writer.WriteLine();
+ }
+
+ }
+
+ // Return Value
+
+ private void WriteReturnValue (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (type == null) {
+ writer.WriteKeyword("void");
+ } else {
+ WriteTypeReference(type, writer);
+ }
+ }
+
+ // References
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ int rank = Convert.ToInt32( reference.GetAttribute("rank",String.Empty) );
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i=1; i<rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string reference, SyntaxWriter writer) {
+ switch (reference) {
+ case "T:System.Void":
+ writer.WriteReferenceLink(reference, "void");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(reference, "boolean");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(reference, "byte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(reference, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(reference, "short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(reference, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(reference, "long");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(reference, "float");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(reference, "double");
+ break;
+ default:
+ writer.WriteReferenceLink(reference);
+ break;
+ }
+ }
+
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..b425318
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/Properties/AssemblyInfo.cs
@@ -0,0 +1,42 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("SyntaxComponents")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("SyntaxComponents")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("52404499-7bf9-4908-88db-44f8de788cf0")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs
new file mode 100644
index 0000000..6958df6
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/ScriptSharpDeclarationSyntax.cs
@@ -0,0 +1,614 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Xml.XPath;
+using System.Globalization;
+
+namespace Microsoft.Ddue.Tools {
+ /// <summary>
+ /// Generates syntax that corresponds to JavaScript that Script# generates.
+ /// </summary>
+ public class ScriptSharpDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+ private static readonly XPathExpression typeIsRecordExpression = XPathExpression.Compile("boolean(apidata/@record)");
+
+ private static readonly XPathExpression memberIsGlobalExpression = XPathExpression.Compile("boolean(apidata/@global)");
+
+ /// <summary>
+ /// Initializes a new instance of the <c>ScriptSharpDeclarationSyntaxGenerator</c> class.
+ /// </summary>
+ /// <param name="configuration"></param>
+ public ScriptSharpDeclarationSyntaxGenerator(XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "JavaScript";
+ }
+
+ /// <summary>
+ /// Determines whether the feature is unsupported by this language.
+ /// </summary>
+ /// <param name="reflection"></param>
+ /// <param name="writer"></param>
+ /// <returns></returns>
+ private bool IsUnsupported(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedGeneric(reflection, writer)) {
+ return true;
+ }
+
+ if (IsUnsupportedExplicit(reflection, writer)) {
+ return true;
+ }
+
+ if (IsUnsupportedUnsafe(reflection, writer)) {
+ return true;
+ }
+
+ if (HasAttribute(reflection, "System.NonScriptableAttribute")) {
+ writer.WriteMessage("UnsupportedType_ScriptSharp");
+ return true;
+ }
+
+ return false;
+ }
+
+ private string ReadNamespaceName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiContainingNamespaceNameExpression);
+ }
+
+ private string ReadTypeName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiNameExpression);
+ }
+
+ private string ReadContainingTypeName(XPathNavigator reflection) {
+ return (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ }
+
+ private string ReadFullTypeName(XPathNavigator reflection) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadTypeName(reflection);
+
+ if (String.IsNullOrEmpty(namespaceName) || HasAttribute(reflection, "System.IgnoreNamespaceAttribute")) {
+ return typeName;
+ }
+ else {
+ return String.Format("{0}.{1}", namespaceName, typeName);
+ }
+ }
+
+ private string ReadFullContainingTypeName(XPathNavigator reflection) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadContainingTypeName(reflection);
+
+ if (String.IsNullOrEmpty(namespaceName) || HasAttribute(reflection, "System.IgnoreNamespaceAttribute")) {
+ return typeName;
+ }
+ else {
+ return String.Format("{0}.{1}", namespaceName, typeName);
+ }
+ }
+
+ private string ReadMemberName(XPathNavigator reflection) {
+ string identifier = (string)reflection.Evaluate(apiNameExpression);
+
+ if (!HasAttribute(reflection, "System.PreserveCaseAttribute")) {
+ identifier = CreateCamelCaseName(identifier);
+ }
+
+ return identifier;
+ }
+
+ private bool HasAttribute(XPathNavigator reflection, string attributeName) {
+ attributeName = "T:" + attributeName;
+
+ XPathNodeIterator iterator = (XPathNodeIterator)reflection.Evaluate(apiAttributesExpression);
+ foreach (XPathNavigator navigator in iterator) {
+ XPathNavigator reference = navigator.SelectSingleNode(attributeTypeExpression);
+ if (reference.GetAttribute("api", string.Empty) == attributeName) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public static string CreateCamelCaseName(string name) {
+
+ if (String.IsNullOrEmpty(name)) {
+ return name;
+ }
+
+ // Some exceptions that simply need to be special cased
+ if (name.Equals("ID", StringComparison.Ordinal)) {
+ return "id";
+ }
+
+ bool hasLowerCase = false;
+ int conversionLength = 0;
+
+ for (int i = 0; i < name.Length; i++) {
+ if (Char.IsUpper(name, i)) {
+ conversionLength++;
+ } else {
+ hasLowerCase = true;
+ break;
+ }
+ }
+
+ if (((hasLowerCase == false) && (name.Length != 1)) || (conversionLength == 0)) {
+ // Name is all upper case, or all lower case; leave it as-is.
+ return name;
+ }
+
+ if (conversionLength > 1) {
+ // Convert the leading uppercase segment, except the last character
+ // which is assumed to be the first letter of the next word
+ return name.Substring(0, conversionLength - 1).ToLower(CultureInfo.InvariantCulture) + name.Substring(conversionLength - 1);
+ }
+
+ else if (name.Length == 1) {
+ return name.ToLower(CultureInfo.InvariantCulture);
+ }
+
+ else {
+ // Convert the leading upper case character to lower case
+ return Char.ToLower(name[0], CultureInfo.InvariantCulture) + name.Substring(1);
+ }
+ }
+
+ private void WriteIndentedNewLine(SyntaxWriter writer) {
+ writer.WriteString(",");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+
+ private void WriteParameterList(XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+ writer.WriteString("(");
+
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+
+ WriteParameter(parameter, writer);
+ if (parameters.CurrentPosition < parameters.Count) {
+ writer.WriteString(", ");
+ }
+ }
+ writer.WriteString(")");
+ }
+
+ private void WriteParameter(XPathNavigator parameter, SyntaxWriter writer) {
+ string text = (string)parameter.Evaluate(parameterNameExpression);
+ XPathNavigator reference = parameter.SelectSingleNode(parameterTypeExpression);
+ if ((bool)parameter.Evaluate(parameterIsParamArrayExpression)) {
+ writer.WriteString("... ");
+ }
+ writer.WriteParameter(text);
+ }
+
+ private void WriteTypeReference(XPathNavigator reference, SyntaxWriter writer)
+ {
+ switch (reference.LocalName)
+ {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", string.Empty));
+ XPathNavigator navigator = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(navigator, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", string.Empty);
+ WriteNormalTypeReference(id, writer);
+ break;
+ case "pointerTo":
+ case "referenceTo":
+ case "template":
+ case "specialization":
+ // Not supported
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference(string api, SyntaxWriter writer) {
+ switch (api) {
+ case "T:System.Byte":
+ writer.WriteReferenceLink(api, "Byte");
+ return;
+
+ case "T:System.SByte":
+ writer.WriteReferenceLink(api, "SByte");
+ return;
+
+ case "T:System.Char":
+ writer.WriteReferenceLink(api, "Char");
+ return;
+
+ case "T:System.Int16":
+ writer.WriteReferenceLink(api, "Int16");
+ return;
+
+ case "T:System.Int32":
+ writer.WriteReferenceLink(api, "Int32");
+ return;
+
+ case "T:System.Int64":
+ writer.WriteReferenceLink(api, "Int64");
+ return;
+
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(api, "UInt16");
+ return;
+
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(api, "UInt32");
+ return;
+
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(api, "UInt64");
+ return;
+
+ case "T:System.Single":
+ writer.WriteReferenceLink(api, "Single");
+ return;
+
+ case "T:System.Double":
+ writer.WriteReferenceLink(api, "Double");
+ return;
+
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(api, "Decimal");
+ return;
+
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(api, "Boolean");
+ return;
+ }
+
+ // Remove 'T:'
+ string name = api.Substring(2);
+
+ // Strip System namespaces
+ if (name.StartsWith("System.")) {
+ int idx = name.LastIndexOf('.');
+ name = name.Substring(idx + 1);
+ }
+
+ writer.WriteReferenceLink(api, name);
+ }
+
+ private void WriteRecordSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadTypeName(reflection);
+
+ writer.WriteString(namespaceName);
+ writer.WriteString(".$create_");
+ writer.WriteString(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+ }
+
+ private void WriteRecordConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string namespaceName = ReadNamespaceName(reflection);
+
+ string typeName = ReadContainingTypeName(reflection);
+
+ writer.WriteString(namespaceName);
+ writer.WriteString(".$create_");
+ writer.WriteString(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteClassSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.RecordAttribute")) {
+ WriteRecordSyntax(reflection, writer);
+ return;
+ }
+
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+ writer.WriteLine();
+
+ writer.WriteIdentifier("Type");
+ writer.WriteString(".createClass(");
+ writer.WriteLine();
+ writer.WriteString("\t'");
+ writer.WriteString(typeName);
+ writer.WriteString("'");
+
+ bool hasBaseClass = false;
+
+ // Write the base class.
+ XPathNavigator reference = reflection.SelectSingleNode(apiBaseClassExpression);
+ if (!((reference == null) || ((bool)reference.Evaluate(typeIsObjectExpression)))) {
+ WriteIndentedNewLine(writer);
+ WriteTypeReference(reference, writer);
+ hasBaseClass = true;
+ }
+
+ // Write the interfaces.
+ XPathNodeIterator iterator = reflection.Select(apiImplementedInterfacesExpression);
+ if (iterator.Count != 0) {
+ if (!hasBaseClass) {
+ WriteIndentedNewLine(writer);
+ writer.WriteString("null");
+ }
+
+ WriteIndentedNewLine(writer);
+
+ while (iterator.MoveNext()) {
+ XPathNavigator interfaceRef = iterator.Current;
+ WriteTypeReference(interfaceRef, writer);
+ if (iterator.CurrentPosition < iterator.Count) {
+ WriteIndentedNewLine(writer);
+ }
+ }
+ }
+
+ writer.WriteString(");");
+ }
+
+ public override void WriteConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) {
+ return;
+ }
+
+ bool isRecord = (bool)reflection.Evaluate(typeIsRecordExpression);
+
+ if (isRecord) {
+ WriteRecordConstructorSyntax(reflection, writer);
+ return;
+ }
+
+ string typeName = ReadFullContainingTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteNormalMethodSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.AttachedPropertyAttribute")) {
+ WriteAttachedPropertySyntax(reflection, writer);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isGlobal = (bool)reflection.Evaluate(memberIsGlobalExpression);
+
+ if (isStatic && !isGlobal) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(memberName);
+ }
+
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteDelegateSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteKeyword("function");
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ }
+
+ public override void WriteEnumerationSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".createEnum('");
+ writer.WriteIdentifier(typeName);
+ writer.WriteString("', ");
+ writer.WriteString(HasAttribute(reflection, "System.FlagsAttribute") ? "true" : "false");
+ writer.WriteString(");");
+ }
+
+ public override void WriteEventSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (reflection.Select(apiParametersExpression).Count > 0) {
+ writer.WriteMessage("UnsupportedIndex_" + Language);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ writer.WriteKeyword("function");
+ writer.WriteString(" add_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+
+ writer.WriteLine();
+
+ writer.WriteKeyword("function");
+ writer.WriteString(" remove_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+ }
+
+ public override void WriteFieldSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ if (IsUnsupported(reflection, writer)) {
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ if (isStatic) {
+ string typeName = ReadFullContainingTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".");
+ }
+
+ writer.WriteIdentifier(memberName);
+ }
+
+ public override void WriteInterfaceSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ string typeName = ReadFullTypeName(reflection);
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ writer.WriteString("();");
+
+ writer.WriteLine();
+
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(".createInterface('");
+ writer.WriteIdentifier(typeName);
+ writer.WriteString("');");
+ }
+
+ public override void WriteAttachedEventSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ // Not supported
+ }
+
+ public override void WriteAttachedPropertySyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string typeName = ReadContainingTypeName(reflection);
+
+ string methodName = ReadMemberName(reflection);
+
+ string propertyName = String.Format("{0}.{1}", typeName, methodName.Substring(3));
+
+ if (methodName.StartsWith("Get", StringComparison.OrdinalIgnoreCase)) {
+ writer.WriteKeyword("var");
+ writer.WriteString(" value = obj['");
+ writer.WriteString(propertyName);
+ writer.WriteString("'];");
+ }
+ else if (methodName.StartsWith("Set", StringComparison.OrdinalIgnoreCase)) {
+ writer.WriteString("obj['");
+ writer.WriteString(propertyName);
+ writer.WriteString("'] = value;");
+ }
+ }
+
+ public override void WriteOperatorSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ }
+
+ public override void WriteCastSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ writer.WriteMessage("UnsupportedCast_" + Language);
+ }
+
+ public override void WriteNamespaceSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+
+ writer.WriteString("Type.createNamespace('");
+ writer.WriteIdentifier(name);
+ writer.WriteString("');");
+ }
+
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+
+ if (HasAttribute(reflection, "System.IntrinsicPropertyAttribute")) {
+ WriteFieldSyntax(reflection, writer);
+ return;
+ }
+
+ string memberName = ReadMemberName(reflection);
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+
+ bool isGetter = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool isSetter = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+
+ XPathNavigator reference = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (isGetter) {
+ if (isStatic) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+
+ writer.WriteString("get_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+
+ writer.WriteString("get_");
+ writer.WriteIdentifier(memberName);
+ }
+
+ WriteParameterList(reflection, writer);
+ writer.WriteString(";");
+ writer.WriteLine();
+ }
+
+ if (isSetter) {
+ if (isStatic) {
+ writer.WriteIdentifier(ReadFullContainingTypeName(reflection));
+ writer.WriteString(".");
+
+ writer.WriteString("set_");
+ writer.WriteIdentifier(memberName);
+ writer.WriteString(" = ");
+ writer.WriteKeyword("function");
+ }
+ else {
+ writer.WriteKeyword("function");
+ writer.WriteString(" ");
+
+ writer.WriteString("set_");
+ writer.WriteIdentifier(memberName);
+ }
+
+ writer.WriteString("(");
+ writer.WriteParameter("value");
+ writer.WriteString(");");
+ }
+ }
+
+ public override void WriteStructureSyntax(XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupported(reflection, writer)) return;
+ writer.WriteMessage("UnsupportedStructure_" + Language);
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxComponents.csproj b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxComponents.csproj
new file mode 100644
index 0000000..e6d8ad0
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxComponents.csproj
@@ -0,0 +1,105 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{CEAEC85B-973A-4414-8668-723EB65E5088}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>SyntaxComponents</RootNamespace>
+ <AssemblyName>SyntaxComponents</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AspNetSyntax.cs" />
+ <Compile Include="CPlusPlusDeclarationSyntax.cs" />
+ <Compile Include="CSharpDeclarationSyntax.cs" />
+ <Compile Include="FSharpDeclarationSyntax.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="JScriptDeclarationSyntax.cs" />
+ <Compile Include="JSharpDeclarationSyntax.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ScriptSharpDeclarationSyntax.cs" />
+ <Compile Include="SyntaxGenerators.cs" />
+ <Compile Include="VisualBasicDeclarationSyntax.cs" />
+ <Compile Include="VisualBasicUsageSyntax.cs" />
+ <Compile Include="XamlUsageSyntax.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BuildAssemblerLibrary\BuildAssemblerLibrary.csproj">
+ <Project>{399E78F8-4954-409E-991A-37DA9D0579CC}</Project>
+ <Name>BuildAssemblerLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\BuildComponents\BuildComponents.csproj">
+ <Project>{30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}</Project>
+ <Name>BuildComponents</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxGenerators.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxGenerators.cs
new file mode 100644
index 0000000..8f9f2c9
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/SyntaxGenerators.cs
@@ -0,0 +1,435 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public abstract class SyntaxGeneratorTemplate : SyntaxGenerator {
+
+ protected SyntaxGeneratorTemplate (XPathNavigator configuration) : base(configuration) {
+
+ string nameValue = configuration.GetAttribute("name", String.Empty);
+ language = nameValue;
+
+ }
+
+ // A maximum width setting
+
+ protected static int maxPosition = 60;
+
+ // The language itentifier
+
+
+ private string language;
+
+ public string Language {
+ get {
+ return (language);
+ }
+ protected set {
+ language = value;
+ }
+ }
+
+ // Where data is stored
+
+ // api data
+ protected static XPathExpression apiNameExpression = XPathExpression.Compile("string(apidata/@name)");
+ protected static XPathExpression apiGroupExpression = XPathExpression.Compile("string(apidata/@group)");
+ protected static XPathExpression apiSubgroupExpression = XPathExpression.Compile("string(apidata/@subgroup)");
+ protected static XPathExpression apiSubsubgroupExpression = XPathExpression.Compile("string(apidata/@subsubgroup)");
+
+ // support testing
+ protected static XPathExpression apiIsUnsafeExpression = XPathExpression.Compile("boolean(parameters/parameter//pointerTo or returns//pointerTo)");
+ protected static XPathExpression apiIsGenericExpression = XPathExpression.Compile("boolean(templates/template)");
+ protected static XPathExpression apiIsExtensionMethod = XPathExpression.Compile("boolean(attributes/attribute/type[@api='T:System.Runtime.CompilerServices.ExtensionAttribute'])");
+
+ // visibility attribute
+ protected static XPathExpression apiVisibilityExpression = XPathExpression.Compile("string((typedata|memberdata)/@visibility)");
+ protected static XPathExpression apiIsFamilyMemberExpression = XPathExpression.Compile("boolean(contains(memberdata/@visibility,'family'))");
+
+ // type data
+ protected static XPathExpression apiVisibilityOfTypeExpression = XPathExpression.Compile("string(typedata/@visibility)");
+ protected static XPathExpression apiIsAbstractTypeExpression = XPathExpression.Compile("boolean(typedata[@abstract='true'])");
+ protected static XPathExpression apiIsSealedTypeExpression = XPathExpression.Compile("boolean(typedata[@sealed='true'])");
+ protected static XPathExpression apiIsSerializableTypeExpression = XPathExpression.Compile("boolean(typedata[@serializable='true'])");
+
+ // class data
+ protected static XPathExpression apiBaseClassExpression = XPathExpression.Compile("family/ancestors/*[1]");
+ protected static XPathExpression apiAncestorsExpression = XPathExpression.Compile("family/ancestors/*");
+
+ // enumeration data
+
+ // various subheadings
+ protected static XPathExpression apiAttributesExpression = XPathExpression.Compile("attributes/attribute");
+ protected static XPathExpression apiTemplatesExpression = XPathExpression.Compile("templates/template");
+ protected static XPathExpression apiImplementedInterfacesExpression = XPathExpression.Compile("implements/type");
+ protected static XPathExpression apiParametersExpression = XPathExpression.Compile("parameters/parameter");
+ protected static XPathExpression apiReturnTypeExpression = XPathExpression.Compile("returns/*[1]");
+
+ // member data
+ protected static XPathExpression apiVisibilityOfMemberExpression = XPathExpression.Compile("string(memberdata/@visibility)");
+ protected static XPathExpression apiIsStaticExpression = XPathExpression.Compile("boolean(memberdata[@static='true'])");
+ protected static XPathExpression apiIsSpecialExpression = XPathExpression.Compile("boolean(memberdata[@special='true'])");
+ protected static XPathExpression apiIsDefaultMemberExpression = XPathExpression.Compile("boolean(memberdata[@default='true'])");
+
+ // field data
+ protected static XPathExpression apiIsLiteralFieldExpression = XPathExpression.Compile("boolean(fielddata[@literal='true'])");
+ protected static XPathExpression apiIsInitOnlyFieldExpression = XPathExpression.Compile("boolean(fielddata[@initonly='true'])");
+ protected static XPathExpression apiIsVolatileFieldExpression = XPathExpression.Compile("boolean(fielddata[@volatile='true'])");
+ protected static XPathExpression apiIsSerializedFieldExpression = XPathExpression.Compile("boolean(fielddata[@serialized='true'])");
+
+ // procedure data
+ protected static XPathExpression apiIsAbstractProcedureExpression = XPathExpression.Compile("boolean(proceduredata[@abstract='true'])");
+ protected static XPathExpression apiIsVirtualExpression = XPathExpression.Compile("boolean(proceduredata[@virtual='true'])");
+ protected static XPathExpression apiIsFinalExpression = XPathExpression.Compile("boolean(proceduredata[@final='true'])");
+ protected static XPathExpression apiOverridesMemberExpression = XPathExpression.Compile("string(proceduredata/@overrides/member)");
+ protected static XPathExpression apiIsExplicitImplementationExpression = XPathExpression.Compile("boolean(memberdata/@visibility='private' and proceduredata/@virtual='true' and boolean(implements/member))");
+ protected static XPathExpression apiImplementedMembersExpression = XPathExpression.Compile("implements/member");
+ protected static XPathExpression apiIsOverrideExpression = XPathExpression.Compile("boolean(overrides/member)");
+
+ // property data
+ protected static XPathExpression apiIsReadPropertyExpression = XPathExpression.Compile("boolean(propertydata/@get='true')");
+ protected static XPathExpression apiIsWritePropertyExpression = XPathExpression.Compile("boolean(propertydata/@set='true')");
+ protected static XPathExpression apiGetVisibilityExpression = XPathExpression.Compile("string(propertydata/@get-visibility)");
+ protected static XPathExpression apiSetVisibilityExpression = XPathExpression.Compile("string(propertydata/@set-visibility)");
+
+ // event data
+ protected static XPathExpression apiHandlerOfEventExpression = XPathExpression.Compile("eventhandler/*[1]");
+ protected static XPathExpression apiEventArgsExpression = XPathExpression.Compile("eventargs/*[1]");
+
+ // parameter data
+ //protected static XPathExpression params_expression = XPathExpression.Compile("boolean(@params='true')");
+ protected static XPathExpression parameterNameExpression = XPathExpression.Compile("string(@name)");
+ protected static XPathExpression parameterTypeExpression = XPathExpression.Compile("*[1]");
+ protected static XPathExpression parameterIsInExpression = XPathExpression.Compile("boolean(@in='true')");
+ protected static XPathExpression parameterIsOutExpression = XPathExpression.Compile("boolean(@out='true')");
+ protected static XPathExpression parameterIsRefExpression = XPathExpression.Compile("boolean(referenceTo)");
+ protected static XPathExpression parameterIsParamArrayExpression = XPathExpression.Compile("boolean(@params='true')");
+
+ // container data
+ protected static XPathExpression apiContainingTypeExpression = XPathExpression.Compile("containers/type");
+ protected static XPathExpression apiContainingTypeNameExpression = XPathExpression.Compile("string(containers/type/apidata/@name)");
+ protected static XPathExpression apiContainingTypeSubgroupExpression = XPathExpression.Compile("string(containers/type/apidata/@subgroup)");
+ protected static XPathExpression apiContainingAssemblyExpression = XPathExpression.Compile("string(containers/library/@assembly)");
+ protected static XPathExpression apiContainingNamespaceIdExpression = XPathExpression.Compile("string(containers/namespace/@api)");
+ protected static XPathExpression apiContainingNamespaceNameExpression = XPathExpression.Compile("string(containers/namespace/apidata/@name)");
+ // protected static XPathExpression containing_type_templates_expression = XPathExpression.Compile("containers/container[@type]/templates");
+
+ // referenced type data
+ protected static XPathExpression typeExpression = XPathExpression.Compile("*[1]");
+ protected static XPathExpression typeIdExpression = XPathExpression.Compile("@api");
+ protected static XPathExpression typeModifiersExpression = XPathExpression.Compile("optionalModifier|requiredModifier|specialization");
+ protected static XPathExpression typeOuterTypeExpression = XPathExpression.Compile("type");
+ protected static XPathExpression typeIsObjectExpression = XPathExpression.Compile("boolean(local-name()='type' and @api='T:System.Object')");
+ protected static XPathExpression valueExpression = XPathExpression.Compile("*[2]");
+ protected static XPathExpression nameExpression = XPathExpression.Compile("string(@name)");
+ protected static XPathExpression specializationArgumentsExpression = XPathExpression.Compile("*");
+
+ // referenced member data
+ protected static XPathExpression memberDeclaringTypeExpression = XPathExpression.Compile("*[1]");
+
+ // attribute data
+ protected static XPathExpression attributeTypeExpression = XPathExpression.Compile("*[1]");
+ protected static XPathExpression attributeArgumentsExpression = XPathExpression.Compile("argument");
+ protected static XPathExpression attributeAssignmentsExpression = XPathExpression.Compile("assignment");
+ protected static XPathExpression assignmentNameExpression = XPathExpression.Compile("string(@name)");
+
+ // template data
+ protected static XPathExpression templateNameExpression = XPathExpression.Compile("string(@name)");
+ protected static XPathExpression templateIsConstrainedExpression = XPathExpression.Compile("boolean(constrained)");
+ protected static XPathExpression templateIsValueTypeExpression = XPathExpression.Compile("boolean(constrained/@value='true')");
+ protected static XPathExpression templateIsReferenceTypeExpression = XPathExpression.Compile("boolean(constrained/@ref='true')");
+ protected static XPathExpression templateIsConstructableExpression = XPathExpression.Compile("boolean(constrained/@ctor='true')");
+ protected static XPathExpression templateConstraintsExpression = XPathExpression.Compile("constrained/type | constrained/implements/type | constrained/implements/template");
+ protected static XPathExpression templateIsCovariantExpression = XPathExpression.Compile("boolean(variance/@covariant='true')");
+ protected static XPathExpression templateIsContravariantExpression = XPathExpression.Compile("boolean(variance/@contravariant='true')");
+
+ protected static XPathExpression attachedEventAdderExpression = XPathExpression.Compile("string(attachedeventdata/adder/member/@api)");
+ protected static XPathExpression attachedEventRemoverExpression = XPathExpression.Compile("string(attachedeventdata/remover/member/@api)");
+
+ protected static XPathExpression attachedPropertyGetterExpression = XPathExpression.Compile("string(attachedpropertydata/getter/member/@api)");
+ protected static XPathExpression attachedPropertySetterExpression = XPathExpression.Compile("string(attachedpropertydata/setter/member/@api)");
+
+ // Methods to write syntax for different kinds of APIs
+
+ public override void WriteSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ writer.WriteStartBlock(Language);
+
+ string group = (string) reflection.Evaluate(apiGroupExpression);
+
+ switch (group) {
+ case "namespace":
+ WriteNamespaceSyntax(reflection, writer);
+ break;
+ case "type":
+ WriteTypeSyntax(reflection, writer);
+ break;
+ case "member":
+ WriteMemberSyntax(reflection, writer);
+ break;
+ }
+
+ writer.WriteEndBlock();
+
+ }
+
+ public virtual void WriteTypeSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string subgroup = (string) reflection.Evaluate(apiSubgroupExpression);
+
+ switch (subgroup) {
+ case "class":
+ WriteClassSyntax(reflection, writer);
+ break;
+ case "structure":
+ WriteStructureSyntax(reflection, writer);
+ break;
+ case "interface":
+ WriteInterfaceSyntax(reflection, writer);
+ break;
+ case "delegate":
+ WriteDelegateSyntax(reflection, writer);
+ break;
+ case "enumeration":
+ WriteEnumerationSyntax(reflection, writer);
+ break;
+ }
+
+ }
+
+ public virtual void WriteMemberSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string subgroup = (string) reflection.Evaluate(apiSubgroupExpression);
+ string subsubgroup = (string)reflection.Evaluate(apiSubsubgroupExpression);
+
+ switch (subgroup) {
+ case "constructor":
+ WriteConstructorSyntax(reflection, writer);
+ break;
+ case "method":
+ WriteMethodSyntax(reflection, writer);
+ break;
+ case "property":
+ if (subsubgroup == "attachedProperty")
+ WriteAttachedPropertySyntax(reflection, writer);
+ else
+ WritePropertySyntax(reflection, writer);
+ break;
+ case "event":
+ if (subsubgroup == "attachedEvent")
+ WriteAttachedEventSyntax(reflection, writer);
+ else
+ WriteEventSyntax(reflection, writer);
+ break;
+ case "field":
+ WriteFieldSyntax(reflection, writer);
+ break;
+ }
+
+ }
+
+ public abstract void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public virtual void WriteMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isSpecialName = (bool)reflection.Evaluate(apiIsSpecialExpression);
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ if (isSpecialName) {
+ string subsubgroup = (string)reflection.Evaluate(apiSubsubgroupExpression);
+ if (subsubgroup == "operator") {
+ if ((name == "Implicit") || (name == "Explicit")) {
+ WriteCastSyntax(reflection, writer);
+ } else {
+ WriteOperatorSyntax(reflection, writer);
+ }
+ }
+ } else {
+ WriteNormalMethodSyntax(reflection, writer);
+ }
+ }
+
+ public abstract void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public abstract void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer);
+
+ public virtual void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) { }
+
+ public virtual void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) { }
+
+ public virtual void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) { }
+
+ public virtual void WriteAttachedPropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string getterId = (string)reflection.Evaluate(attachedPropertyGetterExpression);
+ string setterId = (string)reflection.Evaluate(attachedPropertySetterExpression);
+ if (!string.IsNullOrEmpty(getterId))
+ {
+ writer.WriteString("See ");
+ writer.WriteReferenceLink(getterId);
+ }
+ if (!string.IsNullOrEmpty(setterId))
+ {
+ if (!string.IsNullOrEmpty(getterId))
+ writer.WriteString(", ");
+ writer.WriteReferenceLink(setterId);
+ }
+ }
+
+ public virtual void WriteAttachedEventSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string adderId = (string)reflection.Evaluate(attachedEventAdderExpression);
+ string removerId = (string)reflection.Evaluate(attachedEventRemoverExpression);
+ if (!(string.IsNullOrEmpty(adderId) && string.IsNullOrEmpty(removerId)))
+ {
+ writer.WriteString("See ");
+ writer.WriteReferenceLink(adderId);
+ writer.WriteString(", ");
+ writer.WriteReferenceLink(removerId);
+ }
+ }
+
+ protected virtual bool IsUnsupportedUnsafe(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ bool isUnsafe = (bool) reflection.Evaluate(apiIsUnsafeExpression);
+
+ if (isUnsafe) {
+ writer.WriteMessage("UnsupportedUnsafe_" + Language);
+ }
+
+ return(isUnsafe);
+ }
+
+ protected virtual bool IsUnsupportedGeneric (XPathNavigator reflection, SyntaxWriter writer) {
+
+ bool isGeneric = (bool) reflection.Evaluate(apiIsGenericExpression);
+
+ if (isGeneric) {
+ writer.WriteMessage("UnsupportedGeneric_" + Language);
+ }
+
+ return(isGeneric);
+
+ }
+
+ protected virtual bool IsUnsupportedExplicit (XPathNavigator reflection, SyntaxWriter writer) {
+
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+
+ if (isExplicit) {
+ writer.WriteMessage("UnsupportedExplicit_" + Language);
+ }
+
+ return(isExplicit);
+
+ }
+
+ }
+
+ public abstract class DeclarationSyntaxGeneratorTemplate : SyntaxGeneratorTemplate {
+
+ protected DeclarationSyntaxGeneratorTemplate (XPathNavigator configuration) : base(configuration) { }
+
+ // Methods to implement
+
+ protected abstract void WriteVisibility (XPathNavigator reflection, SyntaxWriter writer);
+
+ // Utility methods
+
+ protected static string[] SeperateTypes (string typelist) {
+ List<string> types = new List<string>();
+
+ int start = 0;
+ int specializationCount = 0;
+ for (int index=0; index<typelist.Length; index++) {
+ switch (typelist[index]) {
+ case '{':
+ specializationCount++;
+ break;
+ case '}':
+ specializationCount--;
+ break;
+ case ',':
+ if (specializationCount == 0) {
+ types.Add( "T:" + typelist.Substring(start, index-start) );
+ start = index + 1;
+ }
+ break;
+ }
+ }
+ types.Add( "T:" + typelist.Substring(start) );
+ return(types.ToArray());
+ }
+
+ protected static string GetTemplateParameterName (string reference, XPathNavigator reflection) {
+
+ string group = (string) reflection.Evaluate(apiGroupExpression);
+
+ XPathNavigator template = null;
+ if (reference.StartsWith("T:`")) {
+ if (reference[3]=='`') {
+
+ // a method template parameter
+
+ int position = Convert.ToInt32( reference.Substring(4) ) + 1;
+
+ if (group == "member") {
+ // we are in a method, so presumably it is one of that method's template parameters
+ template = reflection.SelectSingleNode( String.Format("templates/template[{0}]", position) );
+ }
+
+ } else {
+
+ // a type template parameter
+
+ int position = Convert.ToInt32( reference.Substring(3) ) + 1;
+
+ if (group == "type") {
+ // we are in a type, so look there for the parameter
+ template = reflection.SelectSingleNode( String.Format("templates/template[{0}]", position) );
+ }
+
+ if (template == null) {
+ // either we weren't in a type, or it didn't have the template
+ // so now look at the templates of the containing type
+ template = reflection.SelectSingleNode( String.Format("containers/container[@type]/templates/template[{0}]", position) );
+ }
+
+
+
+ }
+ }
+
+ if (template != null) {
+ return(template.GetAttribute("name", String.Empty));
+ } else {
+ Console.WriteLine("UNRESOLVED TEMPLATE PARAMETER NAME");
+ return("T");
+ }
+
+ }
+
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicDeclarationSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicDeclarationSyntax.cs
new file mode 100644
index 0000000..e90ab1a
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicDeclarationSyntax.cs
@@ -0,0 +1,961 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class VisualBasicDeclarationSyntaxGenerator : SyntaxGeneratorTemplate {
+
+ public VisualBasicDeclarationSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "VisualBasic";
+ }
+
+ // namespace: done
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ writer.WriteKeyword("Namespace");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ // class: done
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool) reflection.Evaluate(apiIsSealedTypeExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isAbstract) {
+ if (isSealed) {
+ // static -- VB doesn't really handle this case
+ writer.WriteKeyword("NotInheritable");
+ writer.WriteString(" ");
+ } else {
+ writer.WriteKeyword("MustInherit");
+ writer.WriteString(" ");
+ }
+ } else if (isSealed) {
+ writer.WriteKeyword("NotInheritable");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Class");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ WriteBaseClass(reflection, writer);
+ WriteImplementedInterfaces(reflection, writer);
+ }
+
+ // structure: add base type
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("Structure");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ WriteImplementedInterfaces(reflection, writer);
+ }
+
+ // interface: done
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("Interface");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer, true); // Need to write variance info for interfaces and delegates
+ WriteImplementedInterfaces(reflection, writer);
+ }
+
+ // delegate: done
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("Delegate");
+ writer.WriteString(" ");
+ if (type == null) {
+ writer.WriteKeyword("Sub");
+ } else {
+ writer.WriteKeyword("Function");
+ }
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer, true); // Need to write variance info for interfaces and delegates
+ WriteParameters(reflection, writer);
+ if (type != null) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+ }
+
+ }
+
+ // enumeration: done
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isSerializable = (bool) reflection.Evaluate(apiIsSerializableTypeExpression);
+
+ if (isSerializable) WriteAttribute("T:System.SerializableAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("Enumeration");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ // constructor: done
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+
+ WriteAttributes(reflection, writer);
+ if (isStatic) {
+ writer.WriteKeyword("Shared");
+ } else {
+ WriteVisibility(reflection, writer);
+ }
+ writer.WriteString(" ");
+ writer.WriteKeyword("Sub");
+ writer.WriteString(" ");
+ writer.WriteIdentifier("New");
+ WriteParameters(reflection, writer);
+
+ }
+
+
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+ bool isExplicit = (bool) reflection.Evaluate(apiIsExplicitImplementationExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ if (type == null) {
+ writer.WriteKeyword("Sub");
+ } else {
+ writer.WriteKeyword("Function");
+ }
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteGenericTemplates(reflection, writer);
+ WriteParameters(reflection, writer);
+ if (type != null) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+ }
+ if (isExplicit) {
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ } else {
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Implements");
+ writer.WriteString(" ");
+ XPathNodeIterator implementations = reflection.Select(apiImplementedMembersExpression);
+ while (implementations.MoveNext()) {
+ XPathNavigator implementation = implementations.Current;
+ XPathNavigator contract = implementation.SelectSingleNode(attributeTypeExpression);
+ // string id = implementation.GetAttribute("api", String.Empty);
+ if (implementations.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ WriteMemberReference(implementation, writer);
+ }
+ }
+
+ }
+
+ public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ string identifier;
+ switch (name) {
+ // unary math operators
+ case "UnaryPlus":
+ identifier = "+";
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ break;
+ case "Increment":
+ identifier = "++";
+ break;
+ case "Decrement":
+ identifier = "--";
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "Not";
+ break;
+ case "True":
+ identifier = "IsTrue";
+ break;
+ case "False":
+ identifier = "IsFalse";
+ break;
+ // binary comparison operators
+ case "Equality":
+ identifier = "=";
+ break;
+ case "Inequality":
+ identifier = "<>";
+ break;
+ case "LessThan":
+ identifier = "<";
+ break;
+ case "GreaterThan":
+ identifier = ">";
+ break;
+ case "LessThanOrEqual":
+ identifier = "<=";
+ break;
+ case "GreaterThanOrEqual":
+ identifier = ">=";
+ break;
+ // binary math operators
+ case "Addition":
+ identifier = "+";
+ break;
+ case "Subtraction":
+ identifier = "-";
+ break;
+ case "Multiply":
+ identifier = "*";
+ break;
+ case "Division":
+ identifier = "/";
+ break;
+ case "Exponent":
+ identifier = "^";
+ break;
+ case "Modulus":
+ identifier = "Mod";
+ break;
+ case "IntegerDivision":
+ identifier = @"\";
+ break;
+ // binary logical operators
+ case "BitwiseAnd":
+ identifier = "And";
+ break;
+ case "BitwiseOr":
+ identifier = "Or";
+ break;
+ case "ExclusiveOr":
+ identifier = "Xor";
+ break;
+ // bit-array operators
+ case "OnesComplement":
+ identifier = "~";
+ break;
+ case "LeftShift":
+ identifier = "<<";
+ break;
+ case "RightShift":
+ identifier = ">>";
+ break;
+ // concatenation
+ case "Concatenate":
+ identifier = "&";
+ break;
+ // casting operators
+ case "Implicit":
+ case "Explicit":
+ identifier = "CType";
+ break;
+ // didn't recognize an operator
+ default:
+ identifier = null;
+ break;
+ }
+ if (identifier == null) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ return;
+ }
+ WriteProcedureModifiers(reflection, writer);
+ if (name == "Implicit") {
+ writer.WriteKeyword("Widening");
+ writer.WriteString(" ");
+ } else if (name == "Explicit") {
+ writer.WriteKeyword("Narrowing");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Operator");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(identifier);
+ WriteParameters(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+ }
+
+ public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ WriteOperatorSyntax(reflection, writer);
+ }
+
+ public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool getter = (bool) reflection.Evaluate(apiIsReadPropertyExpression);
+ bool setter = (bool) reflection.Evaluate(apiIsWritePropertyExpression);
+ bool isDefault = (bool)reflection.Evaluate(apiIsDefaultMemberExpression);
+ bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ if (getter && !setter) {
+ writer.WriteKeyword("ReadOnly");
+ writer.WriteString(" ");
+ } else if (setter && !getter) {
+ writer.WriteKeyword("WriteOnly");
+ writer.WriteString(" ");
+ }
+ if (isDefault) {
+ writer.WriteKeyword("Default");
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Property");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ WriteParameters(reflection, writer);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+
+ if (isExplicit) {
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ } else {
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Implements");
+ writer.WriteString(" ");
+ XPathNodeIterator implementations = reflection.Select(apiImplementedMembersExpression);
+ while (implementations.MoveNext()) {
+ XPathNavigator implementation = implementations.Current;
+ XPathNavigator contract = implementation.SelectSingleNode(memberDeclaringTypeExpression);
+ //string id = implementation.GetAttribute("api", String.Empty);
+ if (implementations.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ WriteMemberReference(implementation, writer);
+ //writer.WriteReferenceLink(id);
+ }
+ }
+
+ if (getter)
+ {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (!String.IsNullOrEmpty(getVisibility))
+ {
+ WriteVisibility(getVisibility, writer);
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Get");
+ }
+ if (setter)
+ {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (!String.IsNullOrEmpty(setVisibility))
+ {
+ WriteVisibility(setVisibility, writer);
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Set");
+ }
+ }
+
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ WriteAttributes(reflection, writer);
+ WriteProcedureModifiers(reflection, writer);
+ writer.WriteString("Event");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(handler, writer);
+ WriteExplicitImplementations(reflection, writer);
+ }
+
+ private void WriteExplicitImplementations (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ if (isExplicit) {
+ if (writer.Position > maxPosition) {
+ writer.WriteLine();
+ writer.WriteString("\t");
+ } else {
+ writer.WriteString(" ");
+ }
+ writer.WriteKeyword("Implements");
+ writer.WriteString(" ");
+ XPathNodeIterator implementations = reflection.Select(apiImplementedMembersExpression);
+ while (implementations.MoveNext()) {
+ XPathNavigator implementation = implementations.Current;
+ XPathNavigator contract = implementation.SelectSingleNode(memberDeclaringTypeExpression);
+ //string id = implementation.GetAttribute("api", String.Empty);
+ if (implementations.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(contract, writer);
+ writer.WriteString(".");
+ WriteMemberReference(implementation, writer);
+ //writer.WriteReferenceLink(id);
+ }
+ }
+ }
+
+ private void WriteProcedureModifiers (XPathNavigator reflection, SyntaxWriter writer) {
+
+ // interface members don't get modified
+ string typeSubgroup = (string) reflection.Evaluate(apiContainingTypeSubgroupExpression);
+ if (typeSubgroup == "interface") return;
+
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isVirtual = (bool) reflection.Evaluate(apiIsVirtualExpression);
+ bool isAbstract = (bool) reflection.Evaluate(apiIsAbstractProcedureExpression);
+ bool isFinal = (bool) reflection.Evaluate(apiIsFinalExpression);
+ bool isOverride = (bool) reflection.Evaluate(apiIsOverrideExpression);
+
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isStatic) {
+ writer.WriteKeyword("Shared");
+ writer.WriteString(" ");
+ } else {
+ if (isVirtual) {
+ if (isAbstract) {
+ writer.WriteKeyword("MustOverride");
+ writer.WriteString(" ");
+ } else if (isOverride) {
+ writer.WriteKeyword("Overrides");
+ writer.WriteString(" ");
+ if (isFinal) {
+ writer.WriteKeyword("NotOverridable");
+ writer.WriteString(" ");
+ }
+ } else {
+ if (!isFinal) {
+ writer.WriteKeyword("Overridable");
+ writer.WriteString(" ");
+ }
+ }
+ }
+ }
+
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool) reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool) reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool) reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isSerialized = (bool) reflection.Evaluate(apiIsSerializedFieldExpression);
+ XPathNavigator type = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (!isSerialized) WriteAttribute("T:System.NonSerializedAttribute", writer);
+ WriteAttributes(reflection, writer);
+ WriteVisibility(reflection, writer);
+ writer.WriteString(" ");
+ if (isStatic) {
+ if (isLiteral) {
+ writer.WriteKeyword("Const");
+ } else {
+ writer.WriteKeyword("Shared");
+ }
+ writer.WriteString(" ");
+ }
+ if (isInitOnly) {
+ writer.WriteKeyword("ReadOnly");
+ writer.WriteString(" ");
+ }
+ writer.WriteIdentifier(name);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+
+ }
+
+ // Visibility
+ private void WriteVisibility(XPathNavigator reflection, SyntaxWriter writer) {
+
+ string visibility = (string)reflection.Evaluate(apiVisibilityExpression);
+ WriteVisibility(visibility, writer);
+ }
+
+ private void WriteVisibility (string visibility, SyntaxWriter writer) {
+
+ switch (visibility) {
+ case "public":
+ writer.WriteKeyword("Public");
+ break;
+ case "family":
+ writer.WriteKeyword("Protected");
+ break;
+ case "family or assembly":
+ writer.WriteKeyword("Protected Friend");
+ break;
+ case "family and assembly":
+ writer.WriteKeyword("Friend"); // not right, but same outside assembly
+ break;
+ case "assembly":
+ writer.WriteKeyword("Friend");
+ break;
+ case "private":
+ writer.WriteKeyword("Private");
+ break;
+ }
+
+ }
+
+ // Attributes
+
+ private void WriteAttribute (string reference, SyntaxWriter writer) {
+ WriteAttribute(reference, true, writer);
+ }
+
+ private void WriteAttribute (string reference, bool newLine, SyntaxWriter writer) {
+ writer.WriteString("<");
+ writer.WriteReferenceLink(reference);
+ writer.WriteString(">");
+ if (newLine) {
+ writer.WriteString(" _");
+ writer.WriteLine();
+ }
+ }
+
+ private void WriteAttributes (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator attributes = (XPathNodeIterator) reflection.Evaluate(apiAttributesExpression);
+
+ foreach (XPathNavigator attribute in attributes) {
+
+ XPathNavigator type = attribute.SelectSingleNode(attributeTypeExpression);
+ XPathNodeIterator arguments = (XPathNodeIterator) attribute.Select(attributeArgumentsExpression);
+ XPathNodeIterator assignments = (XPathNodeIterator) attribute.Select(attributeAssignmentsExpression);
+
+ writer.WriteString("<");
+ WriteTypeReference(type, writer);
+
+ if ((arguments.Count > 0) || (assignments.Count > 0)) {
+ writer.WriteString("(");
+ while (arguments.MoveNext()) {
+ XPathNavigator argument = arguments.Current;
+ if (arguments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteString(" _");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ WriteValue(argument, writer);
+ }
+ if ((arguments.Count > 0) && (assignments.Count > 0)) writer.WriteString(", ");
+ while (assignments.MoveNext()) {
+ XPathNavigator assignment = assignments.Current;
+ if (assignments.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteString(" _");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ writer.WriteString((string) assignment.Evaluate(assignmentNameExpression));
+ writer.WriteString(" := ");
+ WriteValue(assignment, writer);
+
+ }
+ writer.WriteString(")");
+ }
+
+ writer.WriteString("> ");
+ writer.WriteString("_");
+ writer.WriteLine();
+ }
+
+ }
+
+ private void WriteValue (XPathNavigator parent, SyntaxWriter writer) {
+
+ XPathNavigator type = parent.SelectSingleNode(attributeTypeExpression);
+ XPathNavigator value = parent.SelectSingleNode(valueExpression);
+ if (value == null) Console.WriteLine("null value");
+
+ switch (value.LocalName) {
+ case "nullValue":
+ writer.WriteKeyword("Nothing");
+ break;
+ case "typeValue":
+ writer.WriteKeyword("GetType");
+ writer.WriteString("(");
+ WriteTypeReference(value.SelectSingleNode(typeExpression), writer);
+ writer.WriteString(")");
+ break;
+ case "enumValue":
+ XPathNodeIterator fields = value.SelectChildren(XPathNodeType.Element);
+ while (fields.MoveNext()) {
+ string name = fields.Current.GetAttribute("name", String.Empty);
+ if (fields.CurrentPosition > 1) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("Or");
+ writer.WriteString(" ");
+ }
+ WriteTypeReference(type, writer);
+ writer.WriteString(".");
+ writer.WriteString(name);
+ }
+ break;
+ case "value":
+ string text = value.Value;
+ string typeId = type.GetAttribute("api", String.Empty);
+ switch (typeId) {
+ case "T:System.String":
+ writer.WriteString("\"");
+ writer.WriteString(text);
+ writer.WriteString("\"");
+ break;
+ case "T:System.Boolean":
+ bool bool_value = Convert.ToBoolean(text);
+ if (bool_value) {
+ writer.WriteKeyword("True");
+ } else {
+ writer.WriteKeyword("False");
+ }
+ break;
+ case "T:System.Char":
+ writer.WriteString("\"");
+ writer.WriteString(text);
+ writer.WriteString("\"C");
+ break;
+ }
+ break;
+ }
+ }
+
+
+ // Interfaces
+
+ private void WriteBaseClass (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNavigator baseClass = reflection.SelectSingleNode(apiBaseClassExpression);
+
+ if ((baseClass != null) && !((bool) baseClass.Evaluate(typeIsObjectExpression))) {
+ writer.WriteString(" _");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ writer.WriteKeyword("Inherits");
+ writer.WriteString(" ");
+ WriteTypeReference(baseClass, writer);
+ }
+
+ }
+
+ private void WriteImplementedInterfaces (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator implements = reflection.Select(apiImplementedInterfacesExpression);
+
+ if (implements.Count == 0) return;
+
+ writer.WriteString(" _");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ string subgroup = (string)reflection.Evaluate(apiSubgroupExpression);
+ if (subgroup == "interface")
+ writer.WriteKeyword("Inherits");
+ else
+ writer.WriteKeyword("Implements");
+ writer.WriteString(" ");
+ while (implements.MoveNext()) {
+ XPathNavigator implement = implements.Current;
+ if (implements.CurrentPosition > 1) {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition) {
+ writer.WriteString(" _");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ WriteTypeReference(implement, writer);
+ }
+
+ }
+
+ // Generics
+
+ private void WriteGenericTemplates(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteGenericTemplates(reflection, writer, false);
+ }
+
+ private void WriteGenericTemplates (XPathNavigator reflection, SyntaxWriter writer, bool writeVariance) {
+
+ XPathNodeIterator templates = reflection.Select(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+ writer.WriteString("(");
+ writer.WriteKeyword("Of");
+ writer.WriteString(" ");
+ while (templates.MoveNext()) {
+ XPathNavigator template = templates.Current;
+ if (templates.CurrentPosition > 1) writer.WriteString(", ");
+
+ if (writeVariance)
+ {
+ bool contravariant = (bool)template.Evaluate(templateIsContravariantExpression);
+ bool covariant = (bool)template.Evaluate(templateIsCovariantExpression);
+
+ if (contravariant)
+ {
+ writer.WriteKeyword("In");
+ writer.WriteString(" ");
+ }
+ if (covariant)
+ {
+ writer.WriteKeyword("Out");
+ writer.WriteString(" ");
+ }
+ }
+
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+
+ // write out constraints
+
+ bool constrained = (bool) template.Evaluate(templateIsConstrainedExpression);
+ if (constrained) {
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+
+ bool value = (bool) template.Evaluate(templateIsValueTypeExpression);
+ bool reference = (bool) template.Evaluate(templateIsReferenceTypeExpression);
+ bool constructor = (bool) template.Evaluate(templateIsConstructableExpression);
+ XPathNodeIterator constraints = template.Select(templateConstraintsExpression);
+
+ int count = constraints.Count;
+ if (value) count++;
+ if (reference) count++;
+ if (constructor) count++;
+
+ if (count > 1) writer.WriteString("{");
+
+ int index = 0;
+ if (value) {
+ if (index > 0) writer.WriteString(", ");
+ writer.WriteKeyword("Structure");
+ index++;
+ }
+ if (reference) {
+ if (index > 0) writer.WriteString(", ");
+ writer.WriteKeyword("Class");
+ index++;
+ }
+ if (constructor) {
+ if (index > 0) writer.WriteString(", ");
+ writer.WriteKeyword("New");
+ index++;
+ }
+ foreach (XPathNavigator constraint in constraints) {
+ if (index > 0) writer.WriteString(", ");
+ WriteTypeReference(constraint, writer);
+ index++;
+ }
+
+ if (count > 1) writer.WriteString("}");
+
+ }
+
+ }
+ writer.WriteString(")");
+ }
+
+ // Parameters
+
+ private void WriteParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+ if (parameters.Count == 0) return;
+
+ writer.WriteString(" ( _");
+ writer.WriteLine();
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ string name = (string) parameter.Evaluate(parameterNameExpression);
+ bool isIn = (bool) parameter.Evaluate(parameterIsInExpression);
+ bool isOut = (bool) parameter.Evaluate(parameterIsOutExpression);
+ bool isParamArray = (bool) parameter.Evaluate(parameterIsParamArrayExpression);
+ bool isByRef = (bool) parameter.Evaluate(parameterIsRefExpression);
+
+ writer.WriteString("\t");
+ if (isOut) {
+ WriteAttribute("T:System.Runtime.InteropServices.OutAttribute", false, writer);
+ writer.WriteString(" ");
+ }
+ if (isParamArray) {
+ writer.WriteKeyword("ParamArray");
+ writer.WriteString(" ");
+ }
+ if (isByRef) {
+ writer.WriteKeyword("ByRef");
+ writer.WriteString(" ");
+ }
+ writer.WriteParameter(name);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ WriteTypeReference(type, writer);
+ if (parameters.CurrentPosition < parameters.Count) writer.WriteString(",");
+ writer.WriteString(" _");
+ writer.WriteLine();
+ }
+ writer.WriteString(")");
+
+ }
+
+ // References
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ int rank = Convert.ToInt32( reference.GetAttribute("rank",String.Empty) );
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("(");
+ for (int i=1; i<rank; i++) { writer.WriteString(","); }
+ writer.WriteString(")");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("(");
+ writer.WriteKeyword("Of");
+ writer.WriteString(" ");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(")");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string reference, SyntaxWriter writer) {
+ switch (reference) {
+ case "T:System.Int16":
+ writer.WriteReferenceLink(reference, "Short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(reference, "Integer");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(reference, "Long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(reference, "UShort");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(reference, "UInteger");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(reference, "ULong");
+ break;
+ default:
+ writer.WriteReferenceLink(reference);
+ break;
+ }
+ }
+
+ private void WriteMemberReference (XPathNavigator member, SyntaxWriter writer) {
+ string api = member.GetAttribute("api", String.Empty);
+ writer.WriteReferenceLink(api);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicUsageSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicUsageSyntax.cs
new file mode 100644
index 0000000..a32faf2
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/VisualBasicUsageSyntax.cs
@@ -0,0 +1,778 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class VisualBasicUsageSyntaxGenerator : SyntaxGeneratorTemplate {
+
+ public VisualBasicUsageSyntaxGenerator (XPathNavigator configuration) : base(configuration) {
+ if (String.IsNullOrEmpty(Language)) Language = "VisualBasicUsage";
+ }
+
+ public override void WriteNamespaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ writer.WriteKeyword("Imports");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(name);
+ }
+
+ private void TypeDeclaration(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ TypeDeclaration(reflection, writer, false);
+ }
+
+ private void TypeDeclaration (XPathNavigator reflection, SyntaxWriter writer, bool writeVariance) {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+
+ writer.WriteKeyword("Dim");
+ writer.WriteString(" ");
+ writer.WriteParameter("instance");
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ if (declaringType != null) {
+ WriteTypeReference(declaringType, writer);
+ writer.WriteString(".");
+ }
+ if (reservedWords.ContainsKey(name)) {
+ writer.WriteString("[");
+ writer.WriteIdentifier(name);
+ writer.WriteString("]");
+ } else {
+ writer.WriteIdentifier(name);
+ }
+ WriteGenericTemplates(reflection, writer, writeVariance);
+ }
+
+ private void WriteGenericTemplates(XPathNavigator type, SyntaxWriter writer, bool writeVariance)
+ {
+ XPathNodeIterator templates = type.Select(apiTemplatesExpression);
+
+ if (templates.Count == 0) return;
+ writer.WriteString("(");
+ writer.WriteKeyword("Of");
+ writer.WriteString(" ");
+ while (templates.MoveNext())
+ {
+ XPathNavigator template = templates.Current;
+ if (templates.CurrentPosition > 1) writer.WriteString(", ");
+ if (writeVariance)
+ {
+ bool contravariant = (bool)template.Evaluate(templateIsContravariantExpression);
+ bool covariant = (bool)template.Evaluate(templateIsCovariantExpression);
+
+ if (contravariant)
+ {
+ writer.WriteKeyword("In");
+ writer.WriteString(" ");
+ }
+ if (covariant)
+ {
+ writer.WriteKeyword("Out");
+ writer.WriteString(" ");
+ }
+ }
+
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ }
+ writer.WriteString(")");
+
+ }
+
+ private void WriteGenericTemplates (XPathNavigator type, SyntaxWriter writer) {
+ WriteGenericTemplates(type, writer, false);
+ }
+
+ private void ParameterDeclaration (string name, XPathNavigator type, SyntaxWriter writer) {
+ writer.WriteKeyword("Dim");
+ writer.WriteString(" ");
+ writer.WriteParameter(name);
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+
+ string typeName = (string) type.Evaluate(apiNameExpression);
+
+ if (reservedWords.ContainsKey(typeName)) {
+ writer.WriteString("[");
+ WriteTypeReference(type, writer);
+ writer.WriteString("]");
+ } else {
+ WriteTypeReference(type, writer);
+ }
+
+ writer.WriteLine();
+ }
+
+ public override void WriteClassSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool)reflection.Evaluate(apiIsSealedTypeExpression);
+
+ if (isAbstract && isSealed) {
+ writer.WriteMessage("UnsupportedStaticClass_" + Language);
+ } else {
+ TypeDeclaration(reflection, writer);
+ }
+
+ }
+
+ public override void WriteStructureSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ TypeDeclaration(reflection, writer);
+ }
+
+ public override void WriteInterfaceSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ TypeDeclaration(reflection, writer, true); // Need to write variance info for interfaces and delegates
+ }
+
+ public override void WriteDelegateSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+
+ writer.WriteKeyword("Dim");
+ writer.WriteString(" ");
+ writer.WriteParameter("instance");
+ writer.WriteString(" ");
+ writer.WriteKeyword("As");
+ writer.WriteString(" ");
+ writer.WriteKeyword("New");
+ writer.WriteString(" ");
+
+ if (reservedWords.ContainsKey(name)) {
+ writer.WriteString("[");
+ writer.WriteIdentifier(name);
+ writer.WriteString("]");
+ } else {
+ writer.WriteIdentifier(name);
+ }
+
+ WriteGenericTemplates(reflection, writer, true); // Need to write variance info for interfaces and delegates
+ writer.WriteString("(");
+ writer.WriteKeyword("AddressOf");
+ writer.WriteString(" HandlerMethod)");
+ }
+
+ public override void WriteEnumerationSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ TypeDeclaration(reflection, writer);
+ }
+
+ public override void WriteFieldSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isLiteral = (bool)reflection.Evaluate(apiIsLiteralFieldExpression);
+ bool isInitOnly = (bool)reflection.Evaluate(apiIsInitOnlyFieldExpression);
+ bool isFamily = (bool)reflection.Evaluate(apiIsFamilyMemberExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ XPathNavigator fieldType = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ if (!(isStatic || isFamily)) ParameterDeclaration("instance", declaringType, writer);
+ ParameterDeclaration("value", fieldType, writer);
+
+ // get value
+ writer.WriteLine();
+ writer.WriteParameter("value");
+ writer.WriteString(" = ");
+ if (isStatic) {
+ WriteTypeReference(declaringType, writer);
+ } else {
+ if (isFamily) {
+ writer.WriteKeyword("Me");
+ } else {
+ writer.WriteParameter("instance");
+ }
+ }
+ writer.WriteString(".");
+ writer.WriteIdentifier(name);
+ writer.WriteLine();
+
+ // set value
+ if (isLiteral || isInitOnly) return;
+ writer.WriteLine();
+ if (isStatic) {
+ WriteTypeReference(declaringType, writer);
+ } else {
+ if (isFamily) {
+ writer.WriteKeyword("Me");
+ } else {
+ writer.WriteParameter("instance");
+ }
+ }
+ writer.WriteString(".");
+ writer.WriteIdentifier(name);
+ writer.WriteString(" = ");
+ writer.WriteParameter("value");
+
+ }
+
+ public override void WriteConstructorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+
+ // if static, no usage
+
+ WriteParameterDeclarations(reflection, writer);
+ writer.WriteLine();
+ writer.WriteKeyword("Dim");
+ writer.WriteString(" ");
+ writer.WriteParameter("instance");
+ writer.WriteString(" ");
+ writer.WriteKeyword("As New");
+ writer.WriteString(" ");
+
+ string typeName = (string)declaringType.Evaluate(apiNameExpression);
+
+ if (reservedWords.ContainsKey(typeName)) {
+ writer.WriteString("[");
+ WriteTypeReference(declaringType, writer);
+ writer.WriteString("]");
+ } else {
+ WriteTypeReference(declaringType, writer);
+ }
+
+ WriteMethodParameters(reflection, writer);
+ }
+
+ public override void WriteMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+ base.WriteMethodSyntax(reflection, writer);
+ }
+
+ public override void WriteNormalMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isExtension = (bool)reflection.Evaluate(apiIsExtensionMethod);
+ if (isExtension) {
+ WriteExtensionMethodSyntax(reflection, writer);
+ } else {
+
+ //string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ //bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isFamily = (bool)reflection.Evaluate(apiIsFamilyMemberExpression);
+
+ if (!(isStatic || isFamily)) ParameterDeclaration("instance", declaringType, writer);
+ WriteParameterDeclarations(reflection, writer);
+ if (returnType != null) ParameterDeclaration("returnValue", returnType, writer);
+ writer.WriteLine();
+
+ if (returnType != null) {
+ writer.WriteParameter("returnValue");
+ writer.WriteString(" = ");
+ }
+
+ WriteMemberName(reflection, writer);
+ WriteMethodParameters(reflection, writer);
+
+ }
+ }
+
+ // what about generic methods?
+
+ private void WriteMemberName (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool isExplicit = (bool)reflection.Evaluate(apiIsExplicitImplementationExpression);
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isFamily = (bool)reflection.Evaluate(apiIsFamilyMemberExpression);
+ bool isDefault = (bool)reflection.Evaluate(apiIsDefaultMemberExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ if (isExplicit) {
+ XPathNavigator member = reflection.SelectSingleNode(apiImplementedMembersExpression);
+ XPathNavigator contract = member.SelectSingleNode(memberDeclaringTypeExpression);
+ writer.WriteKeyword("CType");
+ writer.WriteString("(");
+ writer.WriteParameter("instance");
+ writer.WriteString(", ");
+ WriteTypeReference(contract, writer);
+ writer.WriteString(").");
+ WriteMemberReference(member, writer);
+ } else {
+ if (isStatic) {
+ WriteTypeReference(declaringType, writer);
+ } else {
+ if (isFamily) {
+ writer.WriteKeyword("Me");
+ } else {
+ writer.WriteString("instance");
+ }
+ }
+ if (!isDefault) {
+ writer.WriteString(".");
+ writer.WriteIdentifier(name);
+ }
+ }
+ }
+
+ private void WriteExtensionMethodSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ // extract the first parameter as the extension type
+ parameters.MoveNext();
+ XPathNavigator extendedType = parameters.Current.SelectSingleNode(parameterTypeExpression);
+ string extendedTypeName = (string) parameters.Current.Evaluate(parameterNameExpression);
+
+ // write the declarations
+ ParameterDeclaration(extendedTypeName, extendedType, writer);
+ WriteParameterDeclarations(parameters.Clone(), writer);
+ if (returnType != null) ParameterDeclaration("returnValue", returnType, writer);
+ writer.WriteLine();
+
+ // write the method invocation
+ if (returnType != null) {
+ writer.WriteParameter("returnValue");
+ writer.WriteString(" = ");
+ }
+ writer.WriteParameter(extendedTypeName);
+ writer.WriteString(".");
+ writer.WriteIdentifier(name);
+ writer.WriteString("(");
+ WriteParameters(parameters.Clone(), reflection, writer);
+ writer.WriteString(")");
+
+ }
+
+ public override void WriteOperatorSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ string name = (string) reflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+
+ // Determine operator identifier and type
+ string identifier;
+ int type;
+ switch (name) {
+ // unary math operators
+ case "UnaryPlus":
+ identifier = "+";
+ type = -1;
+ break;
+ case "UnaryNegation":
+ identifier = "-";
+ type = -1;
+ break;
+ case "Increment":
+ identifier = "++";
+ type = +1;
+ break;
+ case "Decrement":
+ identifier = "--";
+ type = +1;
+ break;
+ // unary logical operators
+ case "LogicalNot":
+ identifier = "Not";
+ type = -1;
+ break;
+ case "True":
+ identifier = "IsTrue";
+ type = -1;
+ break;
+ case "False":
+ identifier = "IsFalse";
+ type = -1;
+ break;
+ // binary comparison operators
+ case "Equality":
+ identifier = "=";
+ type = 2;
+ break;
+ case "Inequality":
+ identifier = "<>";
+ type = 2;
+ break;
+ case "LessThan":
+ identifier = "<";
+ type = 2;
+ break;
+ case "GreaterThan":
+ identifier = ">";
+ type = 2;
+ break;
+ case "LessThanOrEqual":
+ identifier = "<=";
+ type = 2;
+ break;
+ case "GreaterThanOrEqual":
+ identifier = ">=";
+ type = 2;
+ break;
+ // binary math operators
+ case "Addition":
+ identifier = "+";
+ type = 2;
+ break;
+ case "Subtraction":
+ identifier = "-";
+ type = 2;
+ break;
+ case "Multiply":
+ identifier = "*";
+ type = 2;
+ break;
+ case "Division":
+ identifier = "/";
+ type = 2;
+ break;
+ case "Exponent":
+ identifier = "^";
+ type = 2;
+ break;
+ case "Modulus":
+ identifier = "Mod";
+ type = 2;
+ break;
+ case "IntegerDivision":
+ identifier = @"\";
+ type = 2;
+ break;
+ // binary logical operators
+ case "BitwiseAnd":
+ identifier = "And";
+ type = 2;
+ break;
+ case "BitwiseOr":
+ identifier = "Or";
+ type = 2;
+ break;
+ case "ExclusiveOr":
+ identifier = "Xor";
+ type = 2;
+ break;
+ // bit-array operators
+ case "OnesComplement":
+ identifier = "~";
+ type = -1;
+ break;
+ case "LeftShift":
+ identifier = "<<";
+ type = 2;
+ break;
+ case "RightShift":
+ identifier = ">>";
+ type = 2;
+ break;
+ // concatenation
+ case "Concatenate":
+ identifier = "&";
+ type = 2;
+ break;
+ // didn't recognize an operator
+ default:
+ identifier = null;
+ type = 0;
+ break;
+ }
+
+ if (identifier == null) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ } else {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+ if (parameters.Count != Math.Abs(type)) {
+ writer.WriteMessage("UnsupportedOperator_" + Language);
+ return;
+ } //throw new InvalidOperationException("An operator has the wrong number of parameters.");
+
+ WriteParameterDeclarations(reflection, writer);
+ ParameterDeclaration("returnValue", returnType, writer);
+ writer.WriteLine();
+ writer.WriteParameter("returnValue");
+ writer.WriteString(" = ");
+ switch (type) {
+ case -1:
+ writer.WriteIdentifier(identifier);
+ parameters.MoveNext();
+ writer.WriteParameter((string)parameters.Current.Evaluate(parameterNameExpression));
+ break;
+ case +1:
+ parameters.MoveNext();
+ writer.WriteParameter((string)parameters.Current.Evaluate(parameterNameExpression));
+ writer.WriteIdentifier(identifier);
+ break;
+ case 2:
+ writer.WriteString("(");
+
+ // parameter 1
+ parameters.MoveNext();
+ writer.WriteParameter((string)parameters.Current.Evaluate(parameterNameExpression));
+
+ writer.WriteString(" ");
+ writer.WriteIdentifier(identifier);
+ writer.WriteString(" ");
+
+ // parameter 2
+ parameters.MoveNext();
+ writer.WriteParameter((string)parameters.Current.Evaluate(parameterNameExpression));
+
+ writer.WriteString(")");
+ break;
+ }
+ }
+
+ }
+
+ public override void WriteCastSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNavigator parameter = reflection.SelectSingleNode(apiParametersExpression);
+ if (parameter == null) return;
+ XPathNavigator inputType = parameter.SelectSingleNode(typeExpression);
+ XPathNavigator outputType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ if ((inputType == null) || (outputType == null)) return;
+
+ ParameterDeclaration("input", inputType, writer);
+ ParameterDeclaration("output", outputType, writer);
+ writer.WriteLine();
+ writer.WriteParameter("output");
+ writer.WriteString(" = ");
+ writer.WriteKeyword("CType");
+ writer.WriteString("(");
+ writer.WriteParameter("input");
+ writer.WriteString(", ");
+ WriteTypeReference(outputType, writer);
+ writer.WriteString(")");
+ }
+
+ public override void WritePropertySyntax (XPathNavigator reflection, SyntaxWriter writer) {
+
+ if (IsUnsupportedUnsafe(reflection, writer)) return;
+
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isFamily = (bool)reflection.Evaluate(apiIsFamilyMemberExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ XPathNavigator propertyType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ bool getter = (bool)reflection.Evaluate(apiIsReadPropertyExpression);
+ bool setter = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+
+ if (!(isStatic || isFamily)) ParameterDeclaration("instance", declaringType, writer);
+ WriteParameterDeclarations(reflection, writer);
+ ParameterDeclaration("value", propertyType, writer);
+
+ // get value
+ if (getter) {
+ string getVisibility = (string)reflection.Evaluate(apiGetVisibilityExpression);
+ if (string.IsNullOrEmpty(getVisibility) || (getVisibility != "assembly" &&
+ getVisibility != "private" && getVisibility != "family and assembly"))
+ {
+ writer.WriteLine();
+ writer.WriteParameter("value");
+ writer.WriteString(" = ");
+ WriteMemberName(reflection, writer);
+ WritePropertyParameters(reflection, writer);
+ writer.WriteLine();
+ }
+ }
+
+ // set value
+ if (setter) {
+ string setVisibility = (string)reflection.Evaluate(apiSetVisibilityExpression);
+ if (string.IsNullOrEmpty(setVisibility) || (setVisibility != "assembly" &&
+ setVisibility != "private" && setVisibility != "family and assembly"))
+ {
+ writer.WriteLine();
+ WriteMemberName(reflection, writer);
+ WritePropertyParameters(reflection, writer);
+ writer.WriteString(" = ");
+ writer.WriteParameter("value");
+ }
+ }
+
+ }
+
+ public override void WriteEventSyntax (XPathNavigator reflection, SyntaxWriter writer) {
+ bool isStatic = (bool)reflection.Evaluate(apiIsStaticExpression);
+ bool isFamily = (bool)reflection.Evaluate(apiIsFamilyMemberExpression);
+ XPathNavigator declaringType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ XPathNavigator handler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ if (!(isStatic | isFamily)) ParameterDeclaration("instance", declaringType, writer);
+ ParameterDeclaration("handler", handler, writer);
+
+ // adder
+ writer.WriteLine();
+ writer.WriteKeyword("AddHandler");
+ writer.WriteString(" ");
+ WriteMemberName(reflection, writer);
+ writer.WriteString(", ");
+ writer.WriteParameter("handler");
+ writer.WriteLine();
+ }
+
+ private void WriteParameterDeclarations (XPathNavigator reflection, SyntaxWriter writer) {
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+ if (parameters.Count == 0) return;
+ WriteParameterDeclarations(parameters, writer);
+ }
+
+ private void WriteParameterDeclarations (XPathNodeIterator parameters, SyntaxWriter writer) {
+ while (parameters.MoveNext()) {
+ XPathNavigator parameter = parameters.Current;
+ XPathNavigator type = parameter.SelectSingleNode(parameterTypeExpression);
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+ ParameterDeclaration(name, type, writer);
+ }
+ }
+
+ private void WriteMethodParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ writer.WriteString("(");
+ if (parameters.Count > 0) {
+ WriteParameters(parameters, reflection, writer);
+ }
+ writer.WriteString(")");
+
+ }
+
+ private void WritePropertyParameters (XPathNavigator reflection, SyntaxWriter writer) {
+
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ if (parameters.Count == 0) return;
+
+ writer.WriteString("(");
+ WriteParameters(parameters, reflection, writer);
+ writer.WriteString(")");
+
+ }
+
+
+ private void WriteParameters(XPathNodeIterator parameters, XPathNavigator reflection, SyntaxWriter writer)
+ {
+ while (parameters.MoveNext())
+ {
+ XPathNavigator parameter = parameters.Current;
+ string name = (string)parameter.Evaluate(parameterNameExpression);
+ writer.WriteParameter(name);
+
+ if (parameters.CurrentPosition < parameters.Count)
+ {
+ writer.WriteString(", ");
+ if (writer.Position > maxPosition)
+ {
+ writer.WriteString("_");
+ writer.WriteLine();
+ writer.WriteString("\t");
+ }
+ }
+ }
+ }
+
+ private void WriteTypeReference (XPathNavigator reference, SyntaxWriter writer) {
+ switch (reference.LocalName) {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", String.Empty));
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("(");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString(")");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext()) {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext()) {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("(");
+ writer.WriteKeyword("Of");
+ writer.WriteString(" ");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext()) {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(")");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference (string reference, SyntaxWriter writer) {
+ switch (reference) {
+ case "T:System.Int16":
+ writer.WriteReferenceLink(reference, "Short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(reference, "Integer");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(reference, "Long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(reference, "UShort");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(reference, "UInteger");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(reference, "ULong");
+ break;
+ default:
+ writer.WriteReferenceLink(reference);
+ break;
+ }
+ }
+
+ private void WriteMemberReference (XPathNavigator member, SyntaxWriter writer) {
+ string api = member.GetAttribute("api", String.Empty);
+ writer.WriteReferenceLink(api);
+ }
+
+ private static Dictionary<string, object> reservedWords = new Dictionary<string, object>();
+
+ static VisualBasicUsageSyntaxGenerator () {
+ reservedWords.Add("Alias", null);
+ reservedWords.Add("Assembly", null);
+ reservedWords.Add("Class", null);
+ reservedWords.Add("Delegate", null);
+ reservedWords.Add("Function", null);
+ reservedWords.Add("Handles", null);
+ reservedWords.Add("Interface", null);
+ reservedWords.Add("Loop", null);
+ reservedWords.Add("Module", null);
+ reservedWords.Add("New", null);
+ reservedWords.Add("Next", null);
+ reservedWords.Add("Nothing", null);
+ reservedWords.Add("Operator", null);
+ reservedWords.Add("Option", null);
+ reservedWords.Add("Property", null);
+ reservedWords.Add("Structure", null);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/XamlUsageSyntax.cs b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/XamlUsageSyntax.cs
new file mode 100644
index 0000000..5a6b590
--- /dev/null
+++ b/tools/Sandcastle/Source/BuildAssembler/SyntaxComponents/XamlUsageSyntax.cs
@@ -0,0 +1,953 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+using System.Configuration;
+using System.IO;
+
+namespace Microsoft.Ddue.Tools
+{
+ public class XamlUsageSyntaxGenerator : SyntaxGeneratorTemplate
+ {
+
+ public XamlUsageSyntaxGenerator(XPathNavigator configuration)
+ : base(configuration)
+ {
+ LoadConfigNode(configuration);
+ if (String.IsNullOrEmpty(Language)) Language = "XAML";
+ }
+
+ public override void WriteSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ writer.WriteStartBlock(Language);
+
+ // Check the list of assemblies for which to generate XAML syntax
+ string assemblyName = (string)reflection.Evaluate(apiContainingAssemblyExpression);
+ string namespaceName = (string)reflection.Evaluate(apiContainingNamespaceNameExpression);
+ if (!xamlAssemblies.ContainsKey(assemblyName.ToLower()))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.nonXamlAssemblyBoilerplate, writer);
+ }
+ else
+ {
+ string group = (string)reflection.Evaluate(apiGroupExpression);
+ switch (group)
+ {
+ case "namespace":
+ WriteNamespaceSyntax(reflection, writer);
+ break;
+ case "type":
+ WriteTypeSyntax(reflection, writer);
+ break;
+ case "member":
+ WriteMemberSyntax(reflection, writer);
+ break;
+ }
+ WriteXamlXmlnsUri(assemblyName, namespaceName, writer);
+ }
+
+ writer.WriteEndBlock();
+ }
+
+ private void WriteXamlXmlnsUri(string assemblyName, string namespaceName, SyntaxWriter writer)
+ {
+ Dictionary<string, List<string>> clrNamespaces;
+ if (xamlAssemblies.TryGetValue(assemblyName.ToLower(), out clrNamespaces))
+ {
+ List<string> xmlnsUriList;
+ if (clrNamespaces.TryGetValue(namespaceName, out xmlnsUriList))
+ {
+ foreach (string xmlnsUri in xmlnsUriList)
+ {
+ // start the syntax block
+ writer.WriteStartSubBlock("xamlXmlnsUri");
+ writer.WriteString(xmlnsUri);
+ writer.WriteEndSubBlock();
+ }
+ }
+ }
+ }
+
+ // list of classes whose subclasses do NOT get XAML syntax
+ protected List<string> excludedAncestorList = new List<string>();
+
+ // list of assemblies whose members get XAML syntax
+ // the nested Dictionary is a list of assembly's namespaces that have one or more xmlns uris for xaml
+ private Dictionary<string, Dictionary<string, List<string>>> xamlAssemblies = new Dictionary<string, Dictionary<string, List<string>>>();
+
+
+ private void LoadConfigNode(XPathNavigator configuration)
+ {
+ // get the filter files
+ XPathNodeIterator filterNodes = configuration.Select("filter");
+ if (filterNodes.Count == 0)
+ {
+ LoadConfiguration(configuration);
+ return;
+ }
+
+ foreach (XPathNavigator filterNode in filterNodes)
+ {
+ string filterFiles = filterNode.GetAttribute("files", String.Empty);
+ if ((filterFiles == null) || (filterFiles.Length == 0))
+ throw new ConfigurationErrorsException("The XamlUsageSyntaxGenerator filter/@files attribute must specify a path.");
+ ParseDocuments(filterFiles);
+ }
+ }
+
+ private void LoadConfiguration(XPathNavigator configuration)
+ {
+ // get the list of excluded ancestor classes
+ foreach (XPathNavigator excludedClass in configuration.Select("xamlExcludedAncestors/class"))
+ {
+ string apiId = excludedClass.GetAttribute("api", string.Empty);
+ if (apiId.Length > 0 && !excludedAncestorList.Contains(apiId))
+ excludedAncestorList.Add(apiId);
+ }
+
+ // get the list of XAML assemblies; members in other assemblies get no xaml syntax, just 'not applicable' boilerplate
+ foreach (XPathNavigator xamlAssembly in configuration.Select("xamlAssemblies/assembly"))
+ {
+ string assemblyName = xamlAssembly.GetAttribute("name", string.Empty);
+ if (string.IsNullOrEmpty(assemblyName))
+ continue; // should emit warning message
+
+ Dictionary<string, List<string>> clrNamespaces;
+ if (!xamlAssemblies.TryGetValue(assemblyName.ToLower(), out clrNamespaces))
+ {
+ clrNamespaces = new Dictionary<string, List<string>>();
+ xamlAssemblies.Add(assemblyName.ToLower(), clrNamespaces);
+ }
+
+ foreach (XPathNavigator xmlnsNode in xamlAssembly.Select("xmlns[@uri][clrNamespace]"))
+ {
+ string xmlnsUri = xmlnsNode.GetAttribute("uri", string.Empty);
+ if (string.IsNullOrEmpty(xmlnsUri))
+ continue; // should emit warning message
+
+ foreach (XPathNavigator clrNamespaceNode in xmlnsNode.Select("clrNamespace[@name]"))
+ {
+ string namespaceName = clrNamespaceNode.GetAttribute("name", string.Empty);
+ if (string.IsNullOrEmpty(namespaceName))
+ continue; // should emit warning message
+
+ List<string> xmlnsUriList;
+ if (!clrNamespaces.TryGetValue(namespaceName, out xmlnsUriList))
+ {
+ xmlnsUriList = new List<string>();
+ clrNamespaces.Add(namespaceName, xmlnsUriList);
+ }
+ if (!xmlnsUriList.Contains(xmlnsUri))
+ xmlnsUriList.Add(xmlnsUri);
+ }
+ }
+ }
+ }
+
+ public void ParseDocuments(string wildcardPath)
+ {
+ string filterFiles = Environment.ExpandEnvironmentVariables(wildcardPath);
+ if ((filterFiles == null) || (filterFiles.Length == 0))
+ throw new ConfigurationErrorsException("The XamlUsageSyntaxGenerator filter path is an empty string.");
+
+ //WriteMessage(MessageLevel.Info, String.Format("XamlUsageSyntaxGenerator: Searching for files that match '{0}'.", filterFiles));
+ string directoryPart = Path.GetDirectoryName(filterFiles);
+ if (String.IsNullOrEmpty(directoryPart))
+ directoryPart = Environment.CurrentDirectory;
+ directoryPart = Path.GetFullPath(directoryPart);
+ string filePart = Path.GetFileName(filterFiles);
+ string[] files = Directory.GetFiles(directoryPart, filePart);
+ foreach (string file in files)
+ ParseDocument(file);
+ //WriteMessage(MessageLevel.Info, String.Format("Found {0} files in {1}.", files.Length, filterFiles));
+ }
+
+ private void ParseDocument(string file)
+ {
+ try
+ {
+ XPathDocument document = new XPathDocument(file);
+
+ XPathNavigator xamlSyntaxNode = document.CreateNavigator().SelectSingleNode("/*");
+ LoadConfiguration(xamlSyntaxNode);
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationErrorsException(string.Format("Exception parsing XamlUsageSyntaxGenerator filter file: {0}. Exception message: {1}", file, e.Message));
+ }
+ }
+
+ public override void WriteNamespaceSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ // empty xaml syntax for namespace topics
+ }
+
+ private void WriteXamlBoilerplate(XamlBoilerplateID bpID, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(bpID, null, writer);
+ }
+
+ private void WriteXamlBoilerplate(XamlBoilerplateID bpID, XPathNavigator typeReflection, SyntaxWriter writer)
+ {
+ string xamlBlockId = System.Enum.GetName(typeof(XamlBoilerplateID), bpID);
+ if (xamlBlockId != null)
+ {
+ writer.WriteStartSubBlock(xamlBlockId);
+ if (typeReflection != null)
+ WriteTypeReference(typeReflection, writer);
+ writer.WriteEndSubBlock();
+ }
+ }
+
+ public override void WriteClassSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = reflection.Evaluate(apiNameExpression).ToString();
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractTypeExpression);
+ bool isSealed = (bool)reflection.Evaluate(apiIsSealedTypeExpression);
+ bool isSerializable = (bool)reflection.Evaluate(apiIsSerializableTypeExpression);
+ //
+ if (isAbstract && !isSealed)
+ {
+ // Output boilerplate for abstract class
+ WriteXamlBoilerplate(XamlBoilerplateID.classXamlSyntax_abstract, writer);
+ }
+ else if (!HasDefaultConstructor(reflection))
+ {
+ if (HasTypeConverterAttribute(reflection))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.classXamlSyntax_noDefaultCtorWithTypeConverter, writer);
+ }
+ else
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.classXamlSyntax_noDefaultCtor, writer);
+ }
+ }
+ else if (IsExcludedSubClass(reflection))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.classXamlSyntax_excludedSubClass, writer);
+ }
+ else
+ {
+ // show the default XAML syntax for classes
+ // Note: skipped the test for TypeConverterAttribute shown in the flowchart because same syntax either way
+ ObjectElementUsageForClassStruct(reflection, writer);
+ }
+ }
+
+ private void ObjectElementUsageForClassStruct(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string typeName = (string)reflection.Evaluate(apiNameExpression);
+ bool isGeneric = (bool)reflection.Evaluate(apiIsGenericExpression);
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlObjectElementUsageHeading);
+
+ string contentPropertyId = (string)reflection.Evaluate(contentPropertyIdExpression);
+ if (contentPropertyId == "")
+ contentPropertyId = (string)reflection.Evaluate(ancestorContentPropertyIdExpression);
+
+ // start the syntax block
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ writer.WriteString("<");
+ if (isGeneric)
+ {
+ writer.WriteIdentifier(typeName);
+
+ // for generic types show the type arguments
+ XPathNodeIterator templates = (XPathNodeIterator)reflection.Evaluate(apiTemplatesExpression);
+ if (templates.Count > 0)
+ {
+ writer.WriteString(" x:TypeArguments=\"");
+ while (templates.MoveNext())
+ {
+ XPathNavigator template = templates.Current;
+ string name = template.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ if (templates.CurrentPosition < templates.Count)
+ writer.WriteString(",");
+ }
+ writer.WriteString("\"");
+ }
+ }
+ else
+ {
+ // for non-generic types just show the name
+ writer.WriteIdentifier(typeName);
+ }
+ if (contentPropertyId == string.Empty)
+ {
+ writer.WriteString(" .../>");
+ }
+ else
+ {
+ // close the start tag
+ writer.WriteString(">");
+
+ // the inner xml of the Object Element syntax for a type with a content property
+ // is a link to the content property
+ writer.WriteLine();
+ writer.WriteString(" ");
+ writer.WriteReferenceLink(contentPropertyId);
+ writer.WriteLine();
+
+ // write the end tag
+ writer.WriteString("</");
+ writer.WriteIdentifier(typeName);
+ writer.WriteString(">");
+ }
+
+ // end the sub block
+ writer.WriteEndSubBlock();
+ }
+
+
+ public override void WriteStructureSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string name = (string)reflection.Evaluate(apiNameExpression);
+ bool notWriteable = (bool)reflection.Evaluate(noSettablePropertiesExpression);
+
+ if (notWriteable)
+ {
+ // Output boilerplate for struct with no writeable properties
+ WriteXamlBoilerplate(XamlBoilerplateID.structXamlSyntax_nonXaml, writer);
+ }
+ else
+ {
+ // All writeable structs in XAML assemblies are usable in XAML
+ // always show the Object Element Usage syntax
+ ObjectElementUsageForClassStruct(reflection, writer);
+
+ // For structs with TypeConverterAttribute,
+ // if we can show multiple syntax blocks, also output AttributeUsage boilerplate
+ if (HasTypeConverterAttribute(reflection))
+ WriteXamlBoilerplate(XamlBoilerplateID.structXamlSyntax_attributeUsage, writer);
+ }
+ }
+
+ public override void WriteInterfaceSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.interfaceOverviewXamlSyntax, writer);
+ }
+
+ public override void WriteDelegateSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.delegateOverviewXamlSyntax, writer);
+ }
+
+ public override void WriteEnumerationSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.enumerationOverviewXamlSyntax, writer);
+ }
+
+ public override void WriteConstructorSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.constructorOverviewXamlSyntax, writer);
+ }
+
+ public override void WriteMethodSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.methodOverviewXamlSyntax, writer);
+ }
+
+ public override void WriteAttachedPropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string propertyName = (string)reflection.Evaluate(apiNameExpression);
+ string containingTypeName = (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ if (!isSettable)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_readOnly, writer);
+ }
+ else
+ {
+ // xaml syntax block for attached property
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlAttributeUsageHeading);
+ writer.WriteStartSubBlock(xamlBlockId);
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(containingTypeName + "." + propertyName);
+ writer.WriteString("=\"");
+ WriteTypeReference(returnType, writer);
+ writer.WriteString("\" .../>");
+ writer.WriteEndSubBlock();
+ }
+ }
+
+ public override void WritePropertySyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ //containingTypeSubgroupExpression
+ string propertyName = (string)reflection.Evaluate(apiNameExpression);
+ bool isSettable = (bool)reflection.Evaluate(apiIsWritePropertyExpression);
+ bool isSetterPublic = (bool)reflection.Evaluate(apiIsSetterPublicExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ string propertyVisibility = (string)reflection.Evaluate(apiVisibilityExpression);
+ XPathNodeIterator parameters = reflection.Select(apiParametersExpression);
+
+ XPathNavigator returnType = reflection.SelectSingleNode(apiReturnTypeExpression);
+ bool notWriteableReturnType = (bool)returnType.Evaluate(noSettablePropertiesExpression);
+ string returnTypeId = returnType.GetAttribute("api", string.Empty);
+ string returnTypeSubgroup = (string)returnType.Evaluate(apiSubgroupExpression);
+ bool returnTypeIsAbstract = (bool)returnType.Evaluate(apiIsAbstractTypeExpression);
+ bool returnTypeIsReadonlyStruct = (returnTypeSubgroup == "structure" && notWriteableReturnType && !IsPrimitiveType(returnTypeId));
+
+ XPathNavigator containingType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ string containingTypeSubgroup = (string)containingType.Evaluate(apiSubgroupExpression);
+
+ // an ordinary property, not an attached prop
+ if (containingTypeSubgroup == "interface")
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_noXamlSyntaxForInterfaceMembers, writer);
+ }
+ else if ((bool)containingType.Evaluate(apiIsAbstractTypeExpression) && (bool)containingType.Evaluate(apiIsSealedTypeExpression))
+ {
+ // the property's containing type is static if it's abstract and sealed
+ // members of a static class cannot be used in XAML.
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_nonXamlParent, writer);
+ }
+ else if (IsExcludedSubClass(containingType))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_parentIsExcludedSubClass, writer);
+ }
+ else if (!DoesParentSupportXaml(reflection))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_nonXamlParent, writer);
+ }
+ else if (propertyVisibility != "public")
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_notPublic, writer);
+ }
+ else if (isAbstract)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_abstract, writer);
+ }
+ else if (parameters.Count > 0)
+ {
+ // per DDUERELTools bug 1373: indexer properties cannot be used in XAML
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_nonXaml, writer);
+ }
+ else if (IsContentProperty(reflection) && !returnTypeIsReadonlyStruct)
+ {
+ PropertyContentElementUsageSimple(reflection, writer);
+ }
+ else if (!isSettable || !isSetterPublic)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_readOnly, writer);
+ }
+ else if (returnTypeIsAbstract)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_abstractType, returnType, writer);
+ }
+ else if (IsPrimitiveType(returnTypeId))
+ {
+ PropertyAttributeUsage(reflection, writer);
+ }
+ else if (returnTypeSubgroup == "enumeration")
+ {
+ PropertyAttributeUsage(reflection, writer);
+ }
+ else
+ {
+ bool hasDefaultConstructor = HasDefaultConstructor(returnType);
+ if (HasTypeConverterAttribute(returnType))
+ {
+ if (hasDefaultConstructor && !returnTypeIsReadonlyStruct)
+ {
+ PropertyElementUsageGrande(reflection, writer);
+ }
+ PropertyAttributeUsage(reflection, writer);
+ }
+ else if (hasDefaultConstructor && !returnTypeIsReadonlyStruct)
+ {
+ PropertyElementUsageGrande(reflection, writer);
+ }
+ else
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.propertyXamlSyntax_nonXaml, writer);
+ }
+ }
+ }
+
+ // A simple Property Element Usage block for a content property
+ // syntax looks like:
+ // <object>
+ // <linkToType .../>
+ // </object>
+ private void PropertyContentElementUsageSimple(XPathNavigator propertyReflection, SyntaxWriter writer)
+ {
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlContentElementUsageHeading);
+ XPathNavigator returnType = propertyReflection.SelectSingleNode(apiReturnTypeExpression);
+
+ // start the syntax block
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ // <object>
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(">");
+ writer.WriteLine();
+ // <linkToType .../>
+ writer.WriteString(" <");
+ WriteTypeReference(returnType, writer);
+ writer.WriteString(" .../>");
+ writer.WriteLine();
+ // </object>
+ writer.WriteString("</");
+ writer.WriteParameter("object");
+ writer.WriteString(">");
+
+ writer.WriteEndSubBlock();
+ }
+
+ // A grandiose Property Element Usage block
+ // syntax looks like:
+ // <object>
+ // <object.PropertyName>
+ // <linkToType .../>
+ // </object.PropertyName>
+ // </object>
+ private void PropertyElementUsageGrande(XPathNavigator propertyReflection, SyntaxWriter writer)
+ {
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlPropertyElementUsageHeading);
+ string propertyName = (string)propertyReflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = propertyReflection.SelectSingleNode(apiReturnTypeExpression);
+
+ // start the syntax block
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ // <object>
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(">");
+ writer.WriteLine();
+ // <object.PropertyName>
+ writer.WriteString(" <");
+ writer.WriteParameter("object");
+ writer.WriteString(".");
+ writer.WriteIdentifier(propertyName);
+ writer.WriteString(">");
+ writer.WriteLine();
+ // <linkToType .../>
+ writer.WriteString(" <");
+ WriteTypeReference(returnType, writer);
+ writer.WriteString(" .../>");
+ writer.WriteLine();
+ // </object.PropertyName>
+ writer.WriteString(" </");
+ writer.WriteParameter("object");
+ writer.WriteString(".");
+ writer.WriteIdentifier(propertyName);
+ writer.WriteString(">");
+ writer.WriteLine();
+ // </object>
+ writer.WriteString("</");
+ writer.WriteParameter("object");
+ writer.WriteString(">");
+
+ writer.WriteEndSubBlock();
+ }
+
+ // An Attribute Usage block
+ private void PropertyAttributeUsage(XPathNavigator propertyReflection, SyntaxWriter writer)
+ {
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlAttributeUsageHeading);
+ string propertyName = (string)propertyReflection.Evaluate(apiNameExpression);
+ XPathNavigator returnType = propertyReflection.SelectSingleNode(apiReturnTypeExpression);
+
+ // start the syntax block
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ // syntax looks like:
+ // <object PropertyName="linkToType" .../>
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(propertyName);
+ writer.WriteString("=\"");
+ WriteTypeReference(returnType, writer);
+ writer.WriteString("\" .../>");
+
+ writer.WriteEndSubBlock();
+ }
+
+ public override void WriteEventSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string eventName = (string)reflection.Evaluate(apiNameExpression);
+ string eventVisibility = (string)reflection.Evaluate(apiVisibilityExpression);
+ bool isAbstract = (bool)reflection.Evaluate(apiIsAbstractProcedureExpression);
+ XPathNavigator eventHandler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ XPathNavigator containingType = reflection.SelectSingleNode(apiContainingTypeExpression);
+ string containingTypeSubgroup = (string)containingType.Evaluate(apiSubgroupExpression);
+ bool containingTypeIsAbstract = (bool)containingType.Evaluate(apiIsAbstractTypeExpression);
+ bool containingTypeIsSealed = (bool)containingType.Evaluate(apiIsSealedTypeExpression);
+
+ if (containingTypeSubgroup == "interface")
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_noXamlSyntaxForInterfaceMembers, writer);
+ }
+ else if (containingTypeIsAbstract && containingTypeIsSealed)
+ {
+ // the event's containing type is static if it's abstract and sealed
+ // members of a static class cannot be used in XAML.
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_nonXamlParent, writer);
+ }
+ else if (IsExcludedSubClass(containingType))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_parentIsExcludedSubClass, writer);
+ }
+ else if (!DoesParentSupportXaml(reflection))
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_nonXamlParent, writer);
+ }
+ else if (eventVisibility != "public")
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_notPublic, writer);
+ }
+ else if (isAbstract)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.eventXamlSyntax_abstract, writer);
+ }
+ else
+ {
+ // start the syntax block
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlAttributeUsageHeading);
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ // syntax looks like:
+ // <object eventName="eventHandlerLink" .../>
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(eventName);
+ writer.WriteString("=\"");
+ WriteTypeReference(eventHandler, writer);
+ writer.WriteString("\" .../>");
+
+ writer.WriteEndSubBlock();
+ }
+ }
+
+ public override void WriteAttachedEventSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ string eventName = (string)reflection.Evaluate(apiNameExpression);
+ string containingTypeName = (string)reflection.Evaluate(apiContainingTypeNameExpression);
+ XPathNavigator eventHandler = reflection.SelectSingleNode(apiHandlerOfEventExpression);
+
+ // xaml syntax block for attached event
+ string xamlBlockId = System.Enum.GetName(typeof(XamlHeadingID), XamlHeadingID.xamlAttributeUsageHeading);
+ writer.WriteStartSubBlock(xamlBlockId);
+
+ writer.WriteString("<");
+ writer.WriteParameter("object");
+ writer.WriteString(" ");
+ writer.WriteIdentifier(containingTypeName + "." + eventName);
+ writer.WriteString("=\"");
+ WriteTypeReference(eventHandler, writer);
+ writer.WriteString(string.Format("\" .../>"));
+
+ writer.WriteEndSubBlock();
+ }
+
+ public override void WriteFieldSyntax(XPathNavigator reflection, SyntaxWriter writer)
+ {
+ WriteXamlBoilerplate(XamlBoilerplateID.fieldOverviewXamlSyntax, writer);
+ }
+
+ // References
+
+ private void WriteTypeReference(XPathNavigator reference, SyntaxWriter writer)
+ {
+ switch (reference.LocalName)
+ {
+ case "arrayOf":
+ int rank = Convert.ToInt32(reference.GetAttribute("rank", String.Empty));
+ XPathNavigator element = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(element, writer);
+ writer.WriteString("[");
+ for (int i = 1; i < rank; i++) { writer.WriteString(","); }
+ writer.WriteString("]");
+ break;
+ case "pointerTo":
+ XPathNavigator pointee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(pointee, writer);
+ writer.WriteString("*");
+ break;
+ case "referenceTo":
+ XPathNavigator referee = reference.SelectSingleNode(typeExpression);
+ WriteTypeReference(referee, writer);
+ break;
+ case "type":
+ string id = reference.GetAttribute("api", String.Empty);
+
+ XPathNavigator outerTypeReference = reference.SelectSingleNode(typeOuterTypeExpression);
+ if (outerTypeReference != null)
+ {
+ WriteTypeReference(outerTypeReference, writer);
+ writer.WriteString(".");
+ }
+
+ WriteNormalTypeReference(id, writer);
+ XPathNodeIterator typeModifiers = reference.Select(typeModifiersExpression);
+ while (typeModifiers.MoveNext())
+ {
+ WriteTypeReference(typeModifiers.Current, writer);
+ }
+ break;
+ case "template":
+ string name = reference.GetAttribute("name", String.Empty);
+ writer.WriteString(name);
+ XPathNodeIterator modifiers = reference.Select(typeModifiersExpression);
+ while (modifiers.MoveNext())
+ {
+ WriteTypeReference(modifiers.Current, writer);
+ }
+ break;
+ case "specialization":
+ writer.WriteString("<");
+ XPathNodeIterator arguments = reference.Select(specializationArgumentsExpression);
+ while (arguments.MoveNext())
+ {
+ if (arguments.CurrentPosition > 1) writer.WriteString(", ");
+ WriteTypeReference(arguments.Current, writer);
+ }
+ writer.WriteString(">");
+ break;
+ }
+ }
+
+ private void WriteNormalTypeReference(string reference, SyntaxWriter writer)
+ {
+ switch (reference)
+ {
+ case "T:System.Void":
+ writer.WriteReferenceLink(reference, "void");
+ break;
+ case "T:System.String":
+ writer.WriteReferenceLink(reference, "string");
+ break;
+ case "T:System.Boolean":
+ writer.WriteReferenceLink(reference, "bool");
+ break;
+ case "T:System.Byte":
+ writer.WriteReferenceLink(reference, "byte");
+ break;
+ case "T:System.SByte":
+ writer.WriteReferenceLink(reference, "sbyte");
+ break;
+ case "T:System.Char":
+ writer.WriteReferenceLink(reference, "char");
+ break;
+ case "T:System.Int16":
+ writer.WriteReferenceLink(reference, "short");
+ break;
+ case "T:System.Int32":
+ writer.WriteReferenceLink(reference, "int");
+ break;
+ case "T:System.Int64":
+ writer.WriteReferenceLink(reference, "long");
+ break;
+ case "T:System.UInt16":
+ writer.WriteReferenceLink(reference, "ushort");
+ break;
+ case "T:System.UInt32":
+ writer.WriteReferenceLink(reference, "uint");
+ break;
+ case "T:System.UInt64":
+ writer.WriteReferenceLink(reference, "ulong");
+ break;
+ case "T:System.Single":
+ writer.WriteReferenceLink(reference, "float");
+ break;
+ case "T:System.Double":
+ writer.WriteReferenceLink(reference, "double");
+ break;
+ case "T:System.Decimal":
+ writer.WriteReferenceLink(reference, "decimal");
+ break;
+ default:
+ writer.WriteReferenceLink(reference);
+ break;
+ }
+ }
+
+ // utility routines
+
+
+ // A default constructor is a a parameterless, public constructor method
+ // This is called for:
+ // a class
+ // the declaring type of a member
+ // the type of a property
+ private bool HasDefaultConstructor(XPathNavigator typeReflection)
+ {
+ // all structs have implicit default constructors
+ string subgroup = (string)typeReflection.Evaluate(apiSubgroupExpression);
+ if (subgroup == "structure")
+ return true;
+
+ return (bool)typeReflection.Evaluate(hasDefaultConstructorExpression);
+ }
+
+ // This is called to check for a "TypeConverterAttribute" on:
+ // a class or structure topic
+ // the declaring type of a property or event member
+ // the type of a property
+ private bool HasTypeConverterAttribute(XPathNavigator typeReflection)
+ {
+ return (bool)typeReflection.Evaluate(hasTypeConverterAttributeExpression);
+ }
+
+ // Get the id of the content property, if any, for the property's containing type
+ // return true if the content property id matches the current property's id
+ private bool IsContentProperty(XPathNavigator propertyReflection)
+ {
+ string propertyName = (string)propertyReflection.Evaluate(apiNameExpression);
+ XPathNavigator containingType = propertyReflection.SelectSingleNode(apiContainingTypeExpression);
+ string containingTypeName = (string)containingType.Evaluate(apiNameExpression);
+ string namespaceId = (string)propertyReflection.Evaluate(apiContainingNamespaceIdExpression);
+ string propertyId = string.Concat("P:", namespaceId.Substring(2), ".", string.Concat(containingTypeName, ".", propertyName));
+ string contentPropertyId = (string)containingType.Evaluate(contentPropertyIdExpression);
+ if (propertyId == contentPropertyId)
+ return true;
+ else
+ return false;
+ }
+
+ // Check the list of subclasses to exclude
+ // This is called to check the class ancestors of
+ // a class
+ // the declaring type of a property or event member
+ private bool IsExcludedSubClass(XPathNavigator typeReflection)
+ {
+ XPathNodeIterator ancestors = (XPathNodeIterator)typeReflection.Evaluate(apiAncestorsExpression);
+
+ foreach (XPathNavigator ancestor in ancestors)
+ {
+ string ancestorId = ancestor.GetAttribute("api", string.Empty);
+ if (excludedAncestorList.Contains(ancestorId))
+ return true;
+ }
+ return false;
+ }
+
+ // Check the parent type of a property or event.
+ // Does it have the necessary characteristics so the property or event can be used in XAML?
+ // Is PARENT CLASS abstract OR does it have a default ctor OR a class-level TypeConverter attribute?
+ private bool DoesParentSupportXaml(XPathNavigator memberReflection)
+ {
+ XPathNavigator containingType = memberReflection.SelectSingleNode(apiContainingTypeExpression);
+ if ((bool)containingType.Evaluate(apiIsAbstractTypeExpression))
+ return true;
+
+ if (HasDefaultConstructor(containingType))
+ return true;
+
+ if (HasTypeConverterAttribute(containingType))
+ return true;
+
+ // A property that returns a String doesn't need a TypeConverterAttribute, so return true here
+ XPathNavigator returnType = memberReflection.SelectSingleNode(apiReturnTypeExpression);
+ if (returnType != null)
+ {
+ string returnTypeId = returnType.GetAttribute("api", string.Empty);
+ if (returnTypeId == "T:System.String")
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool IsPrimitiveType(string typeId)
+ {
+ // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, Char, Double, and Single.
+ switch (typeId)
+ {
+ case "T:System.Boolean":
+ case "T:System.Byte":
+ case "T:System.SByte":
+ case "T:System.Int16":
+ case "T:System.UInt16":
+ case "T:System.Int32":
+ case "T:System.UInt32":
+ case "T:System.Int64":
+ case "T:System.UInt64":
+ case "T:System.IntPtr":
+ case "T:System.Char":
+ case "T:System.Double":
+ case "T:System.Single":
+ case "T:System.String": // String is not a primitive but is treated as one for this XAML purpose
+ return true;
+ default:
+ return false;
+ }
+ }
+
+
+ private XPathExpression hasTypeConverterAttributeExpression = XPathExpression.Compile("boolean(attributes/attribute/type[@api='T:System.ComponentModel.TypeConverterAttribute'])");
+
+ private XPathExpression hasDefaultConstructorExpression = XPathExpression.Compile("boolean(typedata/@defaultConstructor)");
+
+ private XPathExpression contentPropertyNameExpression = XPathExpression.Compile("string(attributes/attribute[type[contains(@api,'.ContentPropertyAttribute')]]/argument/value/.)");
+ private XPathExpression contentPropertyIdExpression = XPathExpression.Compile("string(typedata/@contentProperty)");
+ private XPathExpression ancestorContentPropertyIdExpression = XPathExpression.Compile("string(family/ancestors/type/@contentProperty)");
+
+ private XPathExpression noSettablePropertiesExpression = XPathExpression.Compile("boolean(typedata/@noSettableProperties)");
+
+ private XPathExpression apiIsSetterPublicExpression = XPathExpression.Compile("boolean((memberdata[@visibility='public'] and not(propertydata[@set-visibility!='public'])) or propertydata[@set-visibility='public'])");
+ }
+
+ public enum XamlBoilerplateID
+ {
+ // boilerplate for classes in xaml assemblies
+ classXamlSyntax_abstract,
+ classXamlSyntax_excludedSubClass,
+ classXamlSyntax_noDefaultCtor,
+ classXamlSyntax_noDefaultCtorWithTypeConverter,
+ // boilerplate for structs in xaml assemblies
+ structXamlSyntax_nonXaml,
+ structXamlSyntax_attributeUsage,
+ // boilerplate for events in xaml assemblies
+ eventXamlSyntax_parentIsExcludedSubClass,
+ eventXamlSyntax_noXamlSyntaxForInterfaceMembers,
+ eventXamlSyntax_nonXamlParent,
+ eventXamlSyntax_notPublic,
+ eventXamlSyntax_abstract,
+ eventXamlSyntax_nonXaml,
+ // boilerplate for properties in xaml assemblies
+ propertyXamlSyntax_parentIsExcludedSubClass,
+ propertyXamlSyntax_noXamlSyntaxForInterfaceMembers,
+ propertyXamlSyntax_nonXamlParent,
+ propertyXamlSyntax_notPublic,
+ propertyXamlSyntax_abstract,
+ propertyXamlSyntax_readOnly,
+ propertyXamlSyntax_abstractType,
+ propertyXamlSyntax_nonXaml,
+ // syntax used with all enums in xaml assemblies
+ enumerationOverviewXamlSyntax,
+ // boilerplate used with all method, field, etc. in xaml assemblies
+ delegateOverviewXamlSyntax,
+ interfaceOverviewXamlSyntax,
+ constructorOverviewXamlSyntax,
+ fieldOverviewXamlSyntax,
+ methodOverviewXamlSyntax,
+ // boilerplate used with all types and members in all non-xaml assemblies
+ nonXamlAssemblyBoilerplate
+ }
+
+ // XAML headings
+ public enum XamlHeadingID
+ {
+ xamlAttributeUsageHeading,
+ xamlObjectElementUsageHeading,
+ xamlPropertyElementUsageHeading,
+ xamlContentElementUsageHeading,
+ xamlSyntaxBoilerplateHeading
+ }
+
+
+}
diff --git a/tools/Sandcastle/Source/CCI/AssemblyCache.cs b/tools/Sandcastle/Source/CCI/AssemblyCache.cs
new file mode 100644
index 0000000..48c6787
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/AssemblyCache.cs
@@ -0,0 +1,354 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !ROTOR
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !FxCop
+ public
+#endif
+ class GlobalAssemblyCache
+ {
+ private GlobalAssemblyCache() { }
+ private static readonly object Lock = new object();
+ private static bool FusionLoaded;
+
+ /// <param name="codeBaseUri">Uri pointing to the assembly</param>
+ public static bool Contains(Uri codeBaseUri)
+ {
+ if (codeBaseUri == null) { Debug.Fail("codeBaseUri == null"); return false; }
+ lock (GlobalAssemblyCache.Lock)
+ {
+ if (!GlobalAssemblyCache.FusionLoaded)
+ {
+ GlobalAssemblyCache.FusionLoaded = true;
+ System.Reflection.Assembly systemAssembly = typeof(object).Assembly;
+ //^ assume systemAssembly != null && systemAssembly.Location != null;
+ string dir = Path.GetDirectoryName(systemAssembly.Location);
+ //^ assume dir != null;
+ GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll"));
+ }
+ IAssemblyEnum assemblyEnum;
+ int rc = GlobalAssemblyCache.CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0);
+ if (rc < 0 || assemblyEnum == null) return false;
+ IApplicationContext applicationContext;
+ IAssemblyName currentName;
+ while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0)
+ {
+ //^ assume currentName != null;
+ AssemblyName assemblyName = new AssemblyName(currentName);
+ string scheme = codeBaseUri.Scheme;
+ if (scheme != null && assemblyName.CodeBase.StartsWith(scheme))
+ {
+ try
+ {
+ Uri foundUri = new Uri(assemblyName.CodeBase);
+ if (codeBaseUri.Equals(foundUri)) return true;
+#if !FxCop
+ }
+ catch (Exception)
+ {
+#else
+ }finally{
+#endif
+ }
+ }
+ }
+ return false;
+ }
+ }
+ /// <summary>
+ /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy.
+ /// If the corresponding assembly is not in the GAC, null is returned.
+ /// </summary>
+ public static string GetLocation(AssemblyReference assemblyReference)
+ {
+ if (assemblyReference == null) { Debug.Fail("assemblyReference == null"); return null; }
+ lock (GlobalAssemblyCache.Lock)
+ {
+ if (!GlobalAssemblyCache.FusionLoaded)
+ {
+ GlobalAssemblyCache.FusionLoaded = true;
+ System.Reflection.Assembly systemAssembly = typeof(object).Assembly;
+ //^ assume systemAssembly != null && systemAssembly.Location != null;
+ string dir = Path.GetDirectoryName(systemAssembly.Location);
+ //^ assume dir != null;
+ GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll"));
+ }
+ IAssemblyEnum assemblyEnum;
+ CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0);
+ if (assemblyEnum == null) return null;
+ IApplicationContext applicationContext;
+ IAssemblyName currentName;
+ while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0)
+ {
+ //^ assume currentName != null;
+ AssemblyName aName = new AssemblyName(currentName);
+ if (assemblyReference.Matches(aName.Name, aName.Version, aName.Culture, aName.PublicKeyToken))
+ {
+ string codeBase = aName.CodeBase;
+ if (codeBase != null && codeBase.StartsWith("file:///"))
+ return codeBase.Substring(8);
+ return aName.GetLocation();
+ }
+ }
+ return null;
+ }
+ }
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
+ private static extern IntPtr LoadLibrary(string lpFileName);
+ [DllImport("fusion.dll", CharSet = CharSet.Auto)]
+ private static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum, IApplicationContext pAppCtx, IAssemblyName pName, uint dwFlags, int pvReserved);
+ private class ASM_CACHE
+ {
+ private ASM_CACHE() { }
+ public const uint ZAP = 1;
+ public const uint GAC = 2;
+ public const uint DOWNLOAD = 4;
+ }
+ }
+ internal class AssemblyName
+ {
+ IAssemblyName/*!*/ assemblyName;
+
+ internal AssemblyName(IAssemblyName/*!*/ assemblyName)
+ {
+ this.assemblyName = assemblyName;
+ //^ base();
+ }
+
+ internal string/*!*/ Name
+ {
+ //set {this.WriteString(ASM_NAME.NAME, value);}
+ get { return this.ReadString(ASM_NAME.NAME); }
+ }
+ internal Version Version
+ {
+ //set{
+ // if (value == null) throw new ArgumentNullException();
+ // this.WriteUInt16(ASM_NAME.MAJOR_VERSION, (ushort)value.Major);
+ // this.WriteUInt16(ASM_NAME.MINOR_VERSION, (ushort)value.Minor);
+ // this.WriteUInt16(ASM_NAME.BUILD_NUMBER, (ushort)value.Build);
+ // this.WriteUInt16(ASM_NAME.REVISION_NUMBER, (ushort)value.Revision);
+ //}
+ get
+ {
+ int major = this.ReadUInt16(ASM_NAME.MAJOR_VERSION);
+ int minor = this.ReadUInt16(ASM_NAME.MINOR_VERSION);
+ int build = this.ReadUInt16(ASM_NAME.BUILD_NUMBER);
+ int revision = this.ReadUInt16(ASM_NAME.REVISION_NUMBER);
+ return new Version(major, minor, build, revision);
+ }
+ }
+ internal string/*!*/ Culture
+ {
+ //set {this.WriteString(ASM_NAME.CULTURE, value);}
+ get { return this.ReadString(ASM_NAME.CULTURE); }
+ }
+ internal byte[]/*!*/ PublicKeyToken
+ {
+ //set {this.WriteBytes(ASM_NAME.PUBLIC_KEY_TOKEN, value); }
+ get { return this.ReadBytes(ASM_NAME.PUBLIC_KEY_TOKEN); }
+ }
+ internal string StrongName
+ {
+ get
+ {
+ uint size = 0;
+ this.assemblyName.GetDisplayName(null, ref size, (uint)AssemblyNameDisplayFlags.ALL);
+ if (size == 0) return "";
+ StringBuilder strongName = new StringBuilder((int)size);
+ this.assemblyName.GetDisplayName(strongName, ref size, (uint)AssemblyNameDisplayFlags.ALL);
+ return strongName.ToString();
+ }
+ }
+ internal string/*!*/ CodeBase
+ {
+ //set {this.WriteString(ASM_NAME.CODEBASE_URL, value);}
+ get { return this.ReadString(ASM_NAME.CODEBASE_URL); }
+ }
+ public override string ToString()
+ {
+ return this.StrongName;
+ }
+ internal string GetLocation()
+ {
+ IAssemblyCache assemblyCache;
+ CreateAssemblyCache(out assemblyCache, 0);
+ if (assemblyCache == null) return null;
+ ASSEMBLY_INFO assemblyInfo = new ASSEMBLY_INFO();
+ assemblyInfo.cbAssemblyInfo = (uint)Marshal.SizeOf(typeof(ASSEMBLY_INFO));
+ assemblyCache.QueryAssemblyInfo(ASSEMBLYINFO_FLAG.VALIDATE | ASSEMBLYINFO_FLAG.GETSIZE, this.StrongName, ref assemblyInfo);
+ if (assemblyInfo.cbAssemblyInfo == 0) return null;
+ assemblyInfo.pszCurrentAssemblyPathBuf = new string(new char[assemblyInfo.cchBuf]);
+ assemblyCache.QueryAssemblyInfo(ASSEMBLYINFO_FLAG.VALIDATE | ASSEMBLYINFO_FLAG.GETSIZE, this.StrongName, ref assemblyInfo);
+ String value = assemblyInfo.pszCurrentAssemblyPathBuf;
+ return value;
+ }
+ private string/*!*/ ReadString(uint assemblyNameProperty)
+ {
+ uint size = 0;
+ this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size);
+ if (size == 0 || size > Int16.MaxValue) return String.Empty;
+ IntPtr ptr = Marshal.AllocHGlobal((int)size);
+ this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size);
+ String str = Marshal.PtrToStringUni(ptr);
+ //^ assume str != null;
+ Marshal.FreeHGlobal(ptr);
+ return str;
+ }
+ private ushort ReadUInt16(uint assemblyNameProperty)
+ {
+ uint size = 0;
+ this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size);
+ IntPtr ptr = Marshal.AllocHGlobal((int)size);
+ this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size);
+ ushort value = (ushort)Marshal.ReadInt16(ptr);
+ Marshal.FreeHGlobal(ptr);
+ return value;
+ }
+ private byte[]/*!*/ ReadBytes(uint assemblyNameProperty)
+ {
+ uint size = 0;
+ this.assemblyName.GetProperty(assemblyNameProperty, IntPtr.Zero, ref size);
+ IntPtr ptr = Marshal.AllocHGlobal((int)size);
+ this.assemblyName.GetProperty(assemblyNameProperty, ptr, ref size);
+ byte[] value = new byte[(int)size];
+ Marshal.Copy(ptr, value, 0, (int)size);
+ Marshal.FreeHGlobal(ptr);
+ return value;
+ }
+
+ [DllImport("fusion.dll", CharSet = CharSet.Auto)]
+ private static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, uint dwReserved);
+ private class CREATE_ASM_NAME_OBJ_FLAGS
+ {
+ private CREATE_ASM_NAME_OBJ_FLAGS() { }
+ public const uint CANOF_PARSE_DISPLAY_NAME = 0x1;
+ public const uint CANOF_SET_DEFAULT_VALUES = 0x2;
+ }
+ private class ASM_NAME
+ {
+ private ASM_NAME() { }
+ public const uint PUBLIC_KEY = 0;
+ public const uint PUBLIC_KEY_TOKEN = 1;
+ public const uint HASH_VALUE = 2;
+ public const uint NAME = 3;
+ public const uint MAJOR_VERSION = 4;
+ public const uint MINOR_VERSION = 5;
+ public const uint BUILD_NUMBER = 6;
+ public const uint REVISION_NUMBER = 7;
+ public const uint CULTURE = 8;
+ public const uint PROCESSOR_ID_ARRAY = 9;
+ public const uint OSINFO_ARRAY = 10;
+ public const uint HASH_ALGID = 11;
+ public const uint ALIAS = 12;
+ public const uint CODEBASE_URL = 13;
+ public const uint CODEBASE_LASTMOD = 14;
+ public const uint NULL_PUBLIC_KEY = 15;
+ public const uint NULL_PUBLIC_KEY_TOKEN = 16;
+ public const uint CUSTOM = 17;
+ public const uint NULL_CUSTOM = 18;
+ public const uint MVID = 19;
+ public const uint _32_BIT_ONLY = 20;
+ }
+ [Flags]
+ internal enum AssemblyNameDisplayFlags
+ {
+ VERSION = 0x01,
+ CULTURE = 0x02,
+ PUBLIC_KEY_TOKEN = 0x04,
+ PROCESSORARCHITECTURE = 0x20,
+ RETARGETABLE = 0x80,
+ ALL = VERSION | CULTURE | PUBLIC_KEY_TOKEN | PROCESSORARCHITECTURE | RETARGETABLE
+ }
+ private class ASSEMBLYINFO_FLAG
+ {
+ private ASSEMBLYINFO_FLAG() { }
+ public const uint VALIDATE = 1;
+ public const uint GETSIZE = 2;
+ }
+ [StructLayout(LayoutKind.Sequential)]
+ private struct ASSEMBLY_INFO
+ {
+ public uint cbAssemblyInfo;
+ public uint dwAssemblyFlags;
+ public ulong uliAssemblySizeInKB;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string pszCurrentAssemblyPathBuf;
+ public uint cchBuf;
+ }
+ [ComImport(), Guid("E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ private interface IAssemblyCache
+ {
+ [PreserveSig()]
+ int UninstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, IntPtr pvReserved, int pulDisposition);
+ [PreserveSig()]
+ int QueryAssemblyInfo(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName, ref ASSEMBLY_INFO pAsmInfo);
+ [PreserveSig()]
+ int CreateAssemblyCacheItem(uint dwFlags, IntPtr pvReserved, out object ppAsmItem, [MarshalAs(UnmanagedType.LPWStr)] string pszAssemblyName);
+ [PreserveSig()]
+ int CreateAssemblyScavenger(out object ppAsmScavenger);
+ [PreserveSig()]
+ int InstallAssembly(uint dwFlags, [MarshalAs(UnmanagedType.LPWStr)] string pszManifestFilePath, IntPtr pvReserved);
+ }
+ }
+ [ComImport(), Guid("CD193BC0-B4BC-11D2-9833-00C04FC31D2E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IAssemblyName
+ {
+ [PreserveSig()]
+ int SetProperty(uint PropertyId, IntPtr pvProperty, uint cbProperty);
+ [PreserveSig()]
+ int GetProperty(uint PropertyId, IntPtr pvProperty, ref uint pcbProperty);
+ [PreserveSig()]
+ int Finalize();
+ [PreserveSig()]
+ int GetDisplayName(StringBuilder szDisplayName, ref uint pccDisplayName, uint dwDisplayFlags);
+ [PreserveSig()]
+ int BindToObject(object refIID, object pAsmBindSink, IApplicationContext pApplicationContext, [MarshalAs(UnmanagedType.LPWStr)] string szCodeBase, long llFlags, int pvReserved, uint cbReserved, out int ppv);
+ [PreserveSig()]
+ int GetName(out uint lpcwBuffer, out int pwzName);
+ [PreserveSig()]
+ int GetVersion(out uint pdwVersionHi, out uint pdwVersionLow);
+ [PreserveSig()]
+ int IsEqual(IAssemblyName pName, uint dwCmpFlags);
+ [PreserveSig()]
+ int Clone(out IAssemblyName pName);
+ }
+ [ComImport(), Guid("7C23FF90-33AF-11D3-95DA-00A024A85B51"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IApplicationContext
+ {
+ void SetContextNameObject(IAssemblyName pName);
+ void GetContextNameObject(out IAssemblyName ppName);
+ void Set([MarshalAs(UnmanagedType.LPWStr)] string szName, int pvValue, uint cbValue, uint dwFlags);
+ void Get([MarshalAs(UnmanagedType.LPWStr)] string szName, out int pvValue, ref uint pcbValue, uint dwFlags);
+ void GetDynamicDirectory(out int wzDynamicDir, ref uint pdwSize);
+ }
+ [ComImport(), Guid("21B8916C-F28E-11D2-A473-00C04F8EF448"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IAssemblyEnum
+ {
+ [PreserveSig()]
+ int GetNextAssembly(out IApplicationContext ppAppCtx, out IAssemblyName ppName, uint dwFlags);
+ [PreserveSig()]
+ int Reset();
+ [PreserveSig()]
+ int Clone(out IAssemblyEnum ppEnum);
+ }
+}
+#else
+//TODO: provide a way to query ROTOR GAC
+#endif
diff --git a/tools/Sandcastle/Source/CCI/CCI.csproj b/tools/Sandcastle/Source/CCI/CCI.csproj
new file mode 100644
index 0000000..ee69cae
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/CCI.csproj
@@ -0,0 +1,109 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{4CB332D6-976E-44F6-A320-A515A9D1D1D3}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CCI</RootNamespace>
+ <AssemblyName>CCI</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;WHIDBEY;WHIDBEYwithGenericsAndIEqualityComparer</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyCache.cs" />
+ <Compile Include="DoubleVisitor.cs" />
+ <Compile Include="Duplicator.cs" />
+ <Compile Include="ExceptionStrings.cs" />
+ <Compile Include="FastFileIO.cs" />
+ <Compile Include="ILGenerator.cs" />
+ <Compile Include="ListTemplate.cs" />
+ <Compile Include="MemoryMappedFile.cs" />
+ <Compile Include="Metadata.cs" />
+ <Compile Include="Nodes.cs" />
+ <Compile Include="OpCode.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Reader.cs" />
+ <Compile Include="Specializer.cs" />
+ <Compile Include="StandardIds.cs" />
+ <Compile Include="StandardVisitor.cs" />
+ <Compile Include="SystemTypes.cs" />
+ <Compile Include="Unstacker.cs" />
+ <Compile Include="Updater.cs" />
+ <Compile Include="Writer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="ExceptionStrings.resx">
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/CCI/CCI.subproj b/tools/Sandcastle/Source/CCI/CCI.subproj
new file mode 100644
index 0000000..a066834
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/CCI.subproj
@@ -0,0 +1,38 @@
+<Project MSBuildVersion="1.0" DefaultTargets="System.Compiler">
+ <ItemGroup>
+ <Item Type="CCISource" Include="CCI\System.Compiler\*.cs"/>
+ <Item Type="CCISource" Include="AssemblyKey.cs"/>
+ </ItemGroup>
+ <Target Name="System.Compiler" DependsOnTargets="PreBuild_CCI">
+ <Task Name="VersionTask" BuiltDir="$(builtdir)" TargetFiles="System.Compiler.dll">
+ <OutputItem TaskParameter="VersionedFiles" Type="CompilerTarget"/>
+ </Task>
+ <Task Name="VersionTask" BuiltDir="$(builtdir)" TargetFiles="@(CCIReference)">
+ <OutputItem TaskParameter="VersionedFiles" Type="CCI_ReferencePath"/>
+ </Task>
+ <Task Name="Net10Task" BuiltDir="$(builtdir)">
+ <OutputItem TaskParameter="CompilerConstant" Type="FrameworkConstant"/>
+ </Task>
+ <Task Name="Csc"
+ Sources="@(CCISource)"
+ References="@(CCI_ReferencePath)"
+ OutputAssembly="@(CompilerTarget)"
+ TargetType="library"
+ AllowUnsafeBlocks="true"
+ ToolPath="@(FrameworkLocation)"
+ EmitDebugInformation="true"
+ DefineConstants="TRACE;@(FrameworkConstant)"
+ />
+ </Target>
+ <Target Name="PreBuild_CCI" DependsOnTargets="FrameworkVersion">
+ <Task Name="VersionTask" BuiltDir="$(builtdir)">
+ <OutputItem TaskParameter="VersionedFiles" Type="TargetDir"/>
+ </Task>
+ <Task Name="Exec"
+ Command="if not exist @(TargetDir) md @(TargetDir)" />
+ <Task Name="Exec"
+ Command="if exist @(TargetDir)System.Compiler.dll sd edit @(TargetDir)System.Compiler.*"
+ />
+ </Target>
+
+</Project>
diff --git a/tools/Sandcastle/Source/CCI/DoubleVisitor.cs b/tools/Sandcastle/Source/CCI/DoubleVisitor.cs
new file mode 100644
index 0000000..0e81e51
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/DoubleVisitor.cs
@@ -0,0 +1,2617 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !MinimalReader
+using System;
+using System.Collections;
+using System.Diagnostics;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ /// <summary>
+ /// Base for all classes that process two IR trees, possibily transforming one of them.
+ /// </summary>
+ public abstract class DoubleVisitor
+ {
+ /// <summary>
+ /// Switches on node.NodeType to call a visitor method that has been specialized for node.
+ /// </summary>
+ /// <returns> Returns null if node1 is null. Otherwise returns an updated node (possibly a different object).</returns>
+ public abstract Node Visit(Node node1, Node node2);
+
+ /// <summary>
+ /// Transfers the state from one visitor to another. This enables separate visitor instances to cooperative process a single IR.
+ /// </summary>
+ public virtual void TransferStateTo(DoubleVisitor targetVisitor)
+ {
+ }
+ }
+
+ /// <summary>
+ /// Walks an IR, mutuating it into a new form
+ /// </summary>
+ public abstract class StandardDoubleVisitor : DoubleVisitor
+ {
+ public DoubleVisitor callingVisitor;
+
+ protected StandardDoubleVisitor()
+ {
+ }
+ protected StandardDoubleVisitor(DoubleVisitor callingVisitor)
+ {
+ this.callingVisitor = callingVisitor;
+ }
+ public virtual Node VisitUnknownNodeType(Node node1, Node node2)
+ {
+ if (node1 == null) { Debug.Fail(""); return null; }
+ DoubleVisitor visitor = this.GetVisitorFor(node1);
+ if (visitor == null) return node1;
+ if (this.callingVisitor != null)
+ //Allow specialized state (unknown to this visitor) to propagate all the way down to the new visitor
+ this.callingVisitor.TransferStateTo(visitor);
+ this.TransferStateTo(visitor);
+ node1 = visitor.Visit(node1, node2);
+ visitor.TransferStateTo(this);
+ if (this.callingVisitor != null)
+ //Propagate specialized state (unknown to this visitor) all the way up the chain
+ visitor.TransferStateTo(this.callingVisitor);
+ return node1;
+ }
+ public virtual DoubleVisitor GetVisitorFor(Node/*!*/ node1)
+ {
+ if (node1 == null) { Debug.Fail(""); return null; }
+ return (DoubleVisitor)node1.GetVisitorFor(this, this.GetType().Name);
+ }
+ public override Node Visit(Node node1, Node node2)
+ {
+ if (node1 == null) return null;
+ switch (node1.NodeType)
+ {
+ case NodeType.AddressDereference:
+ return this.VisitAddressDereference((AddressDereference)node1, node2 as AddressDereference);
+ case NodeType.AliasDefinition:
+ return this.VisitAliasDefinition((AliasDefinition)node1, node2 as AliasDefinition);
+ case NodeType.AnonymousNestedFunction:
+ return this.VisitAnonymousNestedFunction((AnonymousNestedFunction)node1, node2 as AnonymousNestedFunction);
+ case NodeType.ApplyToAll:
+ return this.VisitApplyToAll((ApplyToAll)node1, node2 as ApplyToAll);
+ case NodeType.Arglist:
+ return this.VisitExpression((Expression)node1, node2 as Expression);
+ case NodeType.ArrayType:
+ Debug.Assert(false); return null;
+ case NodeType.Assembly:
+ return this.VisitAssembly((AssemblyNode)node1, node2 as AssemblyNode);
+ case NodeType.AssemblyReference:
+ return this.VisitAssemblyReference((AssemblyReference)node1, node2 as AssemblyReference);
+ case NodeType.Assertion:
+ return this.VisitAssertion((Assertion)node1, node2 as Assertion);
+ case NodeType.Assumption:
+ return this.VisitAssumption((Assumption)node1, node2 as Assumption);
+ case NodeType.AssignmentExpression:
+ return this.VisitAssignmentExpression((AssignmentExpression)node1, node2 as AssignmentExpression);
+ case NodeType.AssignmentStatement:
+ return this.VisitAssignmentStatement((AssignmentStatement)node1, node2 as AssignmentStatement);
+ case NodeType.Attribute:
+ return this.VisitAttributeNode((AttributeNode)node1, node2 as AttributeNode);
+ case NodeType.Base:
+ return this.VisitBase((Base)node1, node2 as Base);
+ case NodeType.Block:
+ return this.VisitBlock((Block)node1, node2 as Block);
+ case NodeType.BlockExpression:
+ return this.VisitBlockExpression((BlockExpression)node1, node2 as BlockExpression);
+ case NodeType.Branch:
+ return this.VisitBranch((Branch)node1, node2 as Branch);
+ case NodeType.Compilation:
+ return this.VisitCompilation((Compilation)node1, node2 as Compilation);
+ case NodeType.CompilationUnit:
+ return this.VisitCompilationUnit((CompilationUnit)node1, node2 as CompilationUnit);
+ case NodeType.CompilationUnitSnippet:
+ return this.VisitCompilationUnitSnippet((CompilationUnitSnippet)node1, node2 as CompilationUnitSnippet);
+#if ExtendedRuntime
+ case NodeType.ConstrainedType:
+ return this.VisitConstrainedType((ConstrainedType)node1, node2 as ConstrainedType);
+#endif
+ case NodeType.Continue:
+ return this.VisitContinue((Continue)node1, node2 as Continue);
+ case NodeType.CurrentClosure:
+ return this.VisitCurrentClosure((CurrentClosure)node1, node2 as CurrentClosure);
+ case NodeType.DebugBreak:
+ return node1;
+ case NodeType.Call:
+ case NodeType.Calli:
+ case NodeType.Callvirt:
+ case NodeType.Jmp:
+ case NodeType.MethodCall:
+ return this.VisitMethodCall((MethodCall)node1, node2 as MethodCall);
+ case NodeType.Catch:
+ return this.VisitCatch((Catch)node1, node2 as Catch);
+ case NodeType.Class:
+ return this.VisitClass((Class)node1, node2 as Class);
+ case NodeType.CoerceTuple:
+ return this.VisitCoerceTuple((CoerceTuple)node1, node2 as CoerceTuple);
+ case NodeType.CollectionEnumerator:
+ return this.VisitCollectionEnumerator((CollectionEnumerator)node1, node2 as CollectionEnumerator);
+ case NodeType.Composition:
+ return this.VisitComposition((Composition)node1, node2 as Composition);
+ case NodeType.Construct:
+ return this.VisitConstruct((Construct)node1, node2 as Construct);
+ case NodeType.ConstructArray:
+ return this.VisitConstructArray((ConstructArray)node1, node2 as ConstructArray);
+ case NodeType.ConstructDelegate:
+ return this.VisitConstructDelegate((ConstructDelegate)node1, node2 as ConstructDelegate);
+ case NodeType.ConstructFlexArray:
+ return this.VisitConstructFlexArray((ConstructFlexArray)node1, node2 as ConstructFlexArray);
+ case NodeType.ConstructIterator:
+ return this.VisitConstructIterator((ConstructIterator)node1, node2 as ConstructIterator);
+ case NodeType.ConstructTuple:
+ return this.VisitConstructTuple((ConstructTuple)node1, node2 as ConstructTuple);
+ case NodeType.DelegateNode:
+ return this.VisitDelegateNode((DelegateNode)node1, node2 as DelegateNode);
+ case NodeType.DoWhile:
+ return this.VisitDoWhile((DoWhile)node1, node2 as DoWhile);
+ case NodeType.Dup:
+ return this.VisitExpression((Expression)node1, node2 as Expression);
+ case NodeType.EndFilter:
+ return this.VisitEndFilter((EndFilter)node1, node2 as EndFilter);
+ case NodeType.EndFinally:
+ return this.VisitEndFinally((EndFinally)node1, node2 as EndFinally);
+ case NodeType.EnumNode:
+ return this.VisitEnumNode((EnumNode)node1, node2 as EnumNode);
+ case NodeType.Event:
+ return this.VisitEvent((Event)node1, node2 as Event);
+#if ExtendedRuntime
+ case NodeType.EnsuresExceptional :
+ return this.VisitEnsuresExceptional((EnsuresExceptional)node1, node2 as EnsuresExceptional);
+#endif
+ case NodeType.Exit:
+ return this.VisitExit((Exit)node1, node2 as Exit);
+ case NodeType.Read:
+ case NodeType.Write:
+ return this.VisitExpose((Expose)node1, node2 as Expose);
+ case NodeType.ExpressionSnippet:
+ return this.VisitExpressionSnippet((ExpressionSnippet)node1, node2 as ExpressionSnippet);
+ case NodeType.ExpressionStatement:
+ return this.VisitExpressionStatement((ExpressionStatement)node1, node2 as ExpressionStatement);
+ case NodeType.FaultHandler:
+ return this.VisitFaultHandler((FaultHandler)node1, node2 as FaultHandler);
+ case NodeType.Field:
+ return this.VisitField((Field)node1, node2 as Field);
+ case NodeType.FieldInitializerBlock:
+ return this.VisitFieldInitializerBlock((FieldInitializerBlock)node1, node2 as FieldInitializerBlock);
+ case NodeType.Finally:
+ return this.VisitFinally((Finally)node1, node2 as Finally);
+ case NodeType.Filter:
+ return this.VisitFilter((Filter)node1, node2 as Filter);
+ case NodeType.Fixed:
+ return this.VisitFixed((Fixed)node1, node2 as Fixed);
+ case NodeType.For:
+ return this.VisitFor((For)node1, node2 as For);
+ case NodeType.ForEach:
+ return this.VisitForEach((ForEach)node1, node2 as ForEach);
+ case NodeType.FunctionDeclaration:
+ return this.VisitFunctionDeclaration((FunctionDeclaration)node1, node2 as FunctionDeclaration);
+ case NodeType.Goto:
+ return this.VisitGoto((Goto)node1, node2 as Goto);
+ case NodeType.GotoCase:
+ return this.VisitGotoCase((GotoCase)node1, node2 as GotoCase);
+ case NodeType.Identifier:
+ return this.VisitIdentifier((Identifier)node1, node2 as Identifier);
+ case NodeType.If:
+ return this.VisitIf((If)node1, node2 as If);
+ case NodeType.ImplicitThis:
+ return this.VisitImplicitThis((ImplicitThis)node1, node2 as ImplicitThis);
+ case NodeType.Indexer:
+ return this.VisitIndexer((Indexer)node1, node2 as Indexer);
+ case NodeType.InstanceInitializer:
+ return this.VisitInstanceInitializer((InstanceInitializer)node1, node2 as InstanceInitializer);
+ case NodeType.Interface:
+ return this.VisitInterface((Interface)node1, node2 as Interface);
+#if ExtendedRuntime
+ case NodeType.Invariant :
+ return this.VisitInvariant((Invariant)node1, node2 as Invariant);
+#endif
+ case NodeType.LabeledStatement:
+ return this.VisitLabeledStatement((LabeledStatement)node1, node2 as LabeledStatement);
+ case NodeType.Literal:
+ return this.VisitLiteral((Literal)node1, node2 as Literal);
+ case NodeType.Local:
+ return this.VisitLocal((Local)node1, node2 as Local);
+ case NodeType.LocalDeclaration:
+ return this.VisitLocalDeclaration((LocalDeclaration)node1, node2 as LocalDeclaration);
+ case NodeType.LocalDeclarationsStatement:
+ return this.VisitLocalDeclarationsStatement((LocalDeclarationsStatement)node1, node2 as LocalDeclarationsStatement);
+ case NodeType.Lock:
+ return this.VisitLock((Lock)node1, node2 as Lock);
+ case NodeType.LRExpression:
+ return this.VisitLRExpression((LRExpression)node1, node2 as LRExpression);
+ case NodeType.MemberBinding:
+ return this.VisitMemberBinding((MemberBinding)node1, node2 as MemberBinding);
+ case NodeType.Method:
+ return this.VisitMethod((Method)node1, node2 as Method);
+#if ExtendedRuntime
+ case NodeType.MethodContract :
+ return this.VisitMethodContract((MethodContract)node1, node2 as MethodContract);
+#endif
+ case NodeType.TemplateInstance:
+ return this.VisitTemplateInstance((TemplateInstance)node1, node2 as TemplateInstance);
+ case NodeType.StackAlloc:
+ return this.VisitStackAlloc((StackAlloc)node1, node2 as StackAlloc);
+ case NodeType.Module:
+ return this.VisitModule((Module)node1, node2 as Module);
+ case NodeType.ModuleReference:
+ return this.VisitModuleReference((ModuleReference)node1, node2 as ModuleReference);
+ case NodeType.NameBinding:
+ return this.VisitNameBinding((NameBinding)node1, node2 as NameBinding);
+ case NodeType.NamedArgument:
+ return this.VisitNamedArgument((NamedArgument)node1, node2 as NamedArgument);
+ case NodeType.Namespace:
+ return this.VisitNamespace((Namespace)node1, node2 as Namespace);
+ case NodeType.Nop:
+ return node1;
+#if ExtendedRuntime
+ case NodeType.EnsuresNormal :
+ return this.VisitEnsuresNormal((EnsuresNormal)node1, node2 as EnsuresNormal);
+ case NodeType.OldExpression :
+ return this.VisitOldExpression((OldExpression)node1, node2 as OldExpression);
+ case NodeType.RequiresOtherwise :
+ return this.VisitRequiresOtherwise((RequiresOtherwise)node1, node2 as RequiresOtherwise);
+ case NodeType.RequiresPlain :
+ return this.VisitRequiresPlain((RequiresPlain)node1, node2 as RequiresPlain);
+#endif
+ case NodeType.OptionalModifier:
+ case NodeType.RequiredModifier:
+ return this.VisitTypeModifier((TypeModifier)node1, node2 as TypeModifier);
+ case NodeType.Parameter:
+ return this.VisitParameter((Parameter)node1, node2 as Parameter);
+ case NodeType.Pop:
+ return this.VisitExpression((Expression)node1, node2 as Expression);
+ case NodeType.PrefixExpression:
+ return this.VisitPrefixExpression((PrefixExpression)node1, node2 as PrefixExpression);
+ case NodeType.PostfixExpression:
+ return this.VisitPostfixExpression((PostfixExpression)node1, node2 as PostfixExpression);
+ case NodeType.Property:
+ return this.VisitProperty((Property)node1, node2 as Property);
+ case NodeType.Quantifier:
+ return this.VisitQuantifier((Quantifier)node1, node2 as Quantifier);
+ case NodeType.Comprehension:
+ return this.VisitComprehension((Comprehension)node1, node2 as Comprehension);
+ case NodeType.ComprehensionBinding:
+ return this.VisitComprehensionBinding((ComprehensionBinding)node1, node2 as ComprehensionBinding);
+ case NodeType.QualifiedIdentifer:
+ return this.VisitQualifiedIdentifier((QualifiedIdentifier)node1, node2 as QualifiedIdentifier);
+ case NodeType.Rethrow:
+ case NodeType.Throw:
+ return this.VisitThrow((Throw)node1, node2 as Throw);
+ case NodeType.Return:
+ return this.VisitReturn((Return)node1, node2 as Return);
+ case NodeType.ResourceUse:
+ return this.VisitResourceUse((ResourceUse)node1, node2 as ResourceUse);
+ case NodeType.Repeat:
+ return this.VisitRepeat((Repeat)node1, node2 as Repeat);
+ case NodeType.SecurityAttribute:
+ return this.VisitSecurityAttribute((SecurityAttribute)node1, node2 as SecurityAttribute);
+ case NodeType.SetterValue:
+ return this.VisitSetterValue((SetterValue)node1, node2 as SetterValue);
+ case NodeType.StaticInitializer:
+ return this.VisitStaticInitializer((StaticInitializer)node1, node2 as StaticInitializer);
+ case NodeType.StatementSnippet:
+ return this.VisitStatementSnippet((StatementSnippet)node1, node2 as StatementSnippet);
+ case NodeType.Struct:
+ return this.VisitStruct((Struct)node1, node2 as Struct);
+ case NodeType.Switch:
+ return this.VisitSwitch((Switch)node1, node2 as Switch);
+ case NodeType.SwitchCase:
+ return this.VisitSwitchCase((SwitchCase)node1, node2 as SwitchCase);
+ case NodeType.SwitchInstruction:
+ return this.VisitSwitchInstruction((SwitchInstruction)node1, node2 as SwitchInstruction);
+ case NodeType.Typeswitch:
+ return this.VisitTypeswitch((Typeswitch)node1, node2 as Typeswitch);
+ case NodeType.TypeswitchCase:
+ return this.VisitTypeswitchCase((TypeswitchCase)node1, node2 as TypeswitchCase);
+ case NodeType.This:
+ return this.VisitThis((This)node1, node2 as This);
+ case NodeType.Try:
+ return this.VisitTry((Try)node1, node2 as Try);
+#if ExtendedRuntime
+ case NodeType.TupleType:
+ return this.VisitTupleType((TupleType)node1, node2 as TupleType);
+ case NodeType.TypeAlias:
+ return this.VisitTypeAlias((TypeAlias)node1, node2 as TypeAlias);
+ case NodeType.TypeIntersection:
+ return this.VisitTypeIntersection((TypeIntersection)node1, node2 as TypeIntersection);
+ case NodeType.TypeContract :
+ return this.VisitTypeContract((TypeContract)node1, node2 as TypeContract);
+#endif
+ case NodeType.TypeMemberSnippet:
+ return this.VisitTypeMemberSnippet((TypeMemberSnippet)node1, node2 as TypeMemberSnippet);
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ return this.VisitTypeParameter((TypeNode)node1, node2 as TypeNode);
+#if ExtendedRuntime
+ case NodeType.TypeUnion:
+ return this.VisitTypeUnion((TypeUnion)node1, node2 as TypeUnion);
+#endif
+ case NodeType.TypeReference:
+ return this.VisitTypeReference((TypeReference)node1, node2 as TypeReference);
+ case NodeType.UsedNamespace:
+ return this.VisitUsedNamespace((UsedNamespace)node1, node2 as UsedNamespace);
+ case NodeType.VariableDeclaration:
+ return this.VisitVariableDeclaration((VariableDeclaration)node1, node2 as VariableDeclaration);
+ case NodeType.While:
+ return this.VisitWhile((While)node1, node2 as While);
+ case NodeType.Yield:
+ return this.VisitYield((Yield)node1, node2 as Yield);
+
+ case NodeType.Conditional:
+ case NodeType.Cpblk:
+ case NodeType.Initblk:
+ return this.VisitTernaryExpression((TernaryExpression)node1, node2 as TernaryExpression);
+
+ case NodeType.Add:
+ case NodeType.Add_Ovf:
+ case NodeType.Add_Ovf_Un:
+ case NodeType.AddEventHandler:
+ case NodeType.And:
+ case NodeType.As:
+ case NodeType.Box:
+ case NodeType.Castclass:
+ case NodeType.Ceq:
+ case NodeType.Cgt:
+ case NodeType.Cgt_Un:
+ case NodeType.Clt:
+ case NodeType.Clt_Un:
+ case NodeType.Comma:
+ case NodeType.Div:
+ case NodeType.Div_Un:
+ case NodeType.Eq:
+ case NodeType.ExplicitCoercion:
+ case NodeType.Ge:
+ case NodeType.Gt:
+ case NodeType.Is:
+ case NodeType.Iff:
+ case NodeType.Implies:
+ case NodeType.Isinst:
+ case NodeType.Ldvirtftn:
+ case NodeType.Le:
+ case NodeType.LogicalAnd:
+ case NodeType.LogicalOr:
+ case NodeType.Lt:
+ case NodeType.Mkrefany:
+ case NodeType.Maplet:
+ case NodeType.Mul:
+ case NodeType.Mul_Ovf:
+ case NodeType.Mul_Ovf_Un:
+ case NodeType.Ne:
+ case NodeType.Or:
+ case NodeType.Range:
+ case NodeType.Refanyval:
+ case NodeType.Rem:
+ case NodeType.Rem_Un:
+ case NodeType.RemoveEventHandler:
+ case NodeType.Shl:
+ case NodeType.Shr:
+ case NodeType.Shr_Un:
+ case NodeType.Sub:
+ case NodeType.Sub_Ovf:
+ case NodeType.Sub_Ovf_Un:
+ case NodeType.Unbox:
+ case NodeType.UnboxAny:
+ case NodeType.Xor:
+ return this.VisitBinaryExpression((BinaryExpression)node1, node2 as BinaryExpression);
+
+ case NodeType.AddressOf:
+ case NodeType.OutAddress:
+ case NodeType.RefAddress:
+ case NodeType.Ckfinite:
+ case NodeType.Conv_I:
+ case NodeType.Conv_I1:
+ case NodeType.Conv_I2:
+ case NodeType.Conv_I4:
+ case NodeType.Conv_I8:
+ case NodeType.Conv_Ovf_I:
+ case NodeType.Conv_Ovf_I1:
+ case NodeType.Conv_Ovf_I1_Un:
+ case NodeType.Conv_Ovf_I2:
+ case NodeType.Conv_Ovf_I2_Un:
+ case NodeType.Conv_Ovf_I4:
+ case NodeType.Conv_Ovf_I4_Un:
+ case NodeType.Conv_Ovf_I8:
+ case NodeType.Conv_Ovf_I8_Un:
+ case NodeType.Conv_Ovf_I_Un:
+ case NodeType.Conv_Ovf_U:
+ case NodeType.Conv_Ovf_U1:
+ case NodeType.Conv_Ovf_U1_Un:
+ case NodeType.Conv_Ovf_U2:
+ case NodeType.Conv_Ovf_U2_Un:
+ case NodeType.Conv_Ovf_U4:
+ case NodeType.Conv_Ovf_U4_Un:
+ case NodeType.Conv_Ovf_U8:
+ case NodeType.Conv_Ovf_U8_Un:
+ case NodeType.Conv_Ovf_U_Un:
+ case NodeType.Conv_R4:
+ case NodeType.Conv_R8:
+ case NodeType.Conv_R_Un:
+ case NodeType.Conv_U:
+ case NodeType.Conv_U1:
+ case NodeType.Conv_U2:
+ case NodeType.Conv_U4:
+ case NodeType.Conv_U8:
+ case NodeType.Decrement:
+ case NodeType.DefaultValue:
+ case NodeType.Increment:
+ case NodeType.Ldftn:
+ case NodeType.Ldlen:
+ case NodeType.Ldtoken:
+ case NodeType.Localloc:
+ case NodeType.LogicalNot:
+ case NodeType.Neg:
+ case NodeType.Not:
+ case NodeType.Parentheses:
+ case NodeType.Refanytype:
+ case NodeType.Sizeof:
+ case NodeType.SkipCheck:
+ case NodeType.Typeof:
+ case NodeType.UnaryPlus:
+ return this.VisitUnaryExpression((UnaryExpression)node1, node2 as UnaryExpression);
+#if ExtendedRuntime
+ // query node1 types
+ case NodeType.QueryAggregate:
+ return this.VisitQueryAggregate((QueryAggregate)node1, node2 as QueryAggregate);
+ case NodeType.QueryAlias:
+ return this.VisitQueryAlias((QueryAlias)node1, node2 as QueryAlias);
+ case NodeType.QueryAll:
+ case NodeType.QueryAny:
+ return this.VisitQueryQuantifier((QueryQuantifier)node1, node2 as QueryQuantifier);
+ case NodeType.QueryAxis:
+ return this.VisitQueryAxis((QueryAxis)node1, node2 as QueryAxis);
+ case NodeType.QueryCommit:
+ return this.VisitQueryCommit((QueryCommit)node1, node2 as QueryCommit);
+ case NodeType.QueryContext:
+ return this.VisitQueryContext((QueryContext)node1, node2 as QueryContext);
+ case NodeType.QueryDelete:
+ return this.VisitQueryDelete((QueryDelete)node1, node2 as QueryDelete);
+ case NodeType.QueryDifference:
+ return this.VisitQueryDifference((QueryDifference)node1, node2 as QueryDifference);
+ case NodeType.QueryDistinct:
+ return this.VisitQueryDistinct((QueryDistinct)node1, node2 as QueryDistinct);
+ case NodeType.QueryExists:
+ return this.VisitQueryExists((QueryExists)node1, node2 as QueryExists);
+ case NodeType.QueryFilter:
+ return this.VisitQueryFilter((QueryFilter)node1, node2 as QueryFilter);
+ case NodeType.QueryGeneratedType:
+ return this.VisitQueryGeneratedType((QueryGeneratedType)node1, node2 as QueryGeneratedType);
+ case NodeType.QueryGroupBy:
+ return this.VisitQueryGroupBy((QueryGroupBy)node1, node2 as QueryGroupBy);
+ case NodeType.QueryInsert:
+ return this.VisitQueryInsert((QueryInsert)node1, node2 as QueryInsert);
+ case NodeType.QueryIntersection:
+ return this.VisitQueryIntersection((QueryIntersection)node1, node2 as QueryIntersection);
+ case NodeType.QueryIterator:
+ return this.VisitQueryIterator((QueryIterator)node1, node2 as QueryIterator);
+ case NodeType.QueryJoin:
+ return this.VisitQueryJoin((QueryJoin)node1, node2 as QueryJoin);
+ case NodeType.QueryLimit:
+ return this.VisitQueryLimit((QueryLimit)node1, node2 as QueryLimit);
+ case NodeType.QueryOrderBy:
+ return this.VisitQueryOrderBy((QueryOrderBy)node1, node2 as QueryOrderBy);
+ case NodeType.QueryOrderItem:
+ return this.VisitQueryOrderItem((QueryOrderItem)node1, node2 as QueryOrderItem);
+ case NodeType.QueryPosition:
+ return this.VisitQueryPosition((QueryPosition)node1, node2 as QueryPosition);
+ case NodeType.QueryProject:
+ return this.VisitQueryProject((QueryProject)node1, node2 as QueryProject);
+ case NodeType.QueryQuantifiedExpression:
+ return this.VisitQueryQuantifiedExpression((QueryQuantifiedExpression)node1, node2 as QueryQuantifiedExpression);
+ case NodeType.QueryRollback:
+ return this.VisitQueryRollback((QueryRollback)node1, node2 as QueryRollback);
+ case NodeType.QuerySelect:
+ return this.VisitQuerySelect((QuerySelect)node1, node2 as QuerySelect);
+ case NodeType.QuerySingleton:
+ return this.VisitQuerySingleton((QuerySingleton)node1, node2 as QuerySingleton);
+ case NodeType.QueryTransact:
+ return this.VisitQueryTransact((QueryTransact)node1, node2 as QueryTransact);
+ case NodeType.QueryTypeFilter:
+ return this.VisitQueryTypeFilter((QueryTypeFilter)node1, node2 as QueryTypeFilter);
+ case NodeType.QueryUnion:
+ return this.VisitQueryUnion((QueryUnion)node1, node2 as QueryUnion);
+ case NodeType.QueryUpdate:
+ return this.VisitQueryUpdate((QueryUpdate)node1, node2 as QueryUpdate);
+ case NodeType.QueryYielder:
+ return this.VisitQueryYielder((QueryYielder)node1, node2 as QueryYielder);
+#endif
+ default:
+ return this.VisitUnknownNodeType(node1, node2);
+ }
+ }
+ public virtual Expression VisitAddressDereference(AddressDereference addr1, AddressDereference addr2)
+ {
+ if (addr1 == null) return null;
+ if (addr2 == null)
+ addr1.Address = this.VisitExpression(addr1.Address, null);
+ else
+ addr1.Address = this.VisitExpression(addr1.Address, addr2.Address);
+ return addr1;
+ }
+ public virtual AliasDefinition VisitAliasDefinition(AliasDefinition aliasDefinition1, AliasDefinition aliasDefinition2)
+ {
+ if (aliasDefinition1 == null) return null;
+ if (aliasDefinition2 == null)
+ aliasDefinition1.AliasedType = this.VisitTypeReference(aliasDefinition1.AliasedType, null);
+ else
+ aliasDefinition1.AliasedType = this.VisitTypeReference(aliasDefinition1.AliasedType, aliasDefinition2.AliasedType);
+ return aliasDefinition1;
+ }
+ public virtual AliasDefinitionList VisitAliasDefinitionList(AliasDefinitionList aliasDefinitions1, AliasDefinitionList aliasDefinitions2)
+ {
+ if (aliasDefinitions1 == null) return null;
+ for (int i = 0, n = aliasDefinitions1.Count, m = aliasDefinitions2 == null ? 0 : aliasDefinitions2.Count; i < n; i++)
+ {
+ //^ assert aliasDefinitions2 != null;
+ if (i >= m)
+ aliasDefinitions1[i] = this.VisitAliasDefinition(aliasDefinitions1[i], null);
+ else
+ aliasDefinitions1[i] = this.VisitAliasDefinition(aliasDefinitions1[i], aliasDefinitions2[i]);
+ }
+ return aliasDefinitions1;
+ }
+ public virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func1, AnonymousNestedFunction func2)
+ {
+ if (func1 == null) return null;
+ if (func2 == null)
+ {
+ func1.Parameters = this.VisitParameterList(func1.Parameters, null);
+ func1.Body = this.VisitBlock(func1.Body, null);
+ }
+ else
+ {
+ func1.Parameters = this.VisitParameterList(func1.Parameters, func2.Parameters);
+ func1.Body = this.VisitBlock(func1.Body, func2.Body);
+ }
+ return func1;
+ }
+ public virtual Expression VisitApplyToAll(ApplyToAll applyToAll1, ApplyToAll applyToAll2)
+ {
+ if (applyToAll1 == null) return null;
+ if (applyToAll2 == null)
+ {
+ applyToAll1.Operand1 = this.VisitExpression(applyToAll1.Operand1, null);
+ applyToAll1.Operand2 = this.VisitExpression(applyToAll1.Operand2, null);
+ }
+ else
+ {
+ applyToAll1.Operand1 = this.VisitExpression(applyToAll1.Operand1, applyToAll2.Operand1);
+ applyToAll1.Operand2 = this.VisitExpression(applyToAll1.Operand2, applyToAll2.Operand2);
+ }
+ return applyToAll1;
+ }
+ public ArrayType VisitArrayType(ArrayType array1, ArrayType array2)
+ {
+ Debug.Assert(false, "An array type exists only at runtime. It should be referred to, but never visited.");
+ return null;
+ }
+ public virtual AssemblyNode VisitAssembly(AssemblyNode assembly1, AssemblyNode assembly2)
+ {
+ if (assembly1 == null) return null;
+ this.VisitModule(assembly1, assembly2);
+ if (assembly2 == null)
+ {
+ assembly1.ModuleAttributes = this.VisitAttributeList(assembly1.ModuleAttributes, null);
+ assembly1.SecurityAttributes = this.VisitSecurityAttributeList(assembly1.SecurityAttributes, null);
+ }
+ else
+ {
+ assembly1.ModuleAttributes = this.VisitAttributeList(assembly1.ModuleAttributes, assembly2.ModuleAttributes);
+ assembly1.SecurityAttributes = this.VisitSecurityAttributeList(assembly1.SecurityAttributes, assembly2.SecurityAttributes);
+ }
+ return assembly1;
+ }
+ public virtual AssemblyReference VisitAssemblyReference(AssemblyReference assemblyReference1, AssemblyReference assemblyReference2)
+ {
+ return assemblyReference1;
+ }
+ public virtual Statement VisitAssertion(Assertion assertion1, Assertion assertion2)
+ {
+ if (assertion1 == null) return null;
+ if (assertion2 == null)
+ assertion1.Condition = this.VisitExpression(assertion1.Condition, null);
+ else
+ assertion1.Condition = this.VisitExpression(assertion1.Condition, assertion2.Condition);
+ return assertion1;
+ }
+ public virtual Statement VisitAssumption(Assumption Assumption1, Assumption Assumption2)
+ {
+ if (Assumption1 == null) return null;
+ if (Assumption2 == null)
+ Assumption1.Condition = this.VisitExpression(Assumption1.Condition, null);
+ else
+ Assumption1.Condition = this.VisitExpression(Assumption1.Condition, Assumption2.Condition);
+ return Assumption1;
+ }
+ public virtual Expression VisitAssignmentExpression(AssignmentExpression assignment1, AssignmentExpression assignment2)
+ {
+ if (assignment1 == null) return null;
+ if (assignment2 == null)
+ assignment1.AssignmentStatement = (Statement)this.Visit(assignment1.AssignmentStatement, null);
+ else
+ assignment1.AssignmentStatement = (Statement)this.Visit(assignment1.AssignmentStatement, assignment2.AssignmentStatement);
+ return assignment1;
+ }
+ public virtual Statement VisitAssignmentStatement(AssignmentStatement assignment1, AssignmentStatement assignment2)
+ {
+ if (assignment1 == null) return null;
+ if (assignment2 == null)
+ {
+ assignment1.Target = this.VisitTargetExpression(assignment1.Target, null);
+ assignment1.Source = this.VisitExpression(assignment1.Source, null);
+ }
+ else
+ {
+ assignment1.Target = this.VisitTargetExpression(assignment1.Target, assignment2.Target);
+ assignment1.Source = this.VisitExpression(assignment1.Source, assignment2.Source);
+ }
+ return assignment1;
+ }
+ public virtual Expression VisitAttributeConstructor(AttributeNode attribute1, AttributeNode attribute2)
+ {
+ if (attribute1 == null) return null;
+ if (attribute2 == null)
+ return this.VisitExpression(attribute1.Constructor, null);
+ else
+ return this.VisitExpression(attribute1.Constructor, attribute2.Constructor);
+ }
+ public virtual AttributeNode VisitAttributeNode(AttributeNode attribute1, AttributeNode attribute2)
+ {
+ if (attribute1 == null) return null;
+ if (attribute2 == null)
+ {
+ attribute1.Constructor = this.VisitAttributeConstructor(attribute1, null);
+ attribute1.Expressions = this.VisitExpressionList(attribute1.Expressions, null);
+ }
+ else
+ {
+ attribute1.Constructor = this.VisitAttributeConstructor(attribute1, attribute2);
+ attribute1.Expressions = this.VisitExpressionList(attribute1.Expressions, attribute2.Expressions);
+ }
+ return attribute1;
+ }
+ public virtual AttributeList VisitAttributeList(AttributeList attributes1, AttributeList attributes2)
+ {
+ if (attributes1 == null) return null;
+ for (int i = 0, n = attributes1.Count, m = attributes2 == null ? 0 : attributes2.Count; i < n; i++)
+ {
+ //^ assert attributes2 != null;
+ if (i >= m)
+ attributes1[i] = this.VisitAttributeNode(attributes1[i], null);
+ else
+ attributes1[i] = this.VisitAttributeNode(attributes1[i], attributes2[i]);
+ }
+ return attributes1;
+ }
+ public virtual Expression VisitBase(Base Base1, Base Base2)
+ {
+ return Base1;
+ }
+ public virtual Expression VisitBinaryExpression(BinaryExpression binaryExpression1, BinaryExpression binaryExpression2)
+ {
+ if (binaryExpression1 == null) return null;
+ if (binaryExpression2 == null)
+ {
+ binaryExpression1.Operand1 = this.VisitExpression(binaryExpression1.Operand1, null);
+ binaryExpression1.Operand2 = this.VisitExpression(binaryExpression1.Operand2, null);
+ }
+ else
+ {
+ binaryExpression1.Operand1 = this.VisitExpression(binaryExpression1.Operand1, binaryExpression2.Operand1);
+ binaryExpression1.Operand2 = this.VisitExpression(binaryExpression1.Operand2, binaryExpression2.Operand2);
+ }
+ return binaryExpression1;
+ }
+ public virtual Block VisitBlock(Block block1, Block block2)
+ {
+ if (block1 == null) return null;
+ if (block2 == null)
+ block1.Statements = this.VisitStatementList(block1.Statements, null);
+ else
+ block1.Statements = this.VisitStatementList(block1.Statements, block2.Statements);
+ return block1;
+ }
+ public virtual Expression VisitBlockExpression(BlockExpression blockExpression1, BlockExpression blockExpression2)
+ {
+ if (blockExpression1 == null) return null;
+ if (blockExpression2 == null)
+ blockExpression1.Block = this.VisitBlock(blockExpression1.Block, null);
+ else
+ blockExpression1.Block = this.VisitBlock(blockExpression1.Block, blockExpression2.Block);
+ return blockExpression1;
+ }
+ public virtual BlockList VisitBlockList(BlockList blockList1, BlockList blockList2)
+ {
+ if (blockList1 == null) return null;
+ for (int i = 0, n = blockList1.Count, m = blockList2 == null ? 0 : blockList2.Count; i < n; i++)
+ {
+ //^ assert blockList2 != null;
+ if (i >= m)
+ blockList1[i] = this.VisitBlock(blockList1[i], null);
+ else
+ blockList1[i] = this.VisitBlock(blockList1[i], blockList2[i]);
+ }
+ return blockList1;
+ }
+ public virtual Statement VisitBranch(Branch branch1, Branch branch2)
+ {
+ if (branch1 == null) return null;
+ if (branch2 == null)
+ branch1.Condition = this.VisitExpression(branch1.Condition, null);
+ else
+ branch1.Condition = this.VisitExpression(branch1.Condition, branch2.Condition);
+ return branch1;
+ }
+ public virtual Statement VisitCatch(Catch Catch1, Catch Catch2)
+ {
+ if (Catch1 == null) return null;
+ if (Catch2 == null)
+ {
+ Catch1.Variable = this.VisitTargetExpression(Catch1.Variable, null);
+ Catch1.Type = this.VisitTypeReference(Catch1.Type, null);
+ Catch1.Block = this.VisitBlock(Catch1.Block, null);
+ }
+ else
+ {
+ Catch1.Variable = this.VisitTargetExpression(Catch1.Variable, Catch2.Variable);
+ Catch1.Type = this.VisitTypeReference(Catch1.Type, Catch2.Type);
+ Catch1.Block = this.VisitBlock(Catch1.Block, Catch2.Block);
+ }
+ return Catch1;
+ }
+ public virtual CatchList VisitCatchList(CatchList catchers1, CatchList catchers2)
+ {
+ if (catchers1 == null) return null;
+ for (int i = 0, n = catchers1.Count, m = catchers2 == null ? 0 : catchers2.Count; i < n; i++)
+ {
+ //^ assert catchers2 != null;
+ if (i >= m)
+ catchers1[i] = (Catch)this.VisitCatch(catchers1[i], null);
+ else
+ catchers1[i] = (Catch)this.VisitCatch(catchers1[i], catchers2[i]);
+ }
+ return catchers1;
+ }
+ public virtual Class VisitClass(Class Class1, Class Class2)
+ {
+ return (Class)this.VisitTypeNode(Class1, Class2);
+ }
+ public virtual Expression VisitCoerceTuple(CoerceTuple coerceTuple1, CoerceTuple coerceTuple2)
+ {
+ if (coerceTuple1 == null) return null;
+ if (coerceTuple2 == null)
+ coerceTuple1.OriginalTuple = this.VisitExpression(coerceTuple1.OriginalTuple, null);
+ else
+ coerceTuple1.OriginalTuple = this.VisitExpression(coerceTuple1.OriginalTuple, coerceTuple2.OriginalTuple);
+ return this.VisitConstructTuple(coerceTuple1, coerceTuple2);
+ }
+ public virtual CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce1, CollectionEnumerator ce2)
+ {
+ if (ce1 == null) return null;
+ if (ce2 == null)
+ ce1.Collection = this.VisitExpression(ce1.Collection, null);
+ else
+ ce1.Collection = this.VisitExpression(ce1.Collection, ce2.Collection);
+ return ce1;
+ }
+ public virtual Compilation VisitCompilation(Compilation compilation1, Compilation compilation2)
+ {
+ if (compilation1 == null) return null;
+ Module module1 = compilation1.TargetModule;
+ AssemblyNode assem1 = module1 as AssemblyNode;
+ Module module2 = compilation2 == null ? null : compilation2.TargetModule;
+ AssemblyNode assem2 = module2 as AssemblyNode;
+ if (module1 != null)
+ {
+ if (module2 == null)
+ module1.Attributes = this.VisitAttributeList(module1.Attributes, null);
+ else
+ module1.Attributes = this.VisitAttributeList(module1.Attributes, module2.Attributes);
+ }
+ if (assem1 != null)
+ {
+ if (assem2 == null)
+ assem1.ModuleAttributes = this.VisitAttributeList(assem1.ModuleAttributes, null);
+ else
+ assem1.ModuleAttributes = this.VisitAttributeList(assem1.ModuleAttributes, assem2.ModuleAttributes);
+ }
+ compilation1.CompilationUnits = this.VisitCompilationUnitList(compilation1.CompilationUnits, compilation2 == null ? null : compilation2.CompilationUnits);
+ return null;
+ }
+ public virtual CompilationUnit VisitCompilationUnit(CompilationUnit cUnit1, CompilationUnit cUnit2)
+ {
+ if (cUnit1 == null) return null;
+ cUnit1.Nodes = this.VisitNodeList(cUnit1.Nodes, cUnit2 == null ? null : cUnit2.Nodes);
+ return cUnit1;
+ }
+ public virtual CompilationUnitList VisitCompilationUnitList(CompilationUnitList cUnits1, CompilationUnitList cUnits2)
+ {
+ if (cUnits1 == null) return null;
+ for (int i = 0, n = cUnits1.Count, m = cUnits2 == null ? 0 : cUnits2.Count; i < n; i++)
+ {
+ //^ assert cUnits2 != null;
+ if (i >= m)
+ cUnits1[i] = (CompilationUnit)this.VisitCompilationUnit(cUnits1[i], null);
+ else
+ cUnits1[i] = (CompilationUnit)this.VisitCompilationUnit(cUnits1[i], cUnits2[i]);
+ }
+ return cUnits1;
+ }
+ public virtual CompilationUnitSnippet VisitCompilationUnitSnippet(CompilationUnitSnippet snippet1, CompilationUnitSnippet snippet2)
+ {
+ return snippet1;
+ }
+ public virtual Node VisitComposition(Composition comp1, Composition comp2)
+ {
+ if (comp1 == null) return null;
+ if (comp1.GetType() == typeof(Composition))
+ {
+ comp1.Expression = (Expression)this.Visit(comp1.Expression, comp2 == null ? null : comp2.Expression);
+ return comp1;
+ }
+ return this.VisitUnknownNodeType(comp1, comp2);
+ }
+ public virtual Expression VisitConstruct(Construct cons1, Construct cons2)
+ {
+ if (cons1 == null) return null;
+ if (cons2 == null)
+ {
+ cons1.Constructor = this.VisitExpression(cons1.Constructor, null);
+ cons1.Operands = this.VisitExpressionList(cons1.Operands, null);
+ cons1.Owner = this.VisitExpression(cons1.Owner, null);
+ }
+ else
+ {
+ cons1.Constructor = this.VisitExpression(cons1.Constructor, cons2.Constructor);
+ cons1.Operands = this.VisitExpressionList(cons1.Operands, cons2.Operands);
+ cons1.Owner = this.VisitExpression(cons1.Owner, cons2.Owner);
+ }
+ return cons1;
+ }
+ public virtual Expression VisitConstructArray(ConstructArray consArr1, ConstructArray consArr2)
+ {
+ if (consArr1 == null) return null;
+ if (consArr2 == null)
+ {
+ consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, null);
+ consArr1.Operands = this.VisitExpressionList(consArr1.Operands, null);
+ consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, null);
+ consArr1.Owner = this.VisitExpression(consArr1.Owner, null);
+ }
+ else
+ {
+ consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, consArr2.ElementType);
+ consArr1.Operands = this.VisitExpressionList(consArr1.Operands, consArr2.Operands);
+ consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, consArr2.Initializers);
+ consArr1.Owner = this.VisitExpression(consArr1.Owner, consArr2.Owner);
+ }
+ return consArr1;
+ }
+ public virtual Expression VisitConstructDelegate(ConstructDelegate consDelegate1, ConstructDelegate consDelegate2)
+ {
+ if (consDelegate1 == null) return null;
+ if (consDelegate2 == null)
+ {
+ consDelegate1.DelegateType = this.VisitTypeReference(consDelegate1.DelegateType, null);
+ consDelegate1.TargetObject = this.VisitExpression(consDelegate1.TargetObject, null);
+ }
+ else
+ {
+ consDelegate1.DelegateType = this.VisitTypeReference(consDelegate1.DelegateType, consDelegate2.DelegateType);
+ consDelegate1.TargetObject = this.VisitExpression(consDelegate1.TargetObject, consDelegate2.TargetObject);
+ }
+ return consDelegate1;
+ }
+ public virtual Expression VisitConstructFlexArray(ConstructFlexArray consArr1, ConstructFlexArray consArr2)
+ {
+ if (consArr1 == null) return null;
+ if (consArr2 == null)
+ {
+ consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, null);
+ consArr1.Operands = this.VisitExpressionList(consArr1.Operands, null);
+ consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, null);
+ }
+ else
+ {
+ consArr1.ElementType = this.VisitTypeReference(consArr1.ElementType, consArr2.ElementType);
+ consArr1.Operands = this.VisitExpressionList(consArr1.Operands, consArr2.Operands);
+ consArr1.Initializers = this.VisitExpressionList(consArr1.Initializers, consArr2.Initializers);
+ }
+ return consArr1;
+ }
+ public virtual Expression VisitConstructIterator(ConstructIterator consIterator1, ConstructIterator consIterator2)
+ {
+ return consIterator1;
+ }
+ public virtual Expression VisitConstructTuple(ConstructTuple consTuple1, ConstructTuple consTuple2)
+ {
+ if (consTuple1 == null) return null;
+ if (consTuple2 == null)
+ consTuple1.Fields = this.VisitFieldList(consTuple1.Fields, null);
+ else
+ consTuple1.Fields = this.VisitFieldList(consTuple1.Fields, consTuple2.Fields);
+ return consTuple1;
+ }
+#if ExtendedRuntime
+ public virtual TypeNode VisitConstrainedType(ConstrainedType cType1, ConstrainedType cType2){
+ if (cType1 == null) return null;
+ if (cType2 == null){
+ cType1.UnderlyingType = this.VisitTypeReference(cType1.UnderlyingType, null);
+ cType1.Constraint = this.VisitExpression(cType1.Constraint, null);
+ }else{
+ cType1.UnderlyingType = this.VisitTypeReference(cType1.UnderlyingType, cType2.UnderlyingType);
+ cType1.Constraint = this.VisitExpression(cType1.Constraint, cType2.Constraint);
+ }
+ return cType1;
+ }
+#endif
+ public virtual Statement VisitContinue(Continue Continue1, Continue Continue2)
+ {
+ return Continue1;
+ }
+ public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure1, CurrentClosure currentClosure2)
+ {
+ return currentClosure1;
+ }
+ public virtual DelegateNode VisitDelegateNode(DelegateNode delegateNode1, DelegateNode delegateNode2)
+ {
+ if (delegateNode1 == null) return null;
+ if (delegateNode2 == null)
+ {
+ delegateNode1 = (DelegateNode)this.VisitTypeNode(delegateNode1, null);
+ if (delegateNode1 == null) return null;
+ delegateNode1.Parameters = this.VisitParameterList(delegateNode1.Parameters, null);
+ delegateNode1.ReturnType = this.VisitTypeReference(delegateNode1.ReturnType, null);
+ }
+ else
+ {
+ delegateNode1 = (DelegateNode)this.VisitTypeNode(delegateNode1, delegateNode2);
+ if (delegateNode1 == null) return null;
+ delegateNode1.Parameters = this.VisitParameterList(delegateNode1.Parameters, delegateNode2.Parameters);
+ delegateNode1.ReturnType = this.VisitTypeReference(delegateNode1.ReturnType, delegateNode2.ReturnType);
+ }
+ return delegateNode1;
+ }
+ public virtual Statement VisitDoWhile(DoWhile doWhile1, DoWhile doWhile2)
+ {
+ if (doWhile1 == null) return null;
+ if (doWhile2 == null)
+ {
+ doWhile1.Invariants = this.VisitExpressionList(doWhile1.Invariants, null);
+ doWhile1.Body = this.VisitBlock(doWhile1.Body, null);
+ doWhile1.Condition = this.VisitExpression(doWhile1.Condition, null);
+ }
+ else
+ {
+ doWhile1.Invariants = this.VisitExpressionList(doWhile1.Invariants, doWhile2.Invariants);
+ doWhile1.Body = this.VisitBlock(doWhile1.Body, doWhile2.Body);
+ doWhile1.Condition = this.VisitExpression(doWhile1.Condition, doWhile2.Condition);
+ }
+ return doWhile1;
+ }
+ public virtual Statement VisitEndFilter(EndFilter endFilter1, EndFilter endFilter2)
+ {
+ if (endFilter1 == null) return null;
+ if (endFilter2 == null)
+ endFilter1.Value = this.VisitExpression(endFilter1.Value, null);
+ else
+ endFilter1.Value = this.VisitExpression(endFilter1.Value, endFilter2.Value);
+ return endFilter1;
+ }
+ public virtual Statement VisitEndFinally(EndFinally endFinally1, EndFinally endFinally2)
+ {
+ return endFinally1;
+ }
+#if ExtendedRuntime
+ public virtual EnsuresList VisitEnsuresList(EnsuresList ensures1, EnsuresList ensures2) {
+ if (ensures1 == null) return null;
+ for (int i = 0, n = ensures1.Count, m = ensures2 == null ? 0 : ensures2.Count; i < n; i++) {
+ //^ assert ensures2 != null;
+ if (i >= m)
+ ensures1[i] = (Ensures)this.Visit(ensures1[i], null);
+ else
+ ensures1[i] = (Ensures)this.Visit(ensures1[i], ensures2[i]);
+ }
+ return ensures1;
+ }
+#endif
+ public virtual EnumNode VisitEnumNode(EnumNode enumNode1, EnumNode enumNode2)
+ {
+ return (EnumNode)this.VisitTypeNode(enumNode1, enumNode2);
+ }
+ public virtual Event VisitEvent(Event evnt1, Event evnt2)
+ {
+ if (evnt1 == null) return null;
+ if (evnt2 == null)
+ {
+ evnt1.Attributes = this.VisitAttributeList(evnt1.Attributes, null);
+ evnt1.HandlerType = this.VisitTypeReference(evnt1.HandlerType, null);
+ }
+ else
+ {
+ evnt1.Attributes = this.VisitAttributeList(evnt1.Attributes, evnt2.Attributes);
+ evnt1.HandlerType = this.VisitTypeReference(evnt1.HandlerType, evnt2.HandlerType);
+ }
+ return evnt1;
+ }
+#if ExtendedRuntime
+ public virtual EnsuresExceptional VisitEnsuresExceptional(EnsuresExceptional exceptional1, EnsuresExceptional exceptional2) {
+ if (exceptional1 == null) return null;
+ if (exceptional2 == null) {
+ exceptional1.PostCondition = this.VisitExpression(exceptional1.PostCondition, null);
+ exceptional1.Type = this.VisitTypeReference(exceptional1.Type, null);
+ exceptional1.Variable = this.VisitExpression(exceptional1.Variable, null);
+ }else{
+ exceptional1.PostCondition = this.VisitExpression(exceptional1.PostCondition, exceptional2.PostCondition);
+ exceptional1.Type = this.VisitTypeReference(exceptional1.Type, exceptional2.Type);
+ exceptional1.Variable = this.VisitExpression(exceptional1.Variable, exceptional2.Variable);
+ }
+ return exceptional1;
+ }
+#endif
+ public virtual Statement VisitExit(Exit exit1, Exit exit2)
+ {
+ return exit1;
+ }
+
+ public virtual Statement VisitExpose(Expose expose1, Expose expose2)
+ {
+ if (expose1 == null) return null;
+ if (expose2 == null)
+ {
+ expose1.Instance = this.VisitExpression(expose1.Instance, null);
+ expose1.Body = this.VisitBlock(expose1.Body, null);
+ }
+ else
+ {
+ expose1.Instance = this.VisitExpression(expose1.Instance, expose1.Instance);
+ expose1.Body = this.VisitBlock(expose1.Body, expose2.Body);
+ }
+ return expose1;
+ }
+
+ public virtual Expression VisitExpression(Expression expression1, Expression expression2)
+ {
+ if (expression1 == null) return null;
+ switch (expression1.NodeType)
+ {
+ case NodeType.Dup:
+ case NodeType.Arglist:
+ return expression1;
+ case NodeType.Pop:
+ UnaryExpression uex1 = expression1 as UnaryExpression;
+ UnaryExpression uex2 = expression2 as UnaryExpression;
+ if (uex1 != null)
+ {
+ uex1.Operand = this.VisitExpression(uex1.Operand, uex2 == null ? null : uex2.Operand);
+ return uex1;
+ }
+ return expression1;
+ default:
+ return (Expression)this.Visit(expression1, expression2);
+ }
+ }
+ public virtual ExpressionList VisitExpressionList(ExpressionList list1, ExpressionList list2)
+ {
+ if (list1 == null) return null;
+ for (int i = 0, n = list1.Count, m = list2 == null ? 0 : list2.Count; i < n; i++)
+ {
+ //^ assert list2 != null;
+ if (i >= m)
+ list1[i] = (Expression)this.Visit(list1[i], null);
+ else
+ list1[i] = (Expression)this.Visit(list1[i], list2[i]);
+ }
+ return list1;
+ }
+ public virtual Expression VisitExpressionSnippet(ExpressionSnippet snippet1, ExpressionSnippet snippet2)
+ {
+ return snippet1;
+ }
+ public virtual Statement VisitExpressionStatement(ExpressionStatement statement1, ExpressionStatement statement2)
+ {
+ if (statement1 == null) return null;
+ if (statement2 == null)
+ statement1.Expression = this.VisitExpression(statement1.Expression, null);
+ else
+ statement1.Expression = this.VisitExpression(statement1.Expression, statement2.Expression);
+ return statement1;
+ }
+ public virtual Statement VisitFaultHandler(FaultHandler faultHandler1, FaultHandler faultHandler2)
+ {
+ if (faultHandler1 == null) return null;
+ if (faultHandler2 == null)
+ faultHandler1.Block = this.VisitBlock(faultHandler1.Block, null);
+ else
+ faultHandler1.Block = this.VisitBlock(faultHandler1.Block, faultHandler2.Block);
+ return faultHandler1;
+ }
+ public virtual FaultHandlerList VisitFaultHandlerList(FaultHandlerList faultHandlers1, FaultHandlerList faultHandlers2)
+ {
+ if (faultHandlers1 == null) return null;
+ for (int i = 0, n = faultHandlers1.Count, m = faultHandlers2 == null ? 0 : faultHandlers2.Count; i < n; i++)
+ {
+ //^ assert faultHandlers2 != null;
+ if (i >= m)
+ faultHandlers1[i] = (FaultHandler)this.VisitFaultHandler(faultHandlers1[i], null);
+ else
+ faultHandlers1[i] = (FaultHandler)this.VisitFaultHandler(faultHandlers1[i], faultHandlers2[i]);
+ }
+ return faultHandlers1;
+ }
+ public virtual Field VisitField(Field field1, Field field2)
+ {
+ if (field1 == null) return null;
+ if (field2 == null)
+ {
+ field1.Attributes = this.VisitAttributeList(field1.Attributes, null);
+ field1.Type = this.VisitTypeReference(field1.Type, null);
+ field1.Initializer = this.VisitExpression(field1.Initializer, null);
+ field1.ImplementedInterfaces = this.VisitInterfaceReferenceList(field1.ImplementedInterfaces, null);
+ }
+ else
+ {
+ field1.Attributes = this.VisitAttributeList(field1.Attributes, field2.Attributes);
+ field1.Type = this.VisitTypeReference(field1.Type, field2.Type);
+ field1.Initializer = this.VisitExpression(field1.Initializer, field2.Initializer);
+ field1.ImplementedInterfaces = this.VisitInterfaceReferenceList(field1.ImplementedInterfaces, field2.ImplementedInterfaces);
+ }
+ return field1;
+ }
+ public virtual Block VisitFieldInitializerBlock(FieldInitializerBlock block1, FieldInitializerBlock block2)
+ {
+ if (block1 == null) return null;
+ if (block2 == null)
+ block1.Type = this.VisitTypeReference(block1.Type, null);
+ else
+ block1.Type = this.VisitTypeReference(block1.Type, block2.Type);
+ return this.VisitBlock(block1, block2);
+ }
+ public virtual FieldList VisitFieldList(FieldList fields1, FieldList fields2)
+ {
+ if (fields1 == null) return null;
+ for (int i = 0, n = fields1.Count, m = fields2 == null ? 0 : fields2.Count; i < n; i++)
+ {
+ //^ assert fields2 != null;
+ if (i >= m)
+ fields1[i] = this.VisitField(fields1[i], null);
+ else
+ fields1[i] = this.VisitField(fields1[i], fields2[i]);
+ }
+ return fields1;
+ }
+ public virtual Statement VisitFilter(Filter filter1, Filter filter2)
+ {
+ if (filter1 == null) return null;
+ if (filter2 == null)
+ {
+ filter1.Expression = this.VisitExpression(filter1.Expression, null);
+ filter1.Block = this.VisitBlock(filter1.Block, null);
+ }
+ else
+ {
+ filter1.Expression = this.VisitExpression(filter1.Expression, filter2.Expression);
+ filter1.Block = this.VisitBlock(filter1.Block, filter2.Block);
+ }
+ return filter1;
+ }
+ public virtual FilterList VisitFilterList(FilterList filters1, FilterList filters2)
+ {
+ if (filters1 == null) return null;
+ for (int i = 0, n = filters1.Count, m = filters2 == null ? 0 : filters2.Count; i < n; i++)
+ {
+ //^ assert filters2 != null;
+ if (i >= m)
+ filters1[i] = (Filter)this.VisitFilter(filters1[i], null);
+ else
+ filters1[i] = (Filter)this.VisitFilter(filters1[i], filters2[i]);
+ }
+ return filters1;
+ }
+ public virtual Statement VisitFinally(Finally Finally1, Finally Finally2)
+ {
+ if (Finally1 == null) return null;
+ if (Finally2 == null)
+ Finally1.Block = this.VisitBlock(Finally1.Block, null);
+ else
+ Finally1.Block = this.VisitBlock(Finally1.Block, Finally2.Block);
+ return Finally1;
+ }
+ public virtual Statement VisitFixed(Fixed fixed1, Fixed fixed2)
+ {
+ if (fixed1 == null) return null;
+ if (fixed2 == null)
+ {
+ fixed1.Declarators = (Statement)this.Visit(fixed1.Declarators, null);
+ fixed1.Body = this.VisitBlock(fixed1.Body, null);
+ }
+ else
+ {
+ fixed1.Declarators = (Statement)this.Visit(fixed1.Declarators, fixed2.Declarators);
+ fixed1.Body = this.VisitBlock(fixed1.Body, fixed2.Body);
+ }
+ return fixed1;
+ }
+ public virtual Statement VisitFor(For For1, For For2)
+ {
+ if (For1 == null) return null;
+ if (For2 == null)
+ {
+ For1.Initializer = this.VisitStatementList(For1.Initializer, null);
+ For1.Invariants = this.VisitExpressionList(For1.Invariants, null);
+ For1.Condition = this.VisitExpression(For1.Condition, null);
+ For1.Incrementer = this.VisitStatementList(For1.Incrementer, null);
+ For1.Body = this.VisitBlock(For1.Body, null);
+ }
+ else
+ {
+ For1.Initializer = this.VisitStatementList(For1.Initializer, For2.Initializer);
+ For1.Invariants = this.VisitExpressionList(For1.Invariants, For2.Invariants);
+ For1.Condition = this.VisitExpression(For1.Condition, For2.Condition);
+ For1.Incrementer = this.VisitStatementList(For1.Incrementer, For2.Incrementer);
+ For1.Body = this.VisitBlock(For1.Body, For2.Body);
+ }
+ return For1;
+ }
+ public virtual Statement VisitForEach(ForEach forEach1, ForEach forEach2)
+ {
+ if (forEach1 == null) return null;
+ if (forEach2 == null)
+ {
+ forEach1.TargetVariableType = this.VisitTypeReference(forEach1.TargetVariableType, null);
+ forEach1.TargetVariable = this.VisitTargetExpression(forEach1.TargetVariable, null);
+ forEach1.SourceEnumerable = this.VisitExpression(forEach1.SourceEnumerable, null);
+ forEach1.InductionVariable = this.VisitTargetExpression(forEach1.InductionVariable, null);
+ forEach1.Invariants = this.VisitExpressionList(forEach1.Invariants, null);
+ forEach1.Body = this.VisitBlock(forEach1.Body, null);
+ }
+ else
+ {
+ forEach1.TargetVariableType = this.VisitTypeReference(forEach1.TargetVariableType, forEach2.TargetVariableType);
+ forEach1.TargetVariable = this.VisitTargetExpression(forEach1.TargetVariable, forEach2.TargetVariable);
+ forEach1.SourceEnumerable = this.VisitExpression(forEach1.SourceEnumerable, forEach2.SourceEnumerable);
+ forEach1.InductionVariable = this.VisitTargetExpression(forEach1.InductionVariable, forEach2.InductionVariable);
+ forEach1.Invariants = this.VisitExpressionList(forEach1.Invariants, forEach2.Invariants);
+ forEach1.Body = this.VisitBlock(forEach1.Body, forEach2.Body);
+ }
+ return forEach1;
+ }
+ public virtual Statement VisitFunctionDeclaration(FunctionDeclaration functionDeclaration1, FunctionDeclaration functionDeclaration2)
+ {
+ if (functionDeclaration1 == null) return null;
+ if (functionDeclaration2 == null)
+ {
+ functionDeclaration1.Parameters = this.VisitParameterList(functionDeclaration1.Parameters, null);
+ functionDeclaration1.ReturnType = this.VisitTypeReference(functionDeclaration1.ReturnType, null);
+ functionDeclaration1.Body = this.VisitBlock(functionDeclaration1.Body, null);
+ }
+ else
+ {
+ functionDeclaration1.Parameters = this.VisitParameterList(functionDeclaration1.Parameters, functionDeclaration2.Parameters);
+ functionDeclaration1.ReturnType = this.VisitTypeReference(functionDeclaration1.ReturnType, functionDeclaration2.ReturnType);
+ functionDeclaration1.Body = this.VisitBlock(functionDeclaration1.Body, functionDeclaration2.Body);
+ }
+ return functionDeclaration1;
+ }
+ public virtual Expression VisitTemplateInstance(TemplateInstance genericInstance1, TemplateInstance genericInstance2)
+ {
+ if (genericInstance1 == null) return null;
+ if (genericInstance2 == null)
+ {
+ genericInstance1.Expression = this.VisitExpression(genericInstance1.Expression, null);
+ genericInstance1.TypeArguments = this.VisitTypeReferenceList(genericInstance1.TypeArguments, null);
+ }
+ else
+ {
+ genericInstance1.Expression = this.VisitExpression(genericInstance1.Expression, genericInstance2.Expression);
+ genericInstance1.TypeArguments = this.VisitTypeReferenceList(genericInstance1.TypeArguments, genericInstance2.TypeArguments);
+ }
+ return genericInstance1;
+ }
+ public virtual Expression VisitStackAlloc(StackAlloc alloc1, StackAlloc alloc2)
+ {
+ if (alloc1 == null) return null;
+ if (alloc2 == null)
+ {
+ alloc1.ElementType = this.VisitTypeReference(alloc1.ElementType, null);
+ alloc1.NumberOfElements = this.VisitExpression(alloc1.NumberOfElements, null);
+ }
+ else
+ {
+ alloc1.ElementType = this.VisitTypeReference(alloc1.ElementType, alloc2.ElementType);
+ alloc1.NumberOfElements = this.VisitExpression(alloc1.NumberOfElements, alloc2.NumberOfElements);
+ }
+ return alloc1;
+ }
+ public virtual Statement VisitGoto(Goto Goto1, Goto Goto2)
+ {
+ return Goto1;
+ }
+ public virtual Statement VisitGotoCase(GotoCase gotoCase1, GotoCase gotoCase2)
+ {
+ if (gotoCase1 == null) return null;
+ if (gotoCase2 == null)
+ {
+ gotoCase1.CaseLabel = this.VisitExpression(gotoCase1.CaseLabel, null);
+ }
+ else
+ {
+ gotoCase1.CaseLabel = this.VisitExpression(gotoCase1.CaseLabel, gotoCase2.CaseLabel);
+ }
+ return gotoCase1;
+ }
+ public virtual Expression VisitIdentifier(Identifier identifier1, Identifier identifier2)
+ {
+ return identifier1;
+ }
+ public virtual Statement VisitIf(If If1, If If2)
+ {
+ if (If1 == null) return null;
+ if (If2 == null)
+ {
+ If1.Condition = this.VisitExpression(If1.Condition, null);
+ If1.TrueBlock = this.VisitBlock(If1.TrueBlock, null);
+ If1.FalseBlock = this.VisitBlock(If1.FalseBlock, null);
+ }
+ else
+ {
+ If1.Condition = this.VisitExpression(If1.Condition, If2.Condition);
+ If1.TrueBlock = this.VisitBlock(If1.TrueBlock, If2.TrueBlock);
+ If1.FalseBlock = this.VisitBlock(If1.FalseBlock, If2.FalseBlock);
+ }
+ return If1;
+ }
+ public virtual Expression VisitImplicitThis(ImplicitThis implicitThis1, ImplicitThis implicitThis2)
+ {
+ return implicitThis1;
+ }
+ public virtual Expression VisitIndexer(Indexer indexer1, Indexer indexer2)
+ {
+ if (indexer1 == null) return null;
+ if (indexer2 == null)
+ {
+ indexer1.Object = this.VisitExpression(indexer1.Object, null);
+ indexer1.Operands = this.VisitExpressionList(indexer1.Operands, null);
+ }
+ else
+ {
+ indexer1.Object = this.VisitExpression(indexer1.Object, indexer2.Object);
+ indexer1.Operands = this.VisitExpressionList(indexer1.Operands, indexer2.Operands);
+ }
+ return indexer1;
+ }
+ public virtual Interface VisitInterface(Interface Interface1, Interface Interface2)
+ {
+ return (Interface)this.VisitTypeNode(Interface1, Interface2);
+ }
+ public virtual Interface VisitInterfaceReference(Interface Interface1, Interface Interface2)
+ {
+ return (Interface)this.VisitTypeReference(Interface1, Interface2);
+ }
+ public virtual InterfaceList VisitInterfaceReferenceList(InterfaceList interfaceReferences1, InterfaceList interfaceReferences2)
+ {
+ if (interfaceReferences1 == null) return null;
+ for (int i = 0, n = interfaceReferences1.Count, m = interfaceReferences2 == null ? 0 : interfaceReferences2.Count; i < n; i++)
+ {
+ //^ assert interfaceReferences2 != null;
+ if (i >= m)
+ interfaceReferences1[i] = this.VisitInterfaceReference(interfaceReferences1[i], null);
+ else
+ interfaceReferences1[i] = this.VisitInterfaceReference(interfaceReferences1[i], interfaceReferences2[i]);
+ }
+ return interfaceReferences1;
+ }
+#if ExtendedRuntime
+ public virtual Invariant VisitInvariant(Invariant invariant1, Invariant invariant2){
+ if (invariant1 == null) return null;
+ if (invariant2 == null){
+ invariant1.Condition = this.VisitExpression(invariant1.Condition, null);
+ }else{
+ invariant1.Condition = this.VisitExpression(invariant1.Condition, invariant2.Condition);
+ }
+ return invariant1;
+ }
+ public virtual InvariantList VisitInvariantList(InvariantList Invariants1, InvariantList Invariants2){
+ if (Invariants1 == null) return null;
+ for (int i = 0, n = Invariants1.Count, m = Invariants2 == null ? 0 : Invariants2.Count; i < n; i++){
+ //^ assert Invariants2 != null;
+ if (i >= m)
+ Invariants1[i] = this.VisitInvariant(Invariants1[i], null);
+ else
+ Invariants1[i] = this.VisitInvariant(Invariants1[i], Invariants2[i]);
+ }
+ return Invariants1;
+ }
+#endif
+ public virtual InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons1, InstanceInitializer cons2)
+ {
+ return (InstanceInitializer)this.VisitMethod(cons1, cons2);
+ }
+ public virtual Statement VisitLabeledStatement(LabeledStatement lStatement1, LabeledStatement lStatement2)
+ {
+ if (lStatement1 == null) return null;
+ if (lStatement2 == null)
+ lStatement1.Statement = (Statement)this.Visit(lStatement1.Statement, null);
+ else
+ lStatement1.Statement = (Statement)this.Visit(lStatement1.Statement, lStatement2.Statement);
+ return lStatement1;
+ }
+ public virtual Expression VisitLiteral(Literal literal1, Literal literal2)
+ {
+ return literal1;
+ }
+ public virtual Expression VisitLocal(Local local1, Local local2)
+ {
+ if (local1 == null) return null;
+ if (local2 == null)
+ local1.Type = this.VisitTypeReference(local1.Type, null);
+ else
+ local1.Type = this.VisitTypeReference(local1.Type, local2.Type);
+ return local1;
+ }
+ public virtual LocalDeclaration VisitLocalDeclaration(LocalDeclaration localDeclaration1, LocalDeclaration localDeclaration2)
+ {
+ if (localDeclaration1 == null) return null;
+ if (localDeclaration2 == null)
+ localDeclaration1.InitialValue = this.VisitExpression(localDeclaration1.InitialValue, null);
+ else
+ localDeclaration1.InitialValue = this.VisitExpression(localDeclaration1.InitialValue, localDeclaration2.InitialValue);
+ return localDeclaration1;
+ }
+ public virtual LocalDeclarationList VisitLocalDeclarationList(LocalDeclarationList localDeclarations1, LocalDeclarationList localDeclarations2)
+ {
+ if (localDeclarations1 == null) return null;
+ for (int i = 0, n = localDeclarations1.Count, m = localDeclarations2 == null ? 0 : localDeclarations2.Count; i < n; i++)
+ {
+ //^ assert localDeclarations2 != null;
+ if (i >= m)
+ localDeclarations1[i] = this.VisitLocalDeclaration(localDeclarations1[i], null);
+ else
+ localDeclarations1[i] = this.VisitLocalDeclaration(localDeclarations1[i], localDeclarations2[i]);
+ }
+ return localDeclarations1;
+ }
+ public virtual Statement VisitLocalDeclarationsStatement(LocalDeclarationsStatement localDeclarations1, LocalDeclarationsStatement localDeclarations2)
+ {
+ if (localDeclarations1 == null) return null;
+ if (localDeclarations2 == null)
+ {
+ localDeclarations1.Type = this.VisitTypeReference(localDeclarations1.Type, null);
+ localDeclarations1.Declarations = this.VisitLocalDeclarationList(localDeclarations1.Declarations, null);
+ }
+ else
+ {
+ localDeclarations1.Type = this.VisitTypeReference(localDeclarations1.Type, localDeclarations2.Type);
+ localDeclarations1.Declarations = this.VisitLocalDeclarationList(localDeclarations1.Declarations, localDeclarations2.Declarations);
+ }
+ return localDeclarations1;
+ }
+ public virtual Statement VisitLock(Lock lock1, Lock lock2)
+ {
+ if (lock1 == null) return null;
+ if (lock2 == null)
+ {
+ lock1.Guard = this.VisitExpression(lock1.Guard, null);
+ lock1.Body = this.VisitBlock(lock1.Body, null);
+ }
+ else
+ {
+ lock1.Guard = this.VisitExpression(lock1.Guard, lock2.Guard);
+ lock1.Body = this.VisitBlock(lock1.Body, lock2.Body);
+ }
+ return lock1;
+ }
+ public virtual Expression VisitLRExpression(LRExpression expr1, LRExpression expr2)
+ {
+ if (expr1 == null) return null;
+ if (expr2 == null)
+ expr1.Expression = this.VisitExpression(expr1.Expression, null);
+ else
+ expr1.Expression = this.VisitExpression(expr1.Expression, expr2.Expression);
+ return expr1;
+ }
+ public virtual Expression VisitMemberBinding(MemberBinding memberBinding1, MemberBinding memberBinding2)
+ {
+ if (memberBinding1 == null) return null;
+ if (memberBinding2 == null)
+ memberBinding1.TargetObject = this.VisitExpression(memberBinding1.TargetObject, null);
+ else
+ memberBinding1.TargetObject = this.VisitExpression(memberBinding1.TargetObject, memberBinding2.TargetObject);
+ return memberBinding1;
+ }
+ public virtual MemberList VisitMemberList(MemberList members1, MemberList members2)
+ {
+ if (members1 == null) return null;
+ for (int i = 0, n = members1.Count, m = members2 == null ? 0 : members2.Count; i < n; i++)
+ {
+ //^ assert members2 != null;
+ if (i >= m)
+ members1[i] = (Member)this.Visit(members1[i], null);
+ else
+ members1[i] = (Member)this.Visit(members1[i], members2[i]);
+ }
+ return members1;
+ }
+ public virtual Method VisitMethod(Method method1, Method method2)
+ {
+ if (method1 == null) return null;
+ if (method2 == null)
+ {
+ method1.Attributes = this.VisitAttributeList(method1.Attributes, null);
+ method1.ReturnAttributes = this.VisitAttributeList(method1.ReturnAttributes, null);
+ method1.SecurityAttributes = this.VisitSecurityAttributeList(method1.SecurityAttributes, null);
+ method1.ReturnType = this.VisitTypeReference(method1.ReturnType, null);
+ method1.ImplementedTypes = this.VisitTypeReferenceList(method1.ImplementedTypes, null);
+ method1.Parameters = this.VisitParameterList(method1.Parameters, null);
+ method1.Body = this.VisitBlock(method1.Body, null);
+ }
+ else
+ {
+ method1.Attributes = this.VisitAttributeList(method1.Attributes, method2.Attributes);
+ method1.ReturnAttributes = this.VisitAttributeList(method1.ReturnAttributes, method2.ReturnAttributes);
+ method1.SecurityAttributes = this.VisitSecurityAttributeList(method1.SecurityAttributes, method2.SecurityAttributes);
+ method1.ReturnType = this.VisitTypeReference(method1.ReturnType, method2.ReturnType);
+ method1.ImplementedTypes = this.VisitTypeReferenceList(method1.ImplementedTypes, method2.ImplementedTypes);
+ method1.Parameters = this.VisitParameterList(method1.Parameters, method2.Parameters);
+#if ExtendedRuntime
+ method1.Contract = this.VisitMethodContract(method1.Contract, method2.Contract);
+#endif
+ method1.Body = this.VisitBlock(method1.Body, method2.Body);
+ }
+ return method1;
+ }
+ public virtual Expression VisitMethodCall(MethodCall call1, MethodCall call2)
+ {
+ if (call1 == null) return null;
+ if (call2 == null)
+ {
+ call1.Callee = this.VisitExpression(call1.Callee, null);
+ call1.Operands = this.VisitExpressionList(call1.Operands, null);
+ }
+ else
+ {
+ call1.Callee = this.VisitExpression(call1.Callee, call2.Callee);
+ call1.Operands = this.VisitExpressionList(call1.Operands, call2.Operands);
+ }
+ return call1;
+ }
+#if ExtendedRuntime
+ public virtual MethodContract VisitMethodContract(MethodContract contract1, MethodContract contract2) {
+ if (contract1 == null) return null;
+ if (contract2 == null) {
+ // don't visit contract.DeclaringMethod
+ // don't visit contract.OverriddenMethods
+ contract1.Requires = this.VisitRequiresList(contract1.Requires, null);
+ contract1.Ensures = this.VisitEnsuresList(contract1.Ensures, null);
+ contract1.Modifies = this.VisitExpressionList(contract1.Modifies, null);
+ }else{
+ // don't visit contract.DeclaringMethod
+ // don't visit contract.OverriddenMethods
+ contract1.Requires = this.VisitRequiresList(contract1.Requires,contract2.Requires);
+ contract1.Ensures = this.VisitEnsuresList(contract1.Ensures,contract2.Ensures);
+ contract1.Modifies = this.VisitExpressionList(contract1.Modifies,contract2.Modifies);
+ }
+ return contract1;
+ }
+#endif
+ public virtual Module VisitModule(Module module1, Module module2)
+ {
+ if (module1 == null) return null;
+ if (module2 == null)
+ {
+ module1.Attributes = this.VisitAttributeList(module1.Attributes, null);
+ module1.Types = this.VisitTypeNodeList(module1.Types, null);
+ }
+ else
+ {
+ module1.Attributes = this.VisitAttributeList(module1.Attributes, module2.Attributes);
+ module1.Types = this.VisitTypeNodeList(module1.Types, module2.Types);
+ }
+ return module1;
+ }
+ public virtual ModuleReference VisitModuleReference(ModuleReference moduleReference1, ModuleReference moduleReference2)
+ {
+ return moduleReference1;
+ }
+ public virtual Expression VisitNameBinding(NameBinding nameBinding1, NameBinding nameBinding2)
+ {
+ return nameBinding1;
+ }
+ public virtual Expression VisitNamedArgument(NamedArgument namedArgument1, NamedArgument namedArgument2)
+ {
+ if (namedArgument1 == null) return null;
+ if (namedArgument2 == null)
+ namedArgument1.Value = this.VisitExpression(namedArgument1.Value, null);
+ else
+ namedArgument1.Value = this.VisitExpression(namedArgument1.Value, namedArgument2.Value);
+ return namedArgument1;
+ }
+ public virtual Namespace VisitNamespace(Namespace nspace1, Namespace nspace2)
+ {
+ if (nspace1 == null) return null;
+ if (nspace2 == null)
+ {
+ nspace1.AliasDefinitions = this.VisitAliasDefinitionList(nspace1.AliasDefinitions, null);
+ nspace1.UsedNamespaces = this.VisitUsedNamespaceList(nspace1.UsedNamespaces, null);
+ nspace1.Attributes = this.VisitAttributeList(nspace1.Attributes, null);
+ nspace1.Types = this.VisitTypeNodeList(nspace1.Types, null);
+ nspace1.NestedNamespaces = this.VisitNamespaceList(nspace1.NestedNamespaces, null);
+ }
+ else
+ {
+ nspace1.AliasDefinitions = this.VisitAliasDefinitionList(nspace1.AliasDefinitions, nspace2.AliasDefinitions);
+ nspace1.UsedNamespaces = this.VisitUsedNamespaceList(nspace1.UsedNamespaces, nspace2.UsedNamespaces);
+ nspace1.Attributes = this.VisitAttributeList(nspace1.Attributes, nspace2.Attributes);
+ nspace1.Types = this.VisitTypeNodeList(nspace1.Types, nspace2.Types);
+ nspace1.NestedNamespaces = this.VisitNamespaceList(nspace1.NestedNamespaces, nspace2.NestedNamespaces);
+ }
+ return nspace1;
+ }
+ public virtual NamespaceList VisitNamespaceList(NamespaceList namespaces1, NamespaceList namespaces2)
+ {
+ if (namespaces1 == null) return null;
+ for (int i = 0, n = namespaces1.Count, m = namespaces2 == null ? 0 : namespaces2.Count; i < n; i++)
+ {
+ //^ assert namespaces2 != null;
+ if (i >= m)
+ namespaces1[i] = this.VisitNamespace(namespaces1[i], null);
+ else
+ namespaces1[i] = this.VisitNamespace(namespaces1[i], namespaces2[i]);
+ }
+ return namespaces1;
+ }
+ public virtual NodeList VisitNodeList(NodeList nodes1, NodeList nodes2)
+ {
+ if (nodes1 == null) return null;
+ for (int i = 0, n = nodes1.Count, m = nodes2 == null ? 0 : nodes2.Count; i < n; i++)
+ {
+ //^ assert nodes2 != null;
+ if (i >= m)
+ nodes1[i] = (CompilationUnit)this.Visit(nodes1[i], null);
+ else
+ nodes1[i] = (CompilationUnit)this.Visit(nodes1[i], nodes2[i]);
+ }
+ return nodes1;
+ }
+#if ExtendedRuntime
+ public virtual EnsuresNormal VisitEnsuresNormal(EnsuresNormal normal1, EnsuresNormal normal2) {
+ if (normal1 == null) return null;
+ if (normal2 == null)
+ normal1.PostCondition = this.VisitExpression(normal1.PostCondition, null);
+ else
+ normal1.PostCondition = this.VisitExpression(normal1.PostCondition, normal2.PostCondition);
+ return normal1;
+ }
+ public virtual Expression VisitOldExpression(OldExpression oldExpression1, OldExpression oldExpression2) {
+ if (oldExpression1 == null) return null;
+ if (oldExpression2 == null)
+ oldExpression1.expression = this.VisitExpression(oldExpression1.expression, null);
+ else
+ oldExpression1.expression = this.VisitExpression(oldExpression1.expression, oldExpression2.expression);
+ return oldExpression1;
+ }
+ public virtual RequiresOtherwise VisitRequiresOtherwise(RequiresOtherwise otherwise1, RequiresOtherwise otherwise2) {
+ if (otherwise1 == null) return null;
+ if (otherwise2 == null) {
+ otherwise1.Condition = this.VisitExpression(otherwise1.Condition, null);
+ otherwise1.ThrowException = this.VisitExpression(otherwise1.ThrowException, null);
+ }else{
+ otherwise1.Condition = this.VisitExpression(otherwise1.Condition, otherwise2.Condition);
+ otherwise1.ThrowException = this.VisitExpression(otherwise1.ThrowException, otherwise2.ThrowException);
+ }
+ return otherwise1;
+ }
+#endif
+ public virtual Expression VisitParameter(Parameter parameter1, Parameter parameter2)
+ {
+ if (parameter1 == null) return null;
+ if (parameter2 == null)
+ {
+ parameter1.Attributes = this.VisitAttributeList(parameter1.Attributes, null);
+ parameter1.Type = this.VisitTypeReference(parameter1.Type, null);
+ parameter1.DefaultValue = this.VisitExpression(parameter1.DefaultValue, null);
+ }
+ else
+ {
+ parameter1.Attributes = this.VisitAttributeList(parameter1.Attributes, parameter2.Attributes);
+ parameter1.Type = this.VisitTypeReference(parameter1.Type, parameter2.Type);
+ parameter1.DefaultValue = this.VisitExpression(parameter1.DefaultValue, parameter2.DefaultValue);
+ }
+ return parameter1;
+ }
+ public virtual ParameterList VisitParameterList(ParameterList parameterList1, ParameterList parameterList2)
+ {
+ if (parameterList1 == null) return null;
+ for (int i = 0, n = parameterList1.Count, m = parameterList2 == null ? 0 : parameterList2.Count; i < n; i++)
+ {
+ //^ assert parameterList2 != null;
+ if (i >= m)
+ parameterList1[i] = (Parameter)this.VisitParameter(parameterList1[i], null);
+ else
+ parameterList1[i] = (Parameter)this.VisitParameter(parameterList1[i], parameterList2[i]);
+ }
+ return parameterList1;
+ }
+#if ExtendedRuntime
+ public virtual RequiresPlain VisitRequiresPlain(RequiresPlain plain1, RequiresPlain plain2) {
+ if (plain1 == null) return null;
+ if (plain2 == null)
+ plain1.Condition = this.VisitExpression(plain1.Condition, null);
+ else
+ plain1.Condition = this.VisitExpression(plain1.Condition, plain2.Condition);
+ return plain1;
+ }
+#endif
+ public virtual Expression VisitPrefixExpression(PrefixExpression pExpr1, PrefixExpression pExpr2)
+ {
+ if (pExpr1 == null) return null;
+ if (pExpr2 == null)
+ pExpr1.Expression = this.VisitExpression(pExpr1.Expression, null);
+ else
+ pExpr1.Expression = this.VisitExpression(pExpr1.Expression, pExpr2.Expression);
+ return pExpr1;
+ }
+ public virtual Expression VisitPostfixExpression(PostfixExpression pExpr1, PostfixExpression pExpr2)
+ {
+ if (pExpr1 == null) return null;
+ if (pExpr2 == null)
+ pExpr1.Expression = this.VisitExpression(pExpr1.Expression, null);
+ else
+ pExpr1.Expression = this.VisitExpression(pExpr1.Expression, pExpr2.Expression);
+ return pExpr1;
+ }
+ public virtual Property VisitProperty(Property property1, Property property2)
+ {
+ if (property1 == null) return null;
+ if (property2 == null)
+ {
+ property1.Attributes = this.VisitAttributeList(property1.Attributes, null);
+ property1.Parameters = this.VisitParameterList(property1.Parameters, null);
+ property1.Type = this.VisitTypeReference(property1.Type, null);
+ }
+ else
+ {
+ property1.Attributes = this.VisitAttributeList(property1.Attributes, property2.Attributes);
+ property1.Parameters = this.VisitParameterList(property1.Parameters, property2.Parameters);
+ property1.Type = this.VisitTypeReference(property1.Type, property2.Type);
+ }
+ return property1;
+ }
+ public virtual Expression VisitQuantifier(Quantifier quantifier1, Quantifier quantifier2)
+ {
+ if (quantifier1 == null) return null;
+ if (quantifier2 == null)
+ {
+ quantifier1.Comprehension = (Comprehension)this.VisitComprehension(quantifier1.Comprehension, null);
+ }
+ else
+ {
+ quantifier1.Comprehension = (Comprehension)this.VisitComprehension(quantifier1.Comprehension, quantifier2.Comprehension);
+ }
+ return quantifier1;
+ }
+ public virtual Expression VisitComprehension(Comprehension comprehension1, Comprehension comprehension2)
+ {
+ if (comprehension1 == null) return null;
+ if (comprehension2 == null)
+ {
+ comprehension1.BindingsAndFilters = this.VisitExpressionList(comprehension1.BindingsAndFilters, null);
+ comprehension1.Elements = this.VisitExpressionList(comprehension1.Elements, null);
+ }
+ else
+ {
+ comprehension1.BindingsAndFilters = this.VisitExpressionList(comprehension1.BindingsAndFilters, comprehension2.BindingsAndFilters);
+ comprehension1.Elements = this.VisitExpressionList(comprehension1.Elements, comprehension2.Elements);
+ }
+ return comprehension1;
+ }
+ public virtual ComprehensionBinding VisitComprehensionBinding(ComprehensionBinding comprehensionBinding1, ComprehensionBinding comprehensionBinding2)
+ {
+ if (comprehensionBinding1 == null) return null;
+ if (comprehensionBinding2 == null)
+ {
+ comprehensionBinding1.TargetVariableType = this.VisitTypeReference(comprehensionBinding1.TargetVariableType, null);
+ comprehensionBinding1.TargetVariable = this.VisitTargetExpression(comprehensionBinding1.TargetVariable, null);
+ comprehensionBinding1.SourceEnumerable = this.VisitExpression(comprehensionBinding1.SourceEnumerable, null);
+ }
+ else
+ {
+ comprehensionBinding1.TargetVariableType = this.VisitTypeReference(comprehensionBinding1.TargetVariableType, comprehensionBinding2.TargetVariableType);
+ comprehensionBinding1.TargetVariable = this.VisitTargetExpression(comprehensionBinding1.TargetVariable, comprehensionBinding2.TargetVariable);
+ comprehensionBinding1.SourceEnumerable = this.VisitExpression(comprehensionBinding1.SourceEnumerable, comprehensionBinding2.SourceEnumerable);
+ }
+ return comprehensionBinding1;
+ }
+ public virtual Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier1, QualifiedIdentifier qualifiedIdentifier2)
+ {
+ if (qualifiedIdentifier1 == null) return null;
+ if (qualifiedIdentifier2 == null)
+ qualifiedIdentifier1.Qualifier = this.VisitExpression(qualifiedIdentifier1.Qualifier, null);
+ else
+ qualifiedIdentifier1.Qualifier = this.VisitExpression(qualifiedIdentifier1.Qualifier, qualifiedIdentifier2.Qualifier);
+ return qualifiedIdentifier1;
+ }
+ public virtual Statement VisitRepeat(Repeat repeat1, Repeat repeat2)
+ {
+ if (repeat1 == null) return null;
+ if (repeat2 == null)
+ {
+ repeat1.Body = this.VisitBlock(repeat1.Body, null);
+ repeat1.Condition = this.VisitExpression(repeat1.Condition, null);
+ }
+ else
+ {
+ repeat1.Body = this.VisitBlock(repeat1.Body, repeat2.Body);
+ repeat1.Condition = this.VisitExpression(repeat1.Condition, repeat2.Condition);
+ }
+ return repeat1;
+ }
+#if ExtendedRuntime
+ public virtual RequiresList VisitRequiresList(RequiresList requires1, RequiresList requires2) {
+ if (requires1 == null) return null;
+ for (int i = 0, n = requires1.Count, m = requires2 == null ? 0 : requires2.Count; i < n; i++) {
+ //^ assert requires2 != null;
+ if (i >= m)
+ requires1[i] = (Requires)this.Visit(requires1[i], null);
+ else
+ requires1[i] = (Requires)this.Visit(requires1[i], requires2[i]);
+ }
+ return requires1;
+ }
+#endif
+ public virtual Statement VisitResourceUse(ResourceUse resourceUse1, ResourceUse resourceUse2)
+ {
+ if (resourceUse1 == null) return null;
+ if (resourceUse2 == null)
+ {
+ resourceUse1.ResourceAcquisition = (Statement)this.Visit(resourceUse1.ResourceAcquisition, null);
+ resourceUse1.Body = this.VisitBlock(resourceUse1.Body, null);
+ }
+ else
+ {
+ resourceUse1.ResourceAcquisition = (Statement)this.Visit(resourceUse1.ResourceAcquisition, resourceUse2.ResourceAcquisition);
+ resourceUse1.Body = this.VisitBlock(resourceUse1.Body, resourceUse2.Body);
+ }
+ return resourceUse1;
+ }
+ public virtual Statement VisitReturn(Return Return1, Return Return2)
+ {
+ if (Return1 == null) return null;
+ if (Return2 == null)
+ Return1.Expression = this.VisitExpression(Return1.Expression, null);
+ else
+ Return1.Expression = this.VisitExpression(Return1.Expression, Return2.Expression);
+ return Return1;
+ }
+ public virtual SecurityAttribute VisitSecurityAttribute(SecurityAttribute attribute1, SecurityAttribute attribute2)
+ {
+ return attribute1;
+ }
+ public virtual SecurityAttributeList VisitSecurityAttributeList(SecurityAttributeList attributes1, SecurityAttributeList attributes2)
+ {
+ if (attributes1 == null) return null;
+ for (int i = 0, n = attributes1.Count, m = attributes2 == null ? 0 : attributes2.Count; i < n; i++)
+ {
+ //^ assert attributes2 != null;
+ if (i >= m)
+ attributes1[i] = this.VisitSecurityAttribute(attributes1[i], null);
+ else
+ attributes1[i] = this.VisitSecurityAttribute(attributes1[i], attributes2[i]);
+ }
+ return attributes1;
+ }
+ public virtual Expression VisitSetterValue(SetterValue value1, SetterValue value2)
+ {
+ return value1;
+ }
+ public virtual StatementList VisitStatementList(StatementList statements1, StatementList statements2)
+ {
+ if (statements1 == null) return null;
+ for (int i = 0, n = statements1.Count, m = statements2 == null ? 0 : statements2.Count; i < n; i++)
+ {
+ //^ assert statements2 != null;
+ if (i >= m)
+ statements1[i] = (Statement)this.Visit(statements1[i], null);
+ else
+ statements1[i] = (Statement)this.Visit(statements1[i], statements2[i]);
+ }
+ return statements1;
+ }
+ public virtual StatementSnippet VisitStatementSnippet(StatementSnippet snippet1, StatementSnippet snippet2)
+ {
+ return snippet1;
+ }
+ public virtual StaticInitializer VisitStaticInitializer(StaticInitializer cons1, StaticInitializer cons2)
+ {
+ return (StaticInitializer)this.VisitMethod(cons1, cons2);
+ }
+ public virtual Struct VisitStruct(Struct Struct1, Struct Struct2)
+ {
+ return (Struct)this.VisitTypeNode(Struct1, Struct2);
+ }
+ public virtual Statement VisitSwitch(Switch Switch1, Switch Switch2)
+ {
+ if (Switch1 == null) return null;
+ if (Switch2 == null)
+ {
+ Switch1.Expression = this.VisitExpression(Switch1.Expression, null);
+ Switch1.Cases = this.VisitSwitchCaseList(Switch1.Cases, null);
+ }
+ else
+ {
+ Switch1.Expression = this.VisitExpression(Switch1.Expression, Switch2.Expression);
+ Switch1.Cases = this.VisitSwitchCaseList(Switch1.Cases, Switch2.Cases);
+ }
+ return Switch1;
+ }
+ public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase1, SwitchCase switchCase2)
+ {
+ if (switchCase1 == null) return null;
+ if (switchCase2 == null)
+ {
+ switchCase1.Label = this.VisitExpression(switchCase1.Label, null);
+ switchCase1.Body = this.VisitBlock(switchCase1.Body, null);
+ }
+ else
+ {
+ switchCase1.Label = this.VisitExpression(switchCase1.Label, switchCase2.Label);
+ switchCase1.Body = this.VisitBlock(switchCase1.Body, switchCase2.Body);
+ }
+ return switchCase1;
+ }
+ public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases1, SwitchCaseList switchCases2)
+ {
+ if (switchCases1 == null) return null;
+ for (int i = 0, n = switchCases1.Count, m = switchCases2 == null ? 0 : switchCases2.Count; i < n; i++)
+ {
+ //^ assert switchCases2 != null;
+ if (i >= m)
+ switchCases1[i] = this.VisitSwitchCase(switchCases1[i], null);
+ else
+ switchCases1[i] = this.VisitSwitchCase(switchCases1[i], switchCases2[i]);
+ }
+ return switchCases1;
+ }
+ public virtual Statement VisitSwitchInstruction(SwitchInstruction switchInstruction1, SwitchInstruction switchInstruction2)
+ {
+ if (switchInstruction1 == null) return null;
+ if (switchInstruction2 == null)
+ switchInstruction1.Expression = this.VisitExpression(switchInstruction1.Expression, null);
+ else
+ switchInstruction1.Expression = this.VisitExpression(switchInstruction1.Expression, switchInstruction2.Expression);
+ return switchInstruction1;
+ }
+ public virtual Statement VisitTypeswitch(Typeswitch Typeswitch1, Typeswitch Typeswitch2)
+ {
+ if (Typeswitch1 == null) return null;
+ if (Typeswitch2 == null)
+ {
+ Typeswitch1.Expression = this.VisitExpression(Typeswitch1.Expression, null);
+ Typeswitch1.Cases = this.VisitTypeswitchCaseList(Typeswitch1.Cases, null);
+ }
+ else
+ {
+ Typeswitch1.Expression = this.VisitExpression(Typeswitch1.Expression, Typeswitch2.Expression);
+ Typeswitch1.Cases = this.VisitTypeswitchCaseList(Typeswitch1.Cases, Typeswitch2.Cases);
+ }
+ return Typeswitch1;
+ }
+ public virtual TypeswitchCase VisitTypeswitchCase(TypeswitchCase typeswitchCase1, TypeswitchCase typeswitchCase2)
+ {
+ if (typeswitchCase1 == null) return null;
+ if (typeswitchCase2 == null)
+ {
+ typeswitchCase1.LabelType = this.VisitTypeReference(typeswitchCase1.LabelType, null);
+ typeswitchCase1.LabelVariable = this.VisitTargetExpression(typeswitchCase1.LabelVariable, null);
+ typeswitchCase1.Body = this.VisitBlock(typeswitchCase1.Body, null);
+ }
+ else
+ {
+ typeswitchCase1.LabelType = this.VisitTypeReference(typeswitchCase1.LabelType, typeswitchCase2.LabelType);
+ typeswitchCase1.LabelVariable = this.VisitTargetExpression(typeswitchCase1.LabelVariable, typeswitchCase2.LabelVariable);
+ typeswitchCase1.Body = this.VisitBlock(typeswitchCase1.Body, typeswitchCase2.Body);
+ }
+ return typeswitchCase1;
+ }
+ public virtual TypeswitchCaseList VisitTypeswitchCaseList(TypeswitchCaseList typeswitchCases1, TypeswitchCaseList typeswitchCases2)
+ {
+ if (typeswitchCases1 == null) return null;
+ for (int i = 0, n = typeswitchCases1.Count, m = typeswitchCases2 == null ? 0 : typeswitchCases2.Count; i < n; i++)
+ {
+ //^ assert typeswitchCases2 != null;
+ if (i >= m)
+ typeswitchCases1[i] = this.VisitTypeswitchCase(typeswitchCases1[i], null);
+ else
+ typeswitchCases1[i] = this.VisitTypeswitchCase(typeswitchCases1[i], typeswitchCases2[i]);
+ }
+ return typeswitchCases1;
+ }
+ public virtual Expression VisitTargetExpression(Expression expression1, Expression expression2)
+ {
+ return this.VisitExpression(expression1, expression2);
+ }
+ public virtual Expression VisitTernaryExpression(TernaryExpression expression1, TernaryExpression expression2)
+ {
+ if (expression1 == null) return null;
+ if (expression2 == null)
+ {
+ expression1.Operand1 = this.VisitExpression(expression1.Operand1, null);
+ expression1.Operand2 = this.VisitExpression(expression1.Operand2, null);
+ expression1.Operand3 = this.VisitExpression(expression1.Operand3, null);
+ }
+ else
+ {
+ expression1.Operand1 = this.VisitExpression(expression1.Operand1, expression2.Operand1);
+ expression1.Operand2 = this.VisitExpression(expression1.Operand2, expression2.Operand2);
+ expression1.Operand3 = this.VisitExpression(expression1.Operand3, expression2.Operand3);
+ }
+ return expression1;
+ }
+ public virtual Expression VisitThis(This This1, This This2)
+ {
+ if (This1 == null) return null;
+ if (This2 == null)
+ This1.Type = this.VisitTypeReference(This1.Type, null);
+ else
+ This1.Type = this.VisitTypeReference(This1.Type, This2.Type);
+ return This1;
+ }
+ public virtual Statement VisitThrow(Throw Throw1, Throw Throw2)
+ {
+ if (Throw1 == null) return null;
+ if (Throw2 == null)
+ Throw1.Expression = this.VisitExpression(Throw1.Expression, null);
+ else
+ Throw1.Expression = this.VisitExpression(Throw1.Expression, Throw2.Expression);
+ return Throw1;
+ }
+ public virtual Statement VisitTry(Try Try1, Try Try2)
+ {
+ if (Try1 == null) return null;
+ if (Try2 == null)
+ {
+ Try1.TryBlock = this.VisitBlock(Try1.TryBlock, null);
+ Try1.Catchers = this.VisitCatchList(Try1.Catchers, null);
+ Try1.Filters = this.VisitFilterList(Try1.Filters, null);
+ Try1.FaultHandlers = this.VisitFaultHandlerList(Try1.FaultHandlers, null);
+ Try1.Finally = (Finally)this.VisitFinally(Try1.Finally, null);
+ }
+ else
+ {
+ Try1.TryBlock = this.VisitBlock(Try1.TryBlock, Try2.TryBlock);
+ Try1.Catchers = this.VisitCatchList(Try1.Catchers, Try2.Catchers);
+ Try1.Filters = this.VisitFilterList(Try1.Filters, Try2.Filters);
+ Try1.FaultHandlers = this.VisitFaultHandlerList(Try1.FaultHandlers, Try2.FaultHandlers);
+ Try1.Finally = (Finally)this.VisitFinally(Try1.Finally, Try2.Finally);
+ }
+ return Try1;
+ }
+#if ExtendedRuntime
+ public virtual TupleType VisitTupleType(TupleType tuple1, TupleType tuple2){
+ return (TupleType)this.VisitTypeNode(tuple1, tuple2);
+ }
+ public virtual TypeAlias VisitTypeAlias(TypeAlias tAlias1, TypeAlias tAlias2){
+ if (tAlias1 == null) return null;
+ if (tAlias2 == null){
+ if (tAlias1.AliasedType is ConstrainedType)
+ //The type alias defines the constrained type, rather than just referencing it
+ tAlias1.AliasedType = this.VisitConstrainedType((ConstrainedType)tAlias1.AliasedType, null);
+ else
+ tAlias1.AliasedType = this.VisitTypeReference(tAlias1.AliasedType, null);
+ }else{
+ if (tAlias1.AliasedType is ConstrainedType)
+ //The type alias defines the constrained type, rather than just referencing it
+ tAlias1.AliasedType = this.VisitConstrainedType((ConstrainedType)tAlias1.AliasedType, tAlias2.AliasedType as ConstrainedType);
+ else
+ tAlias1.AliasedType = this.VisitTypeReference(tAlias1.AliasedType, tAlias2.AliasedType);
+ }
+ return tAlias1;
+ }
+ public virtual TypeIntersection VisitTypeIntersection(TypeIntersection typeIntersection1, TypeIntersection typeIntersection2){
+ return (TypeIntersection)this.VisitTypeNode(typeIntersection1, typeIntersection2);
+ }
+ public virtual TypeContract VisitTypeContract(TypeContract contract1, TypeContract contract2) {
+ if (contract1 == null) return null;
+ if (contract2 == null) {
+ // don't visit contract.DeclaringType
+ // don't visit contract.InheitedContracts
+ contract1.Invariants = this.VisitInvariantList(contract1.Invariants, null);
+ }else{
+ // don't visit contract.DeclaringType
+ // don't visit contract.InheitedContracts
+ contract1.Invariants = this.VisitInvariantList(contract1.Invariants, contract2.Invariants);
+ }
+ return contract1;
+ }
+#endif
+ public virtual TypeMemberSnippet VisitTypeMemberSnippet(TypeMemberSnippet snippet1, TypeMemberSnippet snippet2)
+ {
+ return snippet1;
+ }
+ public virtual TypeModifier VisitTypeModifier(TypeModifier typeModifier1, TypeModifier typeModifier2)
+ {
+ if (typeModifier1 == null) return null;
+ if (typeModifier2 == null)
+ {
+ typeModifier1.Modifier = this.VisitTypeReference(typeModifier1.Modifier, null);
+ typeModifier1.ModifiedType = this.VisitTypeReference(typeModifier1.ModifiedType, null);
+ }
+ else
+ {
+ typeModifier1.Modifier = this.VisitTypeReference(typeModifier1.Modifier, typeModifier2.Modifier);
+ typeModifier1.ModifiedType = this.VisitTypeReference(typeModifier1.ModifiedType, typeModifier2.ModifiedType);
+ }
+ return typeModifier1;
+ }
+ public virtual TypeNode VisitTypeNode(TypeNode typeNode1, TypeNode typeNode2)
+ {
+ if (typeNode1 == null) return null;
+ if (typeNode2 == null)
+ {
+ typeNode1.Attributes = this.VisitAttributeList(typeNode1.Attributes, null);
+ typeNode1.SecurityAttributes = this.VisitSecurityAttributeList(typeNode1.SecurityAttributes, null);
+ Class c = typeNode1 as Class;
+ if (c != null) c.BaseClass = (Class)this.VisitTypeReference(c.BaseClass, null);
+ typeNode1.Interfaces = this.VisitInterfaceReferenceList(typeNode1.Interfaces, null);
+ typeNode1.TemplateArguments = this.VisitTypeReferenceList(typeNode1.TemplateArguments, null);
+ typeNode1.TemplateParameters = this.VisitTypeParameterList(typeNode1.TemplateParameters, null);
+ typeNode1.Members = this.VisitMemberList(typeNode1.Members, null);
+ }
+ else
+ {
+ typeNode1.Attributes = this.VisitAttributeList(typeNode1.Attributes, typeNode2.Attributes);
+ typeNode1.SecurityAttributes = this.VisitSecurityAttributeList(typeNode1.SecurityAttributes, typeNode2.SecurityAttributes);
+ Class c1 = typeNode1 as Class;
+ Class c2 = typeNode2 as Class;
+ if (c1 != null) c1.BaseClass = (Class)this.VisitTypeReference(c1.BaseClass, c2 == null ? null : c2.BaseClass);
+ typeNode1.Interfaces = this.VisitInterfaceReferenceList(typeNode1.Interfaces, typeNode2.Interfaces);
+ typeNode1.TemplateArguments = this.VisitTypeReferenceList(typeNode1.TemplateArguments, typeNode2.TemplateArguments);
+ typeNode1.TemplateParameters = this.VisitTypeParameterList(typeNode1.TemplateParameters, typeNode2.TemplateParameters);
+ typeNode1.Members = this.VisitMemberList(typeNode1.Members, typeNode2.Members);
+ }
+ return typeNode1;
+ }
+ public virtual TypeNodeList VisitTypeNodeList(TypeNodeList types1, TypeNodeList types2)
+ {
+ if (types1 == null) return null;
+ if (types2 == null)
+ {
+ for (int i = 0; i < types1.Count; i++) //Visiting a type may result in a new type being appended to this list
+ types1[i] = (TypeNode)this.Visit(types1[i], null);
+ }
+ else
+ {
+ for (int i = 0; i < types1.Count; i++)
+ { //Visiting a type may result in a new type being appended to this list
+ if (i >= types2.Count)
+ types1[i] = (TypeNode)this.Visit(types1[i], null);
+ else
+ types1[i] = (TypeNode)this.Visit(types1[i], types2[i]);
+ }
+ }
+ return types1;
+ }
+ public virtual TypeNode VisitTypeParameter(TypeNode typeParameter1, TypeNode typeParameter2)
+ {
+ if (typeParameter1 == null) return null;
+ if (typeParameter2 == null)
+ typeParameter1.Interfaces = this.VisitInterfaceReferenceList(typeParameter1.Interfaces, null);
+ else
+ typeParameter1.Interfaces = this.VisitInterfaceReferenceList(typeParameter1.Interfaces, typeParameter2.Interfaces);
+ return typeParameter1;
+ }
+ public virtual TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters1, TypeNodeList typeParameters2)
+ {
+ if (typeParameters1 == null) return null;
+ for (int i = 0, n = typeParameters1.Count, m = typeParameters2 == null ? 0 : typeParameters2.Count; i < n; i++)
+ {
+ //^ assert typeParameters2 != null;
+ if (i >= m)
+ typeParameters1[i] = this.VisitTypeParameter(typeParameters1[i], null);
+ else
+ typeParameters1[i] = this.VisitTypeParameter(typeParameters1[i], typeParameters2[i]);
+ }
+ return typeParameters1;
+ }
+ public virtual TypeNode VisitTypeReference(TypeNode type1, TypeNode type2)
+ {
+ return type1;
+ }
+ public virtual TypeReference VisitTypeReference(TypeReference typeReference1, TypeReference variableDeclaration2)
+ {
+ if (typeReference1 == null) return null;
+ if (variableDeclaration2 == null)
+ {
+ typeReference1.Type = this.VisitTypeReference(typeReference1.Type, null);
+ typeReference1.Expression = this.VisitTypeReference(typeReference1.Expression, null);
+ }
+ else
+ {
+ typeReference1.Type = this.VisitTypeReference(typeReference1.Type, variableDeclaration2.Type);
+ typeReference1.Expression = this.VisitTypeReference(typeReference1.Expression, variableDeclaration2.Expression);
+ }
+ return typeReference1;
+ }
+ public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences1, TypeNodeList typeReferences2)
+ {
+ if (typeReferences1 == null) return null;
+ for (int i = 0, n = typeReferences1.Count, m = typeReferences2 == null ? 0 : typeReferences2.Count; i < n; i++)
+ {
+ //^ assert typeReferences2 != null;
+ if (i >= m)
+ typeReferences1[i] = this.VisitTypeReference(typeReferences1[i], null);
+ else
+ typeReferences1[i] = this.VisitTypeReference(typeReferences1[i], typeReferences2[i]);
+ }
+ return typeReferences1;
+ }
+#if ExtendedRuntime
+ public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion1, TypeUnion typeUnion2){
+ return (TypeUnion)this.VisitTypeNode(typeUnion1, typeUnion2);
+ }
+#endif
+ public virtual Expression VisitUnaryExpression(UnaryExpression unaryExpression1, UnaryExpression unaryExpression2)
+ {
+ if (unaryExpression1 == null) return null;
+ if (unaryExpression2 == null)
+ unaryExpression1.Operand = this.VisitExpression(unaryExpression1.Operand, null);
+ else
+ unaryExpression1.Operand = this.VisitExpression(unaryExpression1.Operand, unaryExpression2.Operand);
+ return unaryExpression1;
+ }
+ public virtual Statement VisitVariableDeclaration(VariableDeclaration variableDeclaration1, VariableDeclaration variableDeclaration2)
+ {
+ if (variableDeclaration1 == null) return null;
+ if (variableDeclaration2 == null)
+ {
+ variableDeclaration1.Type = this.VisitTypeReference(variableDeclaration1.Type, null);
+ variableDeclaration1.Initializer = this.VisitExpression(variableDeclaration1.Initializer, null);
+ }
+ else
+ {
+ variableDeclaration1.Type = this.VisitTypeReference(variableDeclaration1.Type, variableDeclaration2.Type);
+ variableDeclaration1.Initializer = this.VisitExpression(variableDeclaration1.Initializer, variableDeclaration2.Initializer);
+ }
+ return variableDeclaration1;
+ }
+ public virtual UsedNamespace VisitUsedNamespace(UsedNamespace usedNamespace1, UsedNamespace usedNamespace2)
+ {
+ return usedNamespace1;
+ }
+ public virtual UsedNamespaceList VisitUsedNamespaceList(UsedNamespaceList usedNspaces1, UsedNamespaceList usedNspaces2)
+ {
+ if (usedNspaces1 == null) return null;
+ for (int i = 0, n = usedNspaces1.Count, m = usedNspaces2 == null ? 0 : usedNspaces2.Count; i < n; i++)
+ {
+ //^ assert usedNspaces2 != null;
+ if (i >= m)
+ usedNspaces1[i] = this.VisitUsedNamespace(usedNspaces1[i], null);
+ else
+ usedNspaces1[i] = this.VisitUsedNamespace(usedNspaces1[i], usedNspaces2[i]);
+ }
+ return usedNspaces1;
+ }
+ public virtual Statement VisitWhile(While While1, While While2)
+ {
+ if (While1 == null) return null;
+ if (While2 == null)
+ {
+ While1.Invariants = this.VisitExpressionList(While1.Invariants, null);
+ While1.Condition = this.VisitExpression(While1.Condition, null);
+ While1.Body = this.VisitBlock(While1.Body, null);
+ }
+ else
+ {
+ While1.Invariants = this.VisitExpressionList(While1.Invariants, While2.Invariants);
+ While1.Condition = this.VisitExpression(While1.Condition, While2.Condition);
+ While1.Body = this.VisitBlock(While1.Body, While2.Body);
+ }
+ return While1;
+ }
+ public virtual Statement VisitYield(Yield Yield1, Yield Yield2)
+ {
+ if (Yield1 == null) return null;
+ if (Yield2 == null)
+ Yield1.Expression = this.VisitExpression(Yield1.Expression, null);
+ else
+ Yield1.Expression = this.VisitExpression(Yield1.Expression, Yield2.Expression);
+ return Yield1;
+ }
+#if ExtendedRuntime
+ // query nodes
+ public virtual Node VisitQueryAggregate(QueryAggregate qa1, QueryAggregate qa2){
+ if (qa1 == null) return null;
+ if (qa2 == null)
+ qa1.Expression = this.VisitExpression(qa1.Expression, null);
+ else
+ qa1.Expression = this.VisitExpression(qa1.Expression, qa2.Expression);
+ return qa1;
+ }
+ public virtual Node VisitQueryAlias(QueryAlias alias1, QueryAlias alias2){
+ if (alias1 == null) return null;
+ if (alias2 == null)
+ alias1.Expression = this.VisitExpression(alias1.Expression, null);
+ else
+ alias1.Expression = this.VisitExpression(alias1.Expression, alias2.Expression);
+ return alias1;
+ }
+ public virtual Node VisitQueryAxis(QueryAxis axis1, QueryAxis axis2){
+ if (axis1 == null) return null;
+ if (axis2 == null)
+ axis1.Source = this.VisitExpression(axis1.Source, null);
+ else
+ axis1.Source = this.VisitExpression(axis1.Source, axis2.Source);
+ return axis1;
+ }
+ public virtual Node VisitQueryCommit(QueryCommit qc1, QueryCommit qc2){
+ return qc1;
+ }
+ public virtual Node VisitQueryContext(QueryContext context1, QueryContext context2){
+ return context1;
+ }
+ public virtual Node VisitQueryDelete(QueryDelete delete1, QueryDelete delete2){
+ if (delete1 == null) return null;
+ if (delete2 == null){
+ delete1.Source = this.VisitExpression(delete1.Source, null);
+ /*delete1.Target =*/ this.VisitExpression(delete1.Target, null); //REVIEW: why should this not be updated?
+ }else{
+ delete1.Source = this.VisitExpression(delete1.Source, delete2.Source);
+ /*delete1.Target =*/ this.VisitExpression(delete1.Target, delete2.Target); //REVIEW: why should this not be updated?
+ }
+ return delete1;
+ }
+ public virtual Node VisitQueryDifference(QueryDifference diff1, QueryDifference diff2){
+ if (diff1 == null) return null;
+ if (diff2 == null){
+ diff1.LeftSource = this.VisitExpression(diff1.LeftSource, null);
+ diff1.RightSource = this.VisitExpression(diff1.RightSource, null);
+ }else{
+ diff1.LeftSource = this.VisitExpression(diff1.LeftSource, diff2.LeftSource);
+ diff1.RightSource = this.VisitExpression(diff1.RightSource, diff2.RightSource);
+ }
+ return diff1;
+ }
+ public virtual Node VisitQueryDistinct(QueryDistinct distinct1, QueryDistinct distinct2){
+ if (distinct1 == null) return null;
+ if (distinct2 == null)
+ distinct1.Source = this.VisitExpression(distinct1.Source, null);
+ else
+ distinct1.Source = this.VisitExpression(distinct1.Source, distinct2.Source);
+ return distinct1;
+ }
+ public virtual Node VisitQueryExists(QueryExists exists1, QueryExists exists2){
+ if (exists1 == null) return null;
+ if (exists2 == null)
+ exists1.Source = this.VisitExpression(exists1.Source, null);
+ else
+ exists1.Source = this.VisitExpression(exists1.Source, exists2.Source);
+ return exists1;
+ }
+ public virtual Node VisitQueryFilter(QueryFilter filter1, QueryFilter filter2){
+ if (filter1 == null) return null;
+ if (filter2 == null){
+ filter1.Source = this.VisitExpression(filter1.Source, null);
+ filter1.Expression = this.VisitExpression(filter1.Expression, null);
+ }else{
+ filter1.Source = this.VisitExpression(filter1.Source, filter2.Source);
+ filter1.Expression = this.VisitExpression(filter1.Expression, filter2.Expression);
+ }
+ return filter1;
+ }
+ public virtual Node VisitQueryGroupBy(QueryGroupBy groupby1, QueryGroupBy groupby2){
+ if (groupby1 == null) return null;
+ if (groupby2 == null){
+ groupby1.Source = this.VisitExpression(groupby1.Source, null);
+ groupby1.GroupList = this.VisitExpressionList(groupby1.GroupList, null);
+ groupby1.Having = this.VisitExpression(groupby1.Having, null);
+ }else{
+ groupby1.Source = this.VisitExpression(groupby1.Source, groupby2.Source);
+ groupby1.GroupList = this.VisitExpressionList(groupby1.GroupList, groupby2.GroupList);
+ groupby1.Having = this.VisitExpression(groupby1.Having, groupby2.Having);
+ }
+ return groupby1;
+ }
+ public virtual Statement VisitQueryGeneratedType(QueryGeneratedType qgt1, QueryGeneratedType qgt2){
+ return qgt1;
+ }
+ public virtual Node VisitQueryInsert(QueryInsert insert1, QueryInsert insert2){
+ if (insert1 == null) return null;
+ if (insert2 == null){
+ insert1.Location = this.VisitExpression(insert1.Location, null);
+ insert1.HintList = this.VisitExpressionList(insert1.HintList, null);
+ insert1.InsertList = this.VisitExpressionList(insert1.InsertList, null);
+ }else{
+ insert1.Location = this.VisitExpression(insert1.Location, insert2.Location);
+ insert1.HintList = this.VisitExpressionList(insert1.HintList, insert2.HintList);
+ insert1.InsertList = this.VisitExpressionList(insert1.InsertList, insert2.InsertList);
+ }
+ return insert1;
+ }
+ public virtual Node VisitQueryIntersection(QueryIntersection intersection1, QueryIntersection intersection2){
+ if (intersection1 == null) return null;
+ if (intersection2 == null){
+ intersection1.LeftSource = this.VisitExpression(intersection1.LeftSource, null);
+ intersection1.RightSource = this.VisitExpression(intersection1.RightSource, null);
+ intersection1.Type = intersection1.LeftSource == null ? null : intersection1.LeftSource.Type;
+ }else{
+ intersection1.LeftSource = this.VisitExpression(intersection1.LeftSource, intersection2.LeftSource);
+ intersection1.RightSource = this.VisitExpression(intersection1.RightSource, intersection2.RightSource);
+ intersection1.Type = intersection1.LeftSource == null ? null : intersection1.LeftSource.Type;
+ }
+ return intersection1;
+ }
+ public virtual Node VisitQueryIterator(QueryIterator xiterator1, QueryIterator xiterator2){
+ if (xiterator1 == null) return null;
+ if (xiterator2 == null){
+ xiterator1.Expression = this.VisitExpression(xiterator1.Expression, null);
+ xiterator1.HintList = this.VisitExpressionList(xiterator1.HintList, null);
+ }else{
+ xiterator1.Expression = this.VisitExpression(xiterator1.Expression, xiterator2.Expression);
+ xiterator1.HintList = this.VisitExpressionList(xiterator1.HintList, xiterator2.HintList);
+ }
+ return xiterator1;
+ }
+ public virtual Node VisitQueryJoin(QueryJoin join1, QueryJoin join2){
+ if (join1 == null) return null;
+ if (join2 == null){
+ join1.LeftOperand = this.VisitExpression(join1.LeftOperand, null);
+ join1.RightOperand = this.VisitExpression(join1.RightOperand, null);
+ join1.JoinExpression = this.VisitExpression(join1.JoinExpression, null);
+ }else{
+ join1.LeftOperand = this.VisitExpression(join1.LeftOperand, join2.LeftOperand);
+ join1.RightOperand = this.VisitExpression(join1.RightOperand, join2.RightOperand);
+ join1.JoinExpression = this.VisitExpression(join1.JoinExpression, join2.JoinExpression);
+ }
+ return join1;
+ }
+ public virtual Node VisitQueryLimit(QueryLimit limit1, QueryLimit limit2){
+ if (limit1 == null) return null;
+ if (limit2 == null){
+ limit1.Source = this.VisitExpression(limit1.Source, null);
+ limit1.Expression = this.VisitExpression(limit1.Expression, null);
+ }else{
+ limit1.Source = this.VisitExpression(limit1.Source, limit2.Source);
+ limit1.Expression = this.VisitExpression(limit1.Expression, limit2.Expression);
+ }
+ return limit1;
+ }
+ public virtual Node VisitQueryOrderBy(QueryOrderBy orderby1, QueryOrderBy orderby2){
+ if (orderby1 == null) return null;
+ if (orderby2 == null){
+ orderby1.Source = this.VisitExpression(orderby1.Source, null);
+ orderby1.OrderList = this.VisitExpressionList(orderby1.OrderList, null);
+ }else{
+ orderby1.Source = this.VisitExpression(orderby1.Source, orderby2.Source);
+ orderby1.OrderList = this.VisitExpressionList(orderby1.OrderList, orderby2.OrderList);
+ }
+ return orderby1;
+ }
+ public virtual Node VisitQueryOrderItem(QueryOrderItem item1, QueryOrderItem item2){
+ if (item1 == null) return null;
+ if (item2 == null)
+ item1.Expression = this.VisitExpression(item1.Expression, null);
+ else
+ item1.Expression = this.VisitExpression(item1.Expression, item2.Expression);
+ return item1;
+ }
+ public virtual Node VisitQueryPosition(QueryPosition position1, QueryPosition position2){
+ return position1;
+ }
+ public virtual Node VisitQueryProject(QueryProject project1, QueryProject project2){
+ if (project1 == null) return null;
+ if (project2 == null){
+ project1.Source = this.VisitExpression(project1.Source, null);
+ project1.ProjectionList = this.VisitExpressionList(project1.ProjectionList, null);
+ }else{
+ project1.Source = this.VisitExpression(project1.Source, project2.Source);
+ project1.ProjectionList = this.VisitExpressionList(project1.ProjectionList, project2.ProjectionList);
+ }
+ return project1;
+ }
+ public virtual Node VisitQueryRollback(QueryRollback qr1, QueryRollback qr2){
+ return qr1;
+ }
+ public virtual Node VisitQueryQuantifier(QueryQuantifier qq1, QueryQuantifier qq2){
+ if (qq1 == null) return null;
+ if (qq2 == null)
+ qq1.Expression = this.VisitExpression(qq1.Expression, null);
+ else
+ qq1.Expression = this.VisitExpression(qq1.Expression, qq2.Expression);
+ return qq1;
+ }
+ public virtual Node VisitQueryQuantifiedExpression(QueryQuantifiedExpression qqe1, QueryQuantifiedExpression qqe2){
+ if (qqe1 == null) return null;
+ if (qqe2 == null)
+ qqe1.Expression = this.VisitExpression(qqe1.Expression, null);
+ else
+ qqe1.Expression = this.VisitExpression(qqe1.Expression, qqe2.Expression);
+ return qqe1;
+ }
+ public virtual Node VisitQuerySelect(QuerySelect select1, QuerySelect select2){
+ if (select1 == null) return null;
+ if (select2 == null)
+ select1.Source = this.VisitExpression(select1.Source, null);
+ else
+ select1.Source = this.VisitExpression(select1.Source, select2.Source);
+ return select1;
+ }
+ public virtual Node VisitQuerySingleton(QuerySingleton singleton1, QuerySingleton singleton2){
+ if (singleton1 == null) return null;
+ if (singleton2 == null)
+ singleton1.Source = this.VisitExpression(singleton1.Source, null);
+ else
+ singleton1.Source = this.VisitExpression(singleton1.Source, singleton2.Source);
+ return singleton1;
+ }
+ public virtual Node VisitQueryTransact(QueryTransact qt1, QueryTransact qt2){
+ if (qt1 == null) return null;
+ if (qt2 == null){
+ qt1.Source = this.VisitExpression(qt1.Source, null);
+ qt1.Body = this.VisitBlock(qt1.Body, null);
+ qt1.CommitBody = this.VisitBlock(qt1.CommitBody, null);
+ qt1.RollbackBody = this.VisitBlock(qt1.RollbackBody, null);
+ }else{
+ qt1.Source = this.VisitExpression(qt1.Source, qt2.Source);
+ qt1.Body = this.VisitBlock(qt1.Body, qt2.Body);
+ qt1.CommitBody = this.VisitBlock(qt1.CommitBody, qt2.CommitBody);
+ qt1.RollbackBody = this.VisitBlock(qt1.RollbackBody, qt2.RollbackBody);
+ }
+ return qt1;
+ }
+ public virtual Node VisitQueryTypeFilter(QueryTypeFilter filter1, QueryTypeFilter filter2){
+ if (filter1 == null) return null;
+ if (filter2 == null)
+ filter1.Source = this.VisitExpression(filter1.Source, null);
+ else
+ filter1.Source = this.VisitExpression(filter1.Source, filter2.Source);
+ return filter1;
+ }
+ public virtual Node VisitQueryUnion(QueryUnion union1, QueryUnion union2){
+ if (union1 == null) return null;
+ if (union2 == null){
+ union1.LeftSource = this.VisitExpression(union1.LeftSource, null);
+ union1.RightSource = this.VisitExpression(union1.RightSource, null);
+ }else{
+ union1.LeftSource = this.VisitExpression(union1.LeftSource, union2.LeftSource);
+ union1.RightSource = this.VisitExpression(union1.RightSource, union2.RightSource);
+ }
+ return union1;
+ }
+ public virtual Node VisitQueryUpdate(QueryUpdate update1, QueryUpdate update2){
+ if (update1 == null) return null;
+ if (update2 == null){
+ update1.Source = this.VisitExpression(update1.Source, null);
+ update1.UpdateList = this.VisitExpressionList(update1.UpdateList, null);
+ }else{
+ update1.Source = this.VisitExpression(update1.Source, update2.Source);
+ update1.UpdateList = this.VisitExpressionList(update1.UpdateList, update2.UpdateList);
+ }
+ return update1;
+ }
+ public virtual Node VisitQueryYielder(QueryYielder yielder1, QueryYielder yielder2){
+ if (yielder1 == null) return null;
+ if (yielder2 == null){
+ yielder1.Source = this.VisitExpression(yielder1.Source, null);
+ yielder1.Target = this.VisitExpression(yielder1.Target, null);
+ yielder1.Body = this.VisitBlock(yielder1.Body, null);
+ }else{
+ yielder1.Source = this.VisitExpression(yielder1.Source, yielder2.Source);
+ yielder1.Target = this.VisitExpression(yielder1.Target, yielder2.Target);
+ yielder1.Body = this.VisitBlock(yielder1.Body, yielder2.Body);
+ }
+ return yielder1;
+ }
+#endif
+ }
+}
+#endif
diff --git a/tools/Sandcastle/Source/CCI/Duplicator.cs b/tools/Sandcastle/Source/CCI/Duplicator.cs
new file mode 100644
index 0000000..bd35981
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Duplicator.cs
@@ -0,0 +1,1926 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+#if FxCop
+using AttributeList = Microsoft.Cci.AttributeNodeCollection;
+using BlockList = Microsoft.Cci.BlockCollection;
+using ExpressionList = Microsoft.Cci.ExpressionCollection;
+using InstructionList = Microsoft.Cci.InstructionCollection;
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using MemberList = Microsoft.Cci.MemberCollection;
+using MethodList = Microsoft.Cci.MethodCollection;
+using ModuleReferenceList = Microsoft.Cci.ModuleReferenceCollection;
+using NamespaceList = Microsoft.Cci.NamespaceCollection;
+using NodeList = Microsoft.Cci.NodeCollection;
+using ParameterList = Microsoft.Cci.ParameterCollection;
+using SecurityAttributeList = Microsoft.Cci.SecurityAttributeCollection;
+using StatementList = Microsoft.Cci.StatementCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Property = Microsoft.Cci.PropertyNode;
+using Module = Microsoft.Cci.ModuleNode;
+using Return = Microsoft.Cci.ReturnNode;
+using Class = Microsoft.Cci.ClassNode;
+using Event = Microsoft.Cci.EventNode;
+using Throw = Microsoft.Cci.ThrowNode;
+#endif
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ /* The idea here is to do a tree traversal of the IR graph, rewriting the IR with duplicate nodes from the bottom up. Nodes that may appear
+ * more than once in the graph keep track of their duplicates in the DuplicateFor hashtable and all references to these nodes are replaced
+ * with references to the corresponding duplicates.
+ *
+ * A complication arises because of the need to duplicate IR subgraphs, such as Methods, Types, CompilationUnits and individual Modules.
+ * The subgraphs contain references to "foreign" nodes that should not be duplicated and it is thus necessary to be able to tell whether
+ * or not a node should be duplicated. This done by tracking all the types that are members of the subgraph to be duplicated in the
+ * TypesToBeDuplicated hashtable. Types are duplicated only if they are members of this table, while fields and methods are duplicated
+ * only if their declaring types are members of this table.
+ *
+ * Since every type contains a reference to its declaring module, the module in which duplicated types will be inserted must be specified
+ * to the constructor.
+ * */
+
+ /// <summary>
+ /// Walks an IR, duplicating it while fixing up self references to point to the duplicate IR. Only good for one duplication.
+ /// Largest unit of duplication is a single module.
+ /// </summary>
+#if !FxCop
+ public
+#endif
+ class Duplicator : StandardVisitor
+ {
+ public TrivialHashtable/*!*/ DuplicateFor;
+ public TrivialHashtable/*!*/ TypesToBeDuplicated;
+ public Module/*!*/ TargetModule;
+ public TypeNode TargetType;
+ public Method TargetMethod;
+ public TypeNode OriginalTargetType;
+ public bool SkipBodies;
+ public bool RecordOriginalAsTemplate;
+#if !NoXml
+ public bool CopyDocumentation;
+#endif
+ /// <param name="module">The module into which the duplicate IR will be grafted.</param>
+ /// <param name="type">The type into which the duplicate Member will be grafted. Ignored if entire type, or larger unit is duplicated.</param>
+ public Duplicator(Module/*!*/ module, TypeNode type)
+ {
+ this.TargetModule = module;
+ this.TargetType = this.OriginalTargetType = type;
+ this.DuplicateFor = new TrivialHashtable();
+ this.TypesToBeDuplicated = new TrivialHashtable();
+ //^ base();
+ }
+#if !MinimalReader
+ public Duplicator(Visitor/*!*/ callingVisitor)
+ : base(callingVisitor)
+ {
+ /*^
+ //Dummy initializations to satisfy compiler.
+ Duplicator cdv = callingVisitor as Duplicator;
+ if (cdv == null) {
+ this.DuplicateFor = new TrivialHashtable();
+ this.TypesToBeDuplicated = new TrivialHashtable();
+ this.TargetModule = new Module();
+ this.TargetType = this.OriginalTargetType = new Class();
+ } else {
+ this.DuplicateFor = cdv.DuplicateFor;
+ this.TypesToBeDuplicated = cdv.TypesToBeDuplicated;
+ this.TargetModule = cdv.TargetModule;
+ this.TargetType = cdv.TargetType;
+ this.OriginalTargetType = cdv.OriginalTargetType;
+ }
+ base; //The real initializations happen here
+ ^*/
+ }
+ public override void TransferStateTo(Visitor targetVisitor)
+ {
+ base.TransferStateTo(targetVisitor);
+ Duplicator target = targetVisitor as Duplicator;
+ if (target == null) return;
+ target.DuplicateFor = this.DuplicateFor;
+ target.OriginalTargetType = this.OriginalTargetType;
+ target.RecordOriginalAsTemplate = this.RecordOriginalAsTemplate;
+ target.SkipBodies = this.SkipBodies;
+ target.TargetMethod = this.TargetMethod;
+ target.TargetModule = this.TargetModule;
+ target.TargetType = this.TargetType;
+ target.TypesToBeDuplicated = this.TypesToBeDuplicated;
+ }
+ public virtual void FindTypesToBeDuplicated(Node node)
+ {
+ }
+ public virtual void FindTypesToBeDuplicated(NodeList nodes)
+ {
+ if (nodes == null) return;
+ for (int i = 0, n = nodes.Count; i < n; i++)
+ {
+ Node node = nodes[i];
+ if (node == null) continue;
+ if (node is Namespace) this.FindTypesToBeDuplicated((Namespace)node);
+ else this.FindTypesToBeDuplicated(node);
+ }
+ }
+ public virtual void FindTypesToBeDuplicated(Namespace nspace)
+ {
+ if (nspace == null) return;
+ this.FindTypesToBeDuplicated(nspace.Types);
+ this.FindTypesToBeDuplicated(nspace.NestedNamespaces);
+ }
+#endif
+ public virtual void FindTypesToBeDuplicated(NamespaceList namespaces)
+ {
+ if (namespaces == null) return;
+ for (int i = 0, n = namespaces.Count; i < n; i++)
+ {
+ Namespace nspace = namespaces[i];
+ if (nspace == null) continue;
+ this.FindTypesToBeDuplicated(nspace.Types);
+#if !MinimalReader
+ this.FindTypesToBeDuplicated(nspace.NestedNamespaces);
+#endif
+ }
+ }
+ public virtual void FindTypesToBeDuplicated(TypeNodeList types)
+ {
+ if (types == null) return;
+ for (int i = 0, n = types.Count; i < n; i++)
+ {
+ TypeNode t = types[i];
+ if (t == null) continue;
+ this.TypesToBeDuplicated[t.UniqueKey] = t;
+ this.FindTypesToBeDuplicated(t.NestedTypes);
+ this.FindTypesToBeDuplicated(t.TemplateParameters);
+ }
+ }
+ public override Node Visit(Node node)
+ {
+ node = base.Visit(node);
+ Expression e = node as Expression;
+ if (e != null) e.Type = this.VisitTypeReference(e.Type);
+ return node;
+ }
+ public override Expression VisitAddressDereference(AddressDereference addr)
+ {
+ if (addr == null) return null;
+ return base.VisitAddressDereference((AddressDereference)addr.Clone());
+ }
+#if !MinimalReader
+ public override AliasDefinition VisitAliasDefinition(AliasDefinition aliasDefinition)
+ {
+ if (aliasDefinition == null) return null;
+ return base.VisitAliasDefinition((AliasDefinition)aliasDefinition.Clone());
+ }
+ public override AliasDefinitionList VisitAliasDefinitionList(AliasDefinitionList aliasDefinitions)
+ {
+ if (aliasDefinitions == null) return null;
+ return base.VisitAliasDefinitionList(aliasDefinitions.Clone());
+ }
+ public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func)
+ {
+ if (func == null) return null;
+ AnonymousNestedFunction dup = (AnonymousNestedFunction)func.Clone();
+ if (func.Method != null)
+ {
+ dup.Method = this.VisitMethod(func.Method);
+ //^ assume dup.Method != null;
+ dup.Parameters = dup.Method.Parameters;
+ dup.Body = dup.Method.Body;
+ return dup;
+ }
+ return base.VisitAnonymousNestedFunction(dup);
+ }
+ public override Expression VisitApplyToAll(ApplyToAll applyToAll)
+ {
+ if (applyToAll == null) return null;
+ return base.VisitApplyToAll((ApplyToAll)applyToAll.Clone());
+ }
+#endif
+ public override AssemblyNode VisitAssembly(AssemblyNode assembly)
+ {
+ if (assembly == null) return null;
+ this.FindTypesToBeDuplicated(assembly.Types);
+ return base.VisitAssembly((AssemblyNode)assembly.Clone());
+ }
+ public override AssemblyReference VisitAssemblyReference(AssemblyReference assemblyReference)
+ {
+ if (assemblyReference == null) return null;
+ return base.VisitAssemblyReference((AssemblyReference)assemblyReference.Clone());
+ }
+#if !MinimalReader
+ public override Statement VisitAssertion(Assertion assertion)
+ {
+ if (assertion == null) return null;
+ return base.VisitAssertion((Assertion)assertion.Clone());
+ }
+ public override Statement VisitAssumption(Assumption Assumption)
+ {
+ if (Assumption == null) return null;
+ return base.VisitAssumption((Assumption)Assumption.Clone());
+ }
+ public override Expression VisitAssignmentExpression(AssignmentExpression assignment)
+ {
+ if (assignment == null) return null;
+ return base.VisitAssignmentExpression((AssignmentExpression)assignment.Clone());
+ }
+#endif
+ public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
+ {
+ if (assignment == null) return null;
+ return base.VisitAssignmentStatement((AssignmentStatement)assignment.Clone());
+ }
+ public override Expression VisitAttributeConstructor(AttributeNode attribute)
+ {
+ if (attribute == null || attribute.Constructor == null) return null;
+ return this.VisitExpression((Expression)attribute.Constructor.Clone());
+ }
+ public override AttributeNode VisitAttributeNode(AttributeNode attribute)
+ {
+ if (attribute == null) return null;
+ return base.VisitAttributeNode((AttributeNode)attribute.Clone());
+ }
+ public override AttributeList VisitAttributeList(AttributeList attributes)
+ {
+ if (attributes == null) return null;
+ return base.VisitAttributeList(attributes.Clone());
+ }
+#if !MinimalReader
+ public override Expression VisitBase(Base Base)
+ {
+ if (Base == null) return null;
+ return base.VisitBase((Base)Base.Clone());
+ }
+#endif
+ public override Expression VisitBinaryExpression(BinaryExpression binaryExpression)
+ {
+ if (binaryExpression == null) return null;
+ binaryExpression = (BinaryExpression)base.VisitBinaryExpression((BinaryExpression)binaryExpression.Clone());
+ return binaryExpression;
+ }
+ public override Block VisitBlock(Block block)
+ {
+ if (block == null) return null;
+ Block dup = (Block)this.DuplicateFor[block.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[block.UniqueKey] = dup = (Block)block.Clone();
+ return base.VisitBlock(dup);
+ }
+#if !MinimalReader
+ public override Expression VisitBlockExpression(BlockExpression blockExpression)
+ {
+ if (blockExpression == null) return null;
+ return base.VisitBlockExpression((BlockExpression)blockExpression.Clone());
+ }
+#endif
+ public override BlockList VisitBlockList(BlockList blockList)
+ {
+ if (blockList == null) return null;
+ return base.VisitBlockList(blockList.Clone());
+ }
+ public override Statement VisitBranch(Branch branch)
+ {
+ if (branch == null) return null;
+ branch = (Branch)base.VisitBranch((Branch)branch.Clone());
+ if (branch == null) return null;
+ branch.Target = this.VisitBlock(branch.Target);
+ return branch;
+ }
+#if !MinimalReader
+ public override Statement VisitCatch(Catch Catch)
+ {
+ if (Catch == null) return null;
+ return base.VisitCatch((Catch)Catch.Clone());
+ }
+ public override CatchList VisitCatchList(CatchList catchers)
+ {
+ if (catchers == null) return null;
+ return base.VisitCatchList(catchers.Clone());
+ }
+ public override Expression VisitCoerceTuple(CoerceTuple coerceTuple)
+ {
+ if (coerceTuple == null) return null;
+ return base.VisitCoerceTuple((CoerceTuple)coerceTuple.Clone());
+ }
+ public override CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce)
+ {
+ if (ce == null) return null;
+ return base.VisitCollectionEnumerator((CollectionEnumerator)ce.Clone());
+ }
+ public override Compilation VisitCompilation(Compilation compilation)
+ {
+ if (compilation == null || compilation.TargetModule == null) return null;
+ this.FindTypesToBeDuplicated(compilation.TargetModule.Types);
+ return base.VisitCompilation((Compilation)compilation.Clone());
+ }
+ public override CompilationUnit VisitCompilationUnit(CompilationUnit cUnit)
+ {
+ if (cUnit == null) return null;
+ this.FindTypesToBeDuplicated(cUnit.Nodes);
+ return base.VisitCompilationUnit((CompilationUnit)cUnit.Clone());
+ }
+ public override CompilationUnit VisitCompilationUnitSnippet(CompilationUnitSnippet snippet)
+ {
+ if (snippet == null) return null;
+ return base.VisitCompilationUnitSnippet((CompilationUnitSnippet)snippet.Clone());
+ }
+ public override Node VisitComposition(Composition comp)
+ {
+ if (comp == null) return null;
+ return base.VisitComposition((Composition)comp.Clone());
+ }
+#endif
+ public override Expression VisitConstruct(Construct cons)
+ {
+ if (cons == null) return null;
+ return base.VisitConstruct((Construct)cons.Clone());
+ }
+ public override Expression VisitConstructArray(ConstructArray consArr)
+ {
+ if (consArr == null) return null;
+ return base.VisitConstructArray((ConstructArray)consArr.Clone());
+ }
+#if !MinimalReader
+ public override Expression VisitConstructDelegate(ConstructDelegate consDelegate)
+ {
+ if (consDelegate == null) return null;
+ return base.VisitConstructDelegate((ConstructDelegate)consDelegate.Clone());
+ }
+ public override Expression VisitConstructFlexArray(ConstructFlexArray consArr)
+ {
+ if (consArr == null) return null;
+ return base.VisitConstructFlexArray((ConstructFlexArray)consArr.Clone());
+ }
+ public override Expression VisitConstructIterator(ConstructIterator consIterator)
+ {
+ if (consIterator == null) return null;
+ return base.VisitConstructIterator((ConstructIterator)consIterator.Clone());
+ }
+ public override Expression VisitConstructTuple(ConstructTuple consTuple)
+ {
+ if (consTuple == null) return null;
+ return base.VisitConstructTuple((ConstructTuple)consTuple.Clone());
+ }
+#endif
+#if ExtendedRuntime
+ public override TypeNode VisitConstrainedType(ConstrainedType cType){
+ if (cType == null) return null;
+ return base.VisitConstrainedType((ConstrainedType)cType.Clone());
+ }
+#endif
+#if !MinimalReader
+ public override Statement VisitContinue(Continue Continue)
+ {
+ if (Continue == null) return null;
+ return base.VisitContinue((Continue)Continue.Clone());
+ }
+ public override Expression VisitCurrentClosure(CurrentClosure currentClosure)
+ {
+ if (currentClosure == null) return null;
+ return base.VisitCurrentClosure((CurrentClosure)currentClosure.Clone());
+ }
+#endif
+ public override DelegateNode VisitDelegateNode(DelegateNode delegateNode)
+ {
+ return this.VisitTypeNode(delegateNode) as DelegateNode;
+ }
+#if !MinimalReader
+ public override Statement VisitDoWhile(DoWhile doWhile)
+ {
+ if (doWhile == null) return null;
+ return base.VisitDoWhile((DoWhile)doWhile.Clone());
+ }
+#endif
+ public override Statement VisitEndFilter(EndFilter endFilter)
+ {
+ if (endFilter == null) return null;
+ return base.VisitEndFilter((EndFilter)endFilter.Clone());
+ }
+ public override Statement VisitEndFinally(EndFinally endFinally)
+ {
+ if (endFinally == null) return null;
+ return base.VisitEndFinally((EndFinally)endFinally.Clone());
+ }
+#if ExtendedRuntime
+ public override EnsuresList VisitEnsuresList(EnsuresList Ensures){
+ if (Ensures == null) return null;
+ return base.VisitEnsuresList(Ensures.Clone());
+ }
+#endif
+ public override Event VisitEvent(Event evnt)
+ {
+ if (evnt == null) return null;
+ Event dup = (Event)this.DuplicateFor[evnt.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[evnt.UniqueKey] = dup = (Event)evnt.Clone();
+#if !NoXml
+ if (this.CopyDocumentation) dup.Documentation = evnt.Documentation;
+#endif
+ dup.HandlerAdder = this.VisitMethod(evnt.HandlerAdder);
+ dup.HandlerCaller = this.VisitMethod(evnt.HandlerCaller);
+ dup.HandlerRemover = this.VisitMethod(evnt.HandlerRemover);
+ dup.OtherMethods = this.VisitMethodList(evnt.OtherMethods);
+ dup.DeclaringType = this.TargetType;
+ return base.VisitEvent(dup);
+ }
+#if !FxCop
+ public virtual ExceptionHandler VisitExceptionHandler(ExceptionHandler handler)
+ {
+ if (handler == null) return null;
+ handler = (ExceptionHandler)handler.Clone();
+ handler.BlockAfterHandlerEnd = this.VisitBlock(handler.BlockAfterHandlerEnd);
+ handler.BlockAfterTryEnd = this.VisitBlock(handler.BlockAfterTryEnd);
+ handler.FilterExpression = this.VisitBlock(handler.FilterExpression);
+ handler.FilterType = this.VisitTypeReference(handler.FilterType);
+ handler.HandlerStartBlock = this.VisitBlock(handler.HandlerStartBlock);
+ handler.TryStartBlock = this.VisitBlock(handler.TryStartBlock);
+ return handler;
+ }
+ public virtual ExceptionHandlerList VisitExceptionHandlerList(ExceptionHandlerList handlers)
+ {
+ if (handlers == null) return null;
+ int n = handlers.Count;
+ ExceptionHandlerList result = new ExceptionHandlerList(n);
+ for (int i = 0; i < n; i++)
+ result.Add(this.VisitExceptionHandler(handlers[i]));
+ return result;
+ }
+#endif
+#if ExtendedRuntime
+ public override EnsuresExceptional VisitEnsuresExceptional(EnsuresExceptional exceptional)
+ {
+ if (exceptional == null) return null;
+ return base.VisitEnsuresExceptional((EnsuresExceptional)exceptional.Clone());
+ }
+#endif
+#if !MinimalReader
+ public override Statement VisitExit(Exit exit)
+ {
+ if (exit == null) return null;
+ return base.VisitExit((Exit)exit.Clone());
+ }
+ public override Statement VisitExpose(Expose Expose)
+ {
+ if (Expose == null) return null;
+ return base.VisitExpose((Expose)Expose.Clone());
+ }
+#endif
+ public override Expression VisitExpression(Expression expression)
+ {
+ if (expression == null) return null;
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ case NodeType.Arglist:
+ expression = (Expression)expression.Clone();
+ break;
+ case NodeType.Pop:
+ UnaryExpression uex = expression as UnaryExpression;
+ if (uex != null)
+ {
+ uex = (UnaryExpression)uex.Clone();
+ uex.Operand = this.VisitExpression(uex.Operand);
+ expression = uex;
+ }
+ else
+ expression = (Expression)expression.Clone();
+ break;
+ default:
+ expression = (Expression)this.Visit(expression);
+ break;
+ }
+ if (expression == null) return null;
+ expression.Type = this.VisitTypeReference(expression.Type);
+ return expression;
+ }
+ public override ExpressionList VisitExpressionList(ExpressionList expressions)
+ {
+ if (expressions == null) return null;
+ return base.VisitExpressionList(expressions.Clone());
+ }
+#if !MinimalReader
+ public override Expression VisitExpressionSnippet(ExpressionSnippet snippet)
+ {
+ if (snippet == null) return null;
+ return base.VisitExpressionSnippet((ExpressionSnippet)snippet.Clone());
+ }
+#endif
+ public override Statement VisitExpressionStatement(ExpressionStatement statement)
+ {
+ if (statement == null) return null;
+ return base.VisitExpressionStatement((ExpressionStatement)statement.Clone());
+ }
+#if !MinimalReader
+ public override Statement VisitFaultHandler(FaultHandler faultHandler)
+ {
+ if (faultHandler == null) return null;
+ return base.VisitFaultHandler((FaultHandler)faultHandler.Clone());
+ }
+ public override FaultHandlerList VisitFaultHandlerList(FaultHandlerList faultHandlers)
+ {
+ if (faultHandlers == null) return null;
+ return base.VisitFaultHandlerList(faultHandlers.Clone());
+ }
+#endif
+ public override Field VisitField(Field field)
+ {
+ if (field == null) return null;
+ Field dup = (Field)this.DuplicateFor[field.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[field.UniqueKey] = dup = (Field)field.Clone();
+ if (field.MarshallingInformation != null)
+ dup.MarshallingInformation = field.MarshallingInformation.Clone();
+#if !MinimalReader
+ ParameterField pField = dup as ParameterField;
+ if (pField != null)
+ pField.Parameter = (Parameter)this.VisitParameter(pField.Parameter);
+#endif
+ dup.DeclaringType = this.TargetType;
+#if !NoXml
+ if (this.CopyDocumentation) dup.Documentation = field.Documentation;
+#endif
+ return base.VisitField(dup);
+ }
+#if !MinimalReader
+ public override Block VisitFieldInitializerBlock(FieldInitializerBlock block)
+ {
+ if (block == null) return null;
+ return base.VisitFieldInitializerBlock((FieldInitializerBlock)block.Clone());
+ }
+ public override FieldList VisitFieldList(FieldList fields)
+ {
+ if (fields == null) return null;
+ return base.VisitFieldList(fields.Clone());
+ }
+ public override Statement VisitFilter(Filter filter)
+ {
+ if (filter == null) return null;
+ return base.VisitFilter((Filter)filter.Clone());
+ }
+ public override FilterList VisitFilterList(FilterList filters)
+ {
+ if (filters == null) return null;
+ return base.VisitFilterList(filters.Clone());
+ }
+ public override Statement VisitFinally(Finally Finally)
+ {
+ if (Finally == null) return null;
+ return base.VisitFinally((Finally)Finally.Clone());
+ }
+ public override Statement VisitFixed(Fixed Fixed)
+ {
+ if (Fixed == null) return null;
+ return base.VisitFixed((Fixed)Fixed.Clone());
+ }
+ public override Statement VisitFor(For For)
+ {
+ if (For == null) return null;
+ return base.VisitFor((For)For.Clone());
+ }
+ public override Statement VisitForEach(ForEach forEach)
+ {
+ if (forEach == null) return null;
+ return base.VisitForEach((ForEach)forEach.Clone());
+ }
+ public override Statement VisitFunctionDeclaration(FunctionDeclaration functionDeclaration)
+ {
+ if (functionDeclaration == null) return null;
+ return base.VisitFunctionDeclaration((FunctionDeclaration)functionDeclaration.Clone());
+ }
+ public override Statement VisitGoto(Goto Goto)
+ {
+ if (Goto == null) return null;
+ return base.VisitGoto((Goto)Goto.Clone());
+ }
+ public override Statement VisitGotoCase(GotoCase gotoCase)
+ {
+ if (gotoCase == null) return null;
+ return base.VisitGotoCase((GotoCase)gotoCase.Clone());
+ }
+#endif
+ public override Expression VisitIdentifier(Identifier identifier)
+ {
+ if (identifier == null) return null;
+ return base.VisitIdentifier((Identifier)identifier.Clone());
+ }
+#if !MinimalReader
+ public override Statement VisitIf(If If)
+ {
+ if (If == null) return null;
+ return base.VisitIf((If)If.Clone());
+ }
+ public override Expression VisitImplicitThis(ImplicitThis implicitThis)
+ {
+ if (implicitThis == null) return null;
+ return base.VisitImplicitThis((ImplicitThis)implicitThis.Clone());
+ }
+#endif
+ public override Expression VisitIndexer(Indexer indexer)
+ {
+ if (indexer == null) return null;
+ indexer = (Indexer)base.VisitIndexer((Indexer)indexer.Clone());
+ if (indexer == null) return null;
+ indexer.ElementType = this.VisitTypeReference(indexer.ElementType);
+ return indexer;
+ }
+ public override InterfaceList VisitInterfaceReferenceList(InterfaceList interfaceReferences)
+ {
+ if (interfaceReferences == null) return null;
+ return base.VisitInterfaceReferenceList(interfaceReferences.Clone());
+ }
+#if ExtendedRuntime
+ public override InvariantList VisitInvariantList(InvariantList Invariants){
+ if (Invariants == null) return null;
+ return base.VisitInvariantList(Invariants.Clone());
+ }
+#endif
+#if !MinimalReader
+ public override Statement VisitLabeledStatement(LabeledStatement lStatement)
+ {
+ if (lStatement == null) return null;
+ return base.VisitLabeledStatement((LabeledStatement)lStatement.Clone());
+ }
+#endif
+ public override Expression VisitLiteral(Literal literal)
+ {
+ if (literal == null) return null;
+ TypeNode t = literal.Value as TypeNode;
+ if (t != null)
+ return new Literal(this.VisitTypeReference(t), literal.Type, literal.SourceContext);
+ ArrayType at = literal.Type as ArrayType;
+ if (at != null && at.ElementType is TypeNode)
+ {
+ TypeNode cloneType = this.VisitTypeReference(literal.Type);
+ TypeNode[] val = literal.Value as TypeNode[];
+ int len = val == null ? 0 : val.Length;
+ TypeNode[] newVal = val == null ? null : new TypeNode[len];
+ for (int i = 0; i < len; i++)
+ {
+ newVal[i] = this.VisitTypeReference(val[i]);
+ }
+ return new Literal(newVal, cloneType);
+ }
+ return (Literal)literal.Clone();
+ }
+ public override Expression VisitLocal(Local local)
+ {
+ if (local == null) return null;
+ Local dup = (Local)this.DuplicateFor[local.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[local.UniqueKey] = dup = (Local)local.Clone();
+ return base.VisitLocal(dup);
+ }
+#if !MinimalReader
+ public override LocalDeclaration VisitLocalDeclaration(LocalDeclaration localDeclaration)
+ {
+ if (localDeclaration == null) return null;
+ return base.VisitLocalDeclaration((LocalDeclaration)localDeclaration.Clone());
+ }
+ public override LocalDeclarationList VisitLocalDeclarationList(LocalDeclarationList localDeclarations)
+ {
+ if (localDeclarations == null) return null;
+ return base.VisitLocalDeclarationList(localDeclarations.Clone());
+ }
+ public override Statement VisitLocalDeclarationsStatement(LocalDeclarationsStatement localDeclarations)
+ {
+ if (localDeclarations == null) return null;
+ return base.VisitLocalDeclarationsStatement((LocalDeclarationsStatement)localDeclarations.Clone());
+ }
+ public override Statement VisitLock(Lock Lock)
+ {
+ if (Lock == null) return null;
+ return base.VisitLock((Lock)Lock.Clone());
+ }
+ public override Statement VisitAcquire(Acquire acquire)
+ {
+ if (acquire == null) return null;
+ return base.VisitAcquire((Acquire)acquire.Clone());
+ }
+ public override Statement VisitResourceUse(ResourceUse resourceUse)
+ {
+ if (resourceUse == null) return null;
+ return base.VisitResourceUse((ResourceUse)resourceUse.Clone());
+ }
+ public override Expression VisitLRExpression(LRExpression expr)
+ {
+ if (expr == null) return null;
+ return base.VisitLRExpression((LRExpression)expr.Clone());
+ }
+#endif
+ public override Expression VisitMemberBinding(MemberBinding memberBinding)
+ {
+ if (memberBinding == null) return null;
+ memberBinding = (MemberBinding)memberBinding.Clone();
+ memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject);
+ memberBinding.Type = this.VisitTypeReference(memberBinding.Type);
+ memberBinding.BoundMember = this.VisitMemberReference(memberBinding.BoundMember);
+ return memberBinding;
+ }
+ public override MemberList VisitMemberList(MemberList members)
+ {
+ if (members == null) return null;
+ return base.VisitMemberList(members.Clone());
+ }
+ public virtual Member VisitMemberReference(Member member)
+ {
+ if (member == null) return null;
+ Member dup = (Member)this.DuplicateFor[member.UniqueKey];
+ if (dup != null) return dup;
+#if !MinimalReader
+ if (member is ParameterField && !(member.DeclaringType is ClosureClass)) return member; //Can happen when duplicating expressions within a method
+#endif
+ TypeNode t = member as TypeNode;
+ if (t != null) member = this.VisitTypeReference(t);
+ if (member == null) return null;
+ Method method = member as Method;
+ if (method != null && method.Template != null && method.TemplateArguments != null && method.TemplateArguments.Count > 0)
+ {
+ Method template = this.VisitMemberReference(method.Template) as Method;
+ bool needNewInstance = template != null && template != method.Template;
+ TypeNodeList args = method.TemplateArguments.Clone();
+ for (int i = 0, n = args.Count; i < n; i++)
+ {
+ TypeNode arg = this.VisitTypeReference(args[i]);
+ if (arg != null && arg != args[i])
+ {
+ args[i] = arg;
+ needNewInstance = true;
+ }
+ }
+ if (needNewInstance)
+ {
+ //^ assert template != null;
+ return template.GetTemplateInstance(this.TargetType, args);
+ }
+ return method;
+ }
+ TypeNode declaringType = member.DeclaringType;
+ if (declaringType == null) return member;
+ if (declaringType.Template == null && this.TypesToBeDuplicated[declaringType.UniqueKey] == null) return member;
+ TypeNode tgtType = this.VisitTypeReference(declaringType); //duplicates its members
+ if (tgtType == null) return null;
+ dup = (Member)this.DuplicateFor[member.UniqueKey];
+ if (dup == null)
+ {
+ if (declaringType.Template != null)
+ {
+ if (tgtType != declaringType && tgtType != null)
+ return Specializer.GetCorrespondingMember(member, tgtType);
+ return member;
+ }
+ //Can get here when tgtType has not yet been completely duplicated
+ TypeNode savedTargetType = this.TargetType;
+ this.TargetType = tgtType;
+ dup = (Member)this.Visit(member);
+ this.TargetType = savedTargetType;
+ }
+ return dup;
+ }
+ public virtual MemberList VisitMemberReferenceList(MemberList members)
+ {
+ if (members == null) return null;
+ int n = members.Count;
+ MemberList dup = new MemberList(n);
+ for (int i = 0; i < n; i++)
+ dup.Add(this.VisitMemberReference(members[i]));
+ return dup;
+ }
+ public readonly Block DummyBody = new Block();
+ public override Method VisitMethod(Method method)
+ {
+ if (method == null) return null;
+ Method dup = (Method)this.DuplicateFor[method.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[method.UniqueKey] = dup = (Method)method.Clone();
+ dup.ProviderHandle = null;
+ if (TargetPlatform.UseGenerics)
+ {
+ this.FindTypesToBeDuplicated(method.TemplateParameters);
+ }
+#if !FxCop
+ dup.LocalList = null;
+#endif
+ Method savedTarget = this.TargetMethod;
+ this.TargetMethod = dup;
+ if (TargetPlatform.UseGenerics)
+ {
+ dup.TemplateParameters = this.VisitTypeParameterList(method.TemplateParameters);
+ }
+#if !MinimalReader
+ if (dup.Scope != null)
+ {
+ this.TypesToBeDuplicated[dup.Scope.UniqueKey] = dup.Scope;
+ dup.Scope = this.VisitTypeNode(dup.Scope) as MethodScope;
+ }
+#endif
+ dup.DeclaringMember = this.VisitMemberReference(dup.DeclaringMember);
+#if !NoXml
+ if (this.CopyDocumentation) dup.Documentation = method.Documentation;
+#endif
+ dup.ImplementedInterfaceMethods = this.VisitMethodReferenceList(method.ImplementedInterfaceMethods);
+ dup.DeclaringType = this.TargetType;
+ if (!method.IsAbstract) dup.Body = this.DummyBody;
+ if (this.RecordOriginalAsTemplate)
+ {
+ if (method.Template != null)
+ dup.Template = method.Template;
+ else
+ dup.Template = method;
+ }
+ dup.PInvokeModule = this.VisitModuleReference(dup.PInvokeModule);
+ if (method.ReturnTypeMarshallingInformation != null)
+ dup.ReturnTypeMarshallingInformation = method.ReturnTypeMarshallingInformation.Clone();
+ dup.ThisParameter = (This)this.VisitParameter(dup.ThisParameter);
+ dup = base.VisitMethod(dup);
+ //^ assume dup != null;
+ dup.fullName = null;
+#if !NoXml
+ dup.DocumentationId = null;
+#endif
+ dup.ProviderHandle = method; // we always need the handle, as we may use it for attributes.
+ dup.Attributes = null;
+ dup.ProvideMethodAttributes = new Method.MethodAttributeProvider(this.ProvideMethodAttributes);
+ if (!this.SkipBodies && !method.IsAbstract)
+ {
+ dup.Body = null;
+ dup.ProvideBody = new Method.MethodBodyProvider(this.ProvideMethodBody);
+ }
+ if (this.SkipBodies) dup.Instructions = new InstructionList(0);
+
+ this.TargetMethod = savedTarget;
+ return dup;
+ }
+ public override Expression VisitMethodCall(MethodCall call)
+ {
+ if (call == null) return null;
+ return base.VisitMethodCall((MethodCall)call.Clone());
+ }
+#if ExtendedRuntime
+ public override MethodContract VisitMethodContract(MethodContract contract)
+ {
+ if (contract == null) return null;
+ contract = (MethodContract)contract.Clone();
+ //^ assume this.TargetMethod != null;
+ contract.DeclaringMethod = this.TargetMethod;
+ contract.ensures = this.VisitEnsuresList(contract.ensures);
+ contract.modifies = this.VisitExpressionList(contract.modifies);
+ contract.requires = this.VisitRequiresList(contract.requires);
+ return contract;
+ }
+#endif
+ public virtual MethodList VisitMethodList(MethodList methods)
+ {
+ if (methods == null) return null;
+ int n = methods.Count;
+ MethodList dup = new MethodList(n);
+ for (int i = 0; i < n; i++)
+ dup.Add(this.VisitMethod(methods[i]));
+ return dup;
+ }
+ public virtual MethodList VisitMethodReferenceList(MethodList methods)
+ {
+ if (methods == null) return null;
+ int n = methods.Count;
+ MethodList dup = new MethodList(n);
+ for (int i = 0; i < n; i++)
+ dup.Add((Method)this.VisitMemberReference(methods[i]));
+ return dup;
+ }
+ public override Module VisitModule(Module module)
+ {
+ if (module == null) return null;
+ Module dup = (Module)module.Clone();
+ if (this.TargetModule == null) this.TargetModule = dup;
+ this.FindTypesToBeDuplicated(module.Types);
+ return base.VisitModule(dup);
+ }
+ public virtual Module VisitModuleReference(Module module)
+ {
+ if (module == null) return null;
+ Module dup = (Module)this.DuplicateFor[module.UniqueKey];
+ if (dup != null) return dup;
+ for (int i = 0, n = this.TargetModule.ModuleReferences == null ? 0 : this.TargetModule.ModuleReferences.Count; i < n; i++)
+ {
+ //^ assert this.TargetModule.ModuleReferences != null;
+ ModuleReference modRef = this.TargetModule.ModuleReferences[i];
+ if (modRef == null) continue;
+ if (string.Compare(module.Name, modRef.Name, true, System.Globalization.CultureInfo.InvariantCulture) != 0) continue;
+ this.DuplicateFor[module.UniqueKey] = modRef.Module; return modRef.Module;
+ }
+ if (this.TargetModule.ModuleReferences == null)
+ this.TargetModule.ModuleReferences = new ModuleReferenceList();
+ this.TargetModule.ModuleReferences.Add(new ModuleReference(module.Name, module));
+ this.DuplicateFor[module.UniqueKey] = module;
+ return module;
+ }
+ public override ModuleReference VisitModuleReference(ModuleReference moduleReference)
+ {
+ if (moduleReference == null) return null;
+ return base.VisitModuleReference((ModuleReference)moduleReference.Clone());
+ }
+#if !MinimalReader
+ public override Expression VisitNameBinding(NameBinding nameBinding)
+ {
+ if (nameBinding == null) return null;
+ nameBinding = (NameBinding)nameBinding.Clone();
+ nameBinding.BoundMember = this.VisitExpression(nameBinding.BoundMember);
+ nameBinding.BoundMembers = this.VisitMemberReferenceList(nameBinding.BoundMembers);
+ return nameBinding;
+ }
+#endif
+ public override Expression VisitNamedArgument(NamedArgument namedArgument)
+ {
+ if (namedArgument == null) return null;
+ return base.VisitNamedArgument((NamedArgument)namedArgument.Clone());
+ }
+#if !MinimalReader
+ public override Namespace VisitNamespace(Namespace nspace)
+ {
+ if (nspace == null) return null;
+ return base.VisitNamespace((Namespace)nspace.Clone());
+ }
+ public override NamespaceList VisitNamespaceList(NamespaceList namespaces)
+ {
+ if (namespaces == null) return null;
+ return base.VisitNamespaceList(namespaces.Clone());
+ }
+ public override NodeList VisitNodeList(NodeList nodes)
+ {
+ if (nodes == null) return null;
+ return base.VisitNodeList(nodes.Clone());
+ }
+#endif
+#if ExtendedRuntime
+ public override EnsuresNormal VisitEnsuresNormal(EnsuresNormal normal)
+ {
+ if (normal == null) return null;
+ return base.VisitEnsuresNormal((EnsuresNormal)normal.Clone());
+ }
+ public override Expression VisitOldExpression(OldExpression oldExpression) {
+ if (oldExpression == null) return null;
+ return base.VisitOldExpression((OldExpression)oldExpression.Clone());
+ }
+ public override RequiresOtherwise VisitRequiresOtherwise(RequiresOtherwise otherwise)
+ {
+ if (otherwise == null) return null;
+ return base.VisitRequiresOtherwise((RequiresOtherwise)otherwise.Clone());
+ }
+#endif
+ public override Expression VisitParameter(Parameter parameter)
+ {
+ if (parameter == null) return null;
+ Parameter dup = (Parameter)this.DuplicateFor[parameter.UniqueKey];
+ if (dup != null)
+ {
+ if (dup.DeclaringMethod == null) dup.DeclaringMethod = this.TargetMethod;
+ return dup;
+ }
+ this.DuplicateFor[parameter.UniqueKey] = dup = (Parameter)parameter.Clone();
+ if (dup.MarshallingInformation != null)
+ dup.MarshallingInformation = dup.MarshallingInformation.Clone();
+ dup.DeclaringMethod = this.TargetMethod;
+ return base.VisitParameter(dup);
+ }
+ public override ParameterList VisitParameterList(ParameterList parameterList)
+ {
+ if (parameterList == null) return null;
+ return base.VisitParameterList(parameterList.Clone());
+ }
+#if ExtendedRuntime
+ public override RequiresPlain VisitRequiresPlain(RequiresPlain plain)
+ {
+ if (plain == null) return null;
+ return base.VisitRequiresPlain((RequiresPlain)plain.Clone());
+ }
+#endif
+#if !MinimalReader
+ public override Expression VisitPrefixExpression(PrefixExpression pExpr)
+ {
+ if (pExpr == null) return null;
+ return base.VisitPrefixExpression((PrefixExpression)pExpr.Clone());
+ }
+ public override Expression VisitPostfixExpression(PostfixExpression pExpr)
+ {
+ if (pExpr == null) return null;
+ return base.VisitPostfixExpression((PostfixExpression)pExpr.Clone());
+ }
+#endif
+ public override Property VisitProperty(Property property)
+ {
+ if (property == null) return null;
+ Property dup = (Property)this.DuplicateFor[property.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[property.UniqueKey] = dup = (Property)property.Clone();
+ dup.Attributes = this.VisitAttributeList(property.Attributes);
+#if !NoXml
+ if (this.CopyDocumentation) dup.Documentation = property.Documentation;
+#endif
+ dup.Type = this.VisitTypeReference(property.Type);
+ dup.Getter = this.VisitMethod(property.Getter);
+ dup.Setter = this.VisitMethod(property.Setter);
+ dup.OtherMethods = this.VisitMethodList(property.OtherMethods);
+ dup.DeclaringType = this.TargetType;
+ dup.Parameters = this.VisitParameterList(dup.Parameters);
+ return dup;
+ }
+#if !MinimalReader
+ public override Expression VisitQuantifier(Quantifier quantifier)
+ {
+ if (quantifier == null) return null;
+ return base.VisitQuantifier((Quantifier)quantifier.Clone());
+ }
+ public override Expression VisitComprehension(Comprehension Comprehension)
+ {
+ if (Comprehension == null) return null;
+ return base.VisitComprehension((Comprehension)Comprehension.Clone());
+ }
+ public override ComprehensionBinding VisitComprehensionBinding(ComprehensionBinding comprehensionBinding)
+ {
+ if (comprehensionBinding == null) return null;
+ return base.VisitComprehensionBinding((ComprehensionBinding)comprehensionBinding.Clone());
+ }
+ public override Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier)
+ {
+ if (qualifiedIdentifier == null) return null;
+ return base.VisitQualifiedIdentifier((QualifiedIdentifier)qualifiedIdentifier.Clone());
+ }
+ public override Statement VisitRepeat(Repeat repeat)
+ {
+ if (repeat == null) return null;
+ return base.VisitRepeat((Repeat)repeat.Clone());
+ }
+#endif
+#if ExtendedRuntime
+ public override RequiresList VisitRequiresList(RequiresList Requires)
+ {
+ if (Requires == null) return null;
+ return base.VisitRequiresList(Requires.Clone());
+ }
+#endif
+ public override Statement VisitReturn(Return Return)
+ {
+ if (Return == null) return null;
+ return base.VisitReturn((Return)Return.Clone());
+ }
+ public override SecurityAttribute VisitSecurityAttribute(SecurityAttribute attribute)
+ {
+ if (attribute == null) return null;
+ return base.VisitSecurityAttribute((SecurityAttribute)attribute.Clone()); ;
+ }
+ public override SecurityAttributeList VisitSecurityAttributeList(SecurityAttributeList attributes)
+ {
+ if (attributes == null) return null;
+ return base.VisitSecurityAttributeList(attributes.Clone());
+ }
+#if !MinimalReader
+ public override Expression VisitSetterValue(SetterValue value)
+ {
+ if (value == null) return null;
+ return base.VisitSetterValue((SetterValue)value.Clone());
+ }
+#endif
+ public override StatementList VisitStatementList(StatementList statements)
+ {
+ if (statements == null) return null;
+ return base.VisitStatementList(statements.Clone());
+ }
+#if !MinimalReader
+ public override StatementSnippet VisitStatementSnippet(StatementSnippet snippet)
+ {
+ if (snippet == null) return null;
+ return base.VisitStatementSnippet((StatementSnippet)snippet.Clone());
+ }
+ public override Statement VisitSwitch(Switch Switch)
+ {
+ if (Switch == null) return null;
+ return base.VisitSwitch((Switch)Switch.Clone());
+ }
+ public override SwitchCase VisitSwitchCase(SwitchCase switchCase)
+ {
+ if (switchCase == null) return null;
+ return base.VisitSwitchCase((SwitchCase)switchCase.Clone());
+ }
+ public override SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases)
+ {
+ if (switchCases == null) return null;
+ return base.VisitSwitchCaseList(switchCases.Clone());
+ }
+#endif
+ public override Statement VisitSwitchInstruction(SwitchInstruction switchInstruction)
+ {
+ if (switchInstruction == null) return null;
+ switchInstruction = (SwitchInstruction)base.VisitSwitchInstruction((SwitchInstruction)switchInstruction.Clone());
+ if (switchInstruction == null) return null;
+ switchInstruction.Targets = this.VisitBlockList(switchInstruction.Targets);
+ return switchInstruction;
+ }
+#if !MinimalReader
+ public override Statement VisitTypeswitch(Typeswitch Typeswitch)
+ {
+ if (Typeswitch == null) return null;
+ return base.VisitTypeswitch((Typeswitch)Typeswitch.Clone());
+ }
+ public override TypeswitchCase VisitTypeswitchCase(TypeswitchCase typeswitchCase)
+ {
+ if (typeswitchCase == null) return null;
+ return base.VisitTypeswitchCase((TypeswitchCase)typeswitchCase.Clone());
+ }
+ public override TypeswitchCaseList VisitTypeswitchCaseList(TypeswitchCaseList typeswitchCases)
+ {
+ if (typeswitchCases == null) return null;
+ return base.VisitTypeswitchCaseList(typeswitchCases.Clone());
+ }
+#endif
+ public override Expression VisitTernaryExpression(TernaryExpression expression)
+ {
+ if (expression == null) return null;
+ return base.VisitTernaryExpression((TernaryExpression)expression.Clone());
+ }
+ public override Expression VisitThis(This This)
+ {
+ if (This == null) return null;
+ This dup = (This)this.DuplicateFor[This.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[This.UniqueKey] = dup = (This)This.Clone();
+ return base.VisitThis(dup);
+ }
+ public override Statement VisitThrow(Throw Throw)
+ {
+ if (Throw == null) return null;
+ return base.VisitThrow((Throw)Throw.Clone());
+ }
+#if !MinimalReader
+ public override Statement VisitTry(Try Try)
+ {
+ if (Try == null) return null;
+ return base.VisitTry((Try)Try.Clone());
+ }
+#endif
+#if ExtendedRuntime
+ public override TypeAlias VisitTypeAlias(TypeAlias tAlias){
+ if (tAlias == null) return null;
+ TypeAlias dup = (TypeAlias)this.DuplicateFor[tAlias.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[tAlias.UniqueKey] = dup = (TypeAlias)tAlias.Clone();
+ dup.Name = tAlias.Name;
+ if (tAlias.AliasedType is ConstrainedType)
+ //The type alias defines the constrained type, rather than just referencing it
+ dup.AliasedType = this.VisitConstrainedType((ConstrainedType)tAlias.AliasedType);
+ else
+ dup.AliasedType = this.VisitTypeReference(tAlias.AliasedType);
+ dup.DeclaringType = this.TargetType;
+ dup.DeclaringModule = this.TargetModule;
+ dup.ProvideMembers();
+ return dup;
+ }
+ public override TypeContract VisitTypeContract(TypeContract contract){
+ if (this.RecordOriginalAsTemplate) return null; //A type template instance does not need invariants
+ if (contract == null) return null;
+ contract = (TypeContract)contract.Clone();
+ contract.DeclaringType = this.VisitTypeReference(contract.DeclaringType);
+ contract.Invariants = this.VisitInvariantList(contract.invariants);
+ return contract;
+ }
+#endif
+ public override TypeModifier VisitTypeModifier(TypeModifier typeModifier)
+ {
+ if (typeModifier == null) return null;
+ return base.VisitTypeModifier((TypeModifier)typeModifier.Clone());
+ }
+ public override TypeNode VisitTypeNode(TypeNode type)
+ {
+ if (type == null) return null;
+ TypeNode dup = this.VisitTypeNode(type, null, null, null, true);
+ //^ assume dup != null;
+ TypeNodeList nestedTypes = type.NestedTypes;
+ if (nestedTypes != null && nestedTypes.Count > 0)
+ this.VisitNestedTypes(dup, nestedTypes);
+ return dup;
+ }
+ internal TypeNode VisitTypeNode(TypeNode type, Identifier mangledName, TypeNodeList templateArguments, TypeNode template, bool delayVisitToNestedTypes)
+ {
+ if (type == null) return null;
+ TypeNode dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
+ if (dup != null) return dup;
+ this.DuplicateFor[type.UniqueKey] = dup = (TypeNode)type.Clone();
+ if (mangledName != null)
+ {
+ this.TargetModule.StructurallyEquivalentType[mangledName.UniqueIdKey] = dup;
+ dup.TemplateArguments = templateArguments;
+ }
+ dup.arrayTypes = null;
+ dup.constructors = null;
+ dup.consolidatedTemplateArguments = null;
+ dup.consolidatedTemplateParameters = null;
+#if DEBUG && !MinimalReader
+ dup.DebugLabel = null;
+#endif
+#if !NoXml
+ dup.DocumentationId = null;
+ if (this.CopyDocumentation) dup.Documentation = type.Documentation;
+#endif
+ dup.defaultMembers = null;
+#if !MinimalReader
+ dup.explicitCoercionFromTable = null;
+ dup.explicitCoercionMethods = null;
+ dup.implicitCoercionFromTable = null;
+ dup.implicitCoercionMethods = null;
+ dup.implicitCoercionToTable = null;
+#endif
+ dup.memberCount = 0;
+ dup.memberTable = null;
+ dup.modifierTable = null;
+ dup.NestedTypes = null;
+ dup.pointerType = null;
+ dup.ProviderHandle = null;
+ dup.ProvideTypeAttributes = null;
+ dup.ProvideTypeMembers = null;
+ dup.ProvideNestedTypes = null;
+ dup.referenceType = null;
+#if !NoReflection
+ dup.runtimeType = null;
+#endif
+ dup.structurallyEquivalentMethod = null;
+ TypeParameter tp = dup as TypeParameter;
+ if (tp != null) tp.structuralElementTypes = null;
+ ClassParameter cp = dup as ClassParameter;
+ if (cp != null) cp.structuralElementTypes = null;
+ dup.szArrayTypes = null;
+ if (this.RecordOriginalAsTemplate) dup.Template = type;
+ dup.TemplateArguments = null;
+ dup.TemplateInstances = null;
+ dup.DeclaringModule = this.TargetModule;
+ dup.DeclaringType = this.TargetType;
+ TypeNode savedTargetType = this.TargetType;
+ this.TargetType = dup;
+ dup.Attributes = this.VisitAttributeList(type.Attributes);
+ dup.SecurityAttributes = this.VisitSecurityAttributeList(type.SecurityAttributes);
+ Class c = dup as Class;
+ if (c != null) c.BaseClass = (Class)this.VisitTypeReference(c.BaseClass);
+ dup.Interfaces = this.VisitInterfaceReferenceList(dup.Interfaces);
+ dup.TemplateParameters = this.VisitTypeReferenceList(type.TemplateParameters);
+ dup.consolidatedTemplateParameters = null;
+#if !MinimalReader
+ if (dup is MethodScope)
+ dup.members = this.VisitMemberList(type.members);
+ else
+#endif
+ if (!this.RecordOriginalAsTemplate)
+ {
+ if (!delayVisitToNestedTypes)
+ dup.nestedTypes = this.VisitNestedTypes(dup, type.NestedTypes);
+ dup.members = null;
+ dup.ProvideTypeMembers = new TypeNode.TypeMemberProvider(this.ProvideTypeMembers);
+ dup.ProviderHandle = type;
+ }
+ else
+ {
+ dup.members = null;
+ dup.ProvideNestedTypes = new TypeNode.NestedTypeProvider(this.ProvideNestedTypes);
+ dup.ProvideTypeMembers = new TypeNode.TypeMemberProvider(this.ProvideTypeMembers);
+ dup.ProviderHandle = type;
+ }
+ DelegateNode delegateNode = dup as DelegateNode;
+ if (delegateNode != null)
+ {
+#if !MinimalReader
+ if (!delegateNode.IsNormalized || !this.RecordOriginalAsTemplate)
+ {
+ if (!delegateNode.IsNormalized)
+ ((DelegateNode)type).ProvideMembers();
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ }
+ else
+#endif
+ {
+ delegateNode.Parameters = null;
+ delegateNode.ReturnType = null;
+ }
+ }
+ dup.membersBeingPopulated = false;
+ this.TargetType = savedTargetType;
+ return dup;
+ }
+ private void ProvideNestedTypes(TypeNode/*!*/ dup, object/*!*/ handle)
+ {
+ TypeNode template = (TypeNode)handle;
+ TypeNode savedTargetType = this.TargetType;
+ Module savedTargetModule = this.TargetModule;
+ this.TargetType = dup;
+ //^ assume dup.DeclaringModule != null;
+ this.TargetModule = dup.DeclaringModule;
+ this.FindTypesToBeDuplicated(template.NestedTypes);
+ dup.NestedTypes = this.VisitNestedTypes(dup, template.NestedTypes);
+ this.TargetModule = savedTargetModule;
+ this.TargetType = savedTargetType;
+ }
+ private void ProvideTypeMembers(TypeNode/*!*/ dup, object/*!*/ handle)
+ {
+ TypeNode template = (TypeNode)handle;
+ Debug.Assert(!template.membersBeingPopulated);
+ TypeNode savedTargetType = this.TargetType;
+ Module savedTargetModule = this.TargetModule;
+ this.TargetType = dup;
+ //^ assume dup.DeclaringModule != null;
+ this.TargetModule = dup.DeclaringModule;
+ this.FindTypesToBeDuplicated(template.NestedTypes);
+ dup.Members = this.VisitMemberList(template.Members);
+ DelegateNode delegateNode = dup as DelegateNode;
+ if (delegateNode != null && delegateNode.IsNormalized)
+ {
+ Debug.Assert(dup.Members != null && dup.Members.Count > 0 && dup.Members[0] != null);
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ }
+ this.TargetModule = savedTargetModule;
+ this.TargetType = savedTargetType;
+ }
+ protected virtual void ProvideMethodBody(Method/*!*/ dup, object/*!*/ handle, bool asInstructionList)
+ {
+ if (asInstructionList)
+ {
+ // We don't really have a way to provide instructions, but we set it to an empty list
+ dup.Instructions = new InstructionList(0);
+ return;
+ }
+ Method template = (Method)handle;
+ Block tbody = template.Body;
+ if (tbody == null)
+ {
+ dup.ProvideBody = null;
+ return;
+ }
+ TypeNode savedTargetType = this.TargetType;
+ this.TargetType = dup.DeclaringType;
+ dup.Body = this.VisitBlock(tbody);
+#if !FxCop
+ dup.ExceptionHandlers = this.VisitExceptionHandlerList(template.ExceptionHandlers);
+#endif
+ this.TargetType = savedTargetType;
+ }
+ protected virtual void ProvideMethodAttributes(Method/*!*/ dup, object/*!*/ handle)
+ {
+ Method template = (Method)handle;
+ AttributeList tattributes = template.Attributes;
+ if (tattributes == null)
+ {
+ dup.ProvideMethodAttributes = null;
+ return;
+ }
+ TypeNode savedTargetType = this.TargetType;
+ this.TargetType = dup.DeclaringType;
+ dup.Attributes = this.VisitAttributeList(tattributes);
+ this.TargetType = savedTargetType;
+ }
+ public virtual TypeNodeList VisitNestedTypes(TypeNode/*!*/ declaringType, TypeNodeList types)
+ {
+ if (types == null) return null;
+ TypeNodeList dupTypes = types.Clone();
+ for (int i = 0, n = types.Count; i < n; i++)
+ {
+ TypeNode nt = types[i];
+ if (nt == null) continue;
+ TypeNode ntdup;
+ if (TargetPlatform.UseGenerics)
+ {
+ ntdup = dupTypes[i] = this.VisitTypeNode(nt, null, null, null, true);
+ }
+ else
+ {
+ ntdup = dupTypes[i] = this.VisitTypeReference(nt);
+ }
+ if (ntdup != nt && ntdup != null)
+ {
+ if (this.RecordOriginalAsTemplate) ntdup.Template = nt;
+ ntdup.DeclaringType = declaringType;
+ ntdup.DeclaringModule = declaringType.DeclaringModule;
+ }
+ }
+ for (int i = 0, n = types.Count; i < n; i++)
+ {
+ TypeNode nt = types[i];
+ if (nt == null) continue;
+ TypeNodeList nestedTypes = nt.NestedTypes;
+ if (nestedTypes == null || nestedTypes.Count == 0) continue;
+ TypeNode ntDup = dupTypes[i];
+ if (ntDup == null) { Debug.Fail(""); continue; }
+ this.VisitNestedTypes(ntDup, nestedTypes);
+ }
+ return dupTypes;
+ }
+ public override TypeNodeList VisitTypeNodeList(TypeNodeList types)
+ {
+ if (types == null) return null;
+ types = base.VisitTypeNodeList(types.Clone());
+ if (this.TargetModule == null) return types;
+ if (types == null) return null;
+ if (this.TargetModule.Types == null) this.TargetModule.Types = new TypeNodeList();
+ for (int i = 0, n = types.Count; i < n; i++)
+ this.TargetModule.Types.Add(types[i]);
+ return types;
+ }
+ public override TypeNode VisitTypeParameter(TypeNode typeParameter)
+ {
+ if (typeParameter == null) return null;
+ if (TargetPlatform.UseGenerics)
+ {
+ if (this.TypesToBeDuplicated[typeParameter.UniqueKey] != null)
+ {
+ TypeParameter tp = typeParameter as TypeParameter;
+ if (tp != null)
+ tp.structuralElementTypes = this.VisitTypeReferenceList(tp.StructuralElementTypes);
+ else
+ {
+ ClassParameter cp = typeParameter as ClassParameter;
+ if (cp != null)
+ cp.structuralElementTypes = this.VisitTypeReferenceList(cp.StructuralElementTypes);
+ }
+ return this.VisitTypeNode(typeParameter);
+ }
+ }
+ return base.VisitTypeParameter(typeParameter);
+ }
+ public override TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters)
+ {
+ if (typeParameters == null) return null;
+ return base.VisitTypeParameterList(typeParameters.Clone());
+ }
+ public override TypeNode VisitTypeReference(TypeNode type)
+ {
+ if (type == null) return null;
+ TypeNode dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
+ if (dup != null && (dup.Template != type || this.RecordOriginalAsTemplate)) return dup;
+ switch (type.NodeType)
+ {
+ case NodeType.ArrayType:
+ ArrayType arrType = (ArrayType)type;
+ TypeNode elemType = this.VisitTypeReference(arrType.ElementType);
+ if (elemType == arrType.ElementType) return arrType;
+ if (elemType == null) { Debug.Fail(""); return null; }
+ this.TypesToBeDuplicated[arrType.UniqueKey] = arrType;
+ dup = elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds);
+ break;
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ if (this.RecordOriginalAsTemplate) return type;
+ if (this.TypesToBeDuplicated[type.UniqueKey] == null) return type;
+ dup = this.VisitTypeNode(type);
+ break;
+#if !MinimalReader
+ case NodeType.DelegateNode:
+ {
+ FunctionType ftype = type as FunctionType;
+ if (ftype == null) goto default;
+ dup = FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), this.TargetType);
+ break;
+ }
+#endif
+ case NodeType.Pointer:
+ Pointer pType = (Pointer)type;
+ elemType = this.VisitTypeReference(pType.ElementType);
+ if (elemType == pType.ElementType) return pType;
+ if (elemType == null) { Debug.Fail(""); return null; }
+ dup = elemType.GetPointerType();
+ break;
+ case NodeType.Reference:
+ Reference rType = (Reference)type;
+ elemType = this.VisitTypeReference(rType.ElementType);
+ if (elemType == rType.ElementType) return rType;
+ if (elemType == null) { Debug.Fail(""); return null; }
+ dup = elemType.GetReferenceType();
+ break;
+#if ExtendedRuntime
+ case NodeType.TupleType:{
+ TupleType tType = (TupleType)type;
+ bool reconstruct = false;
+ MemberList members = tType.Members;
+ int n = members == null ? 0 : members.Count;
+ FieldList fields = new FieldList(n);
+ for (int i = 0; i < n; i++){
+ //^ assert members != null;
+ Field f = members[i] as Field;
+ if (f == null) continue;
+ f = (Field)f.Clone();
+ fields.Add(f);
+ TypeNode oft = f.Type;
+ TypeNode ft = f.Type = this.VisitTypeReference(f.Type);
+ if (ft != oft) reconstruct = true;
+ }
+ if (!reconstruct) return tType;
+ dup = TupleType.For(fields, this.TargetType);
+ break;}
+ case NodeType.TypeIntersection:
+ TypeIntersection tIntersect = (TypeIntersection)type;
+ dup = TypeIntersection.For(this.VisitTypeReferenceList(tIntersect.Types), this.TargetType);
+ break;
+ case NodeType.TypeUnion:
+ TypeUnion tUnion = (TypeUnion)type;
+ TypeNodeList types = this.VisitTypeReferenceList(tUnion.Types);
+ if (types == null) { Debug.Fail(""); return null; }
+ if (this.TargetType == null)
+ dup = TypeUnion.For(types, TargetModule);
+ else
+ dup = TypeUnion.For(types, this.TargetType);
+ break;
+#endif
+#if !MinimalReader
+ //These types typically have only one reference and do not have pointer identity. Just duplicate them.
+ case NodeType.ArrayTypeExpression:
+ ArrayTypeExpression aExpr = (ArrayTypeExpression)type.Clone();
+ elemType = this.VisitTypeReference(aExpr.ElementType);
+ if (elemType == null) { Debug.Fail(""); return aExpr; }
+ aExpr.ElementType = elemType;
+ return aExpr;
+ case NodeType.BoxedTypeExpression:
+ BoxedTypeExpression bExpr = (BoxedTypeExpression)type.Clone();
+ bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
+ return bExpr;
+ case NodeType.ClassExpression:
+ ClassExpression cExpr = (ClassExpression)type.Clone();
+ cExpr.Expression = this.VisitExpression(cExpr.Expression);
+ cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
+ return cExpr;
+#endif
+#if ExtendedRuntime
+ case NodeType.ConstrainedType:
+ ConstrainedType conType = (ConstrainedType)type;
+ TypeNode underlyingType = this.VisitTypeReference(conType.UnderlyingType);
+ Expression constraint = this.VisitExpression(conType.Constraint);
+ if (underlyingType == null || constraint == null) { Debug.Fail(""); return null; }
+ if (this.TargetType == null)
+ return null;
+ else
+ return new ConstrainedType(underlyingType, constraint, this.TargetType);
+#endif
+#if !MinimalReader
+ case NodeType.FlexArrayTypeExpression:
+ FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type.Clone();
+ flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
+ return flExpr;
+#endif
+ case NodeType.FunctionPointer:
+ FunctionPointer funcPointer = (FunctionPointer)type.Clone();
+ funcPointer.ParameterTypes = this.VisitTypeReferenceList(funcPointer.ParameterTypes);
+ funcPointer.ReturnType = this.VisitTypeReference(funcPointer.ReturnType);
+ return funcPointer;
+#if !MinimalReader
+ case NodeType.FunctionTypeExpression:
+ FunctionTypeExpression ftExpr = (FunctionTypeExpression)type.Clone();
+ ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
+ ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
+ return ftExpr;
+ case NodeType.InvariantTypeExpression:
+ InvariantTypeExpression invExpr = (InvariantTypeExpression)type.Clone();
+ invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
+ return invExpr;
+#endif
+ case NodeType.InterfaceExpression:
+ InterfaceExpression iExpr = (InterfaceExpression)type.Clone();
+ iExpr.Expression = this.VisitExpression(iExpr.Expression);
+ iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
+ return iExpr;
+#if !MinimalReader
+ case NodeType.NonEmptyStreamTypeExpression:
+ NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type.Clone();
+ neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
+ return neExpr;
+ case NodeType.NonNullTypeExpression:
+ NonNullTypeExpression nnExpr = (NonNullTypeExpression)type.Clone();
+ nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
+ return nnExpr;
+ case NodeType.NonNullableTypeExpression:
+ NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type.Clone();
+ nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
+ return nbExpr;
+ case NodeType.NullableTypeExpression:
+ NullableTypeExpression nuExpr = (NullableTypeExpression)type.Clone();
+ nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
+ return nuExpr;
+#endif
+ case NodeType.OptionalModifier:
+ TypeModifier modType = (TypeModifier)type;
+ TypeNode modified = this.VisitTypeReference(modType.ModifiedType);
+ TypeNode modifier = this.VisitTypeReference(modType.Modifier);
+ if (modified == null || modifier == null) { Debug.Fail(""); return null; }
+ return OptionalModifier.For(modifier, modified);
+ case NodeType.RequiredModifier:
+ modType = (TypeModifier)type;
+ modified = this.VisitTypeReference(modType.ModifiedType);
+ modifier = this.VisitTypeReference(modType.Modifier);
+ if (modified == null || modifier == null) { Debug.Fail(""); return null; }
+ return RequiredModifier.For(modifier, modified);
+#if !MinimalReader
+ case NodeType.OptionalModifierTypeExpression:
+ OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type.Clone();
+ optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
+ optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier);
+ return optmodType;
+ case NodeType.RequiredModifierTypeExpression:
+ RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type.Clone();
+ reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
+ reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier);
+ return reqmodType;
+ case NodeType.PointerTypeExpression:
+ PointerTypeExpression pExpr = (PointerTypeExpression)type.Clone();
+ elemType = this.VisitTypeReference(pExpr.ElementType);
+ if (elemType == null) { Debug.Fail(""); return pExpr; }
+ pExpr.ElementType = elemType;
+ return pExpr;
+ case NodeType.ReferenceTypeExpression:
+ ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type.Clone();
+ elemType = this.VisitTypeReference(rExpr.ElementType);
+ if (elemType == null) { Debug.Fail(""); return rExpr; }
+ rExpr.ElementType = elemType;
+ return rExpr;
+ case NodeType.StreamTypeExpression:
+ StreamTypeExpression sExpr = (StreamTypeExpression)type.Clone();
+ sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
+ return sExpr;
+ case NodeType.TupleTypeExpression:
+ TupleTypeExpression tuExpr = (TupleTypeExpression)type.Clone();
+ tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
+ return tuExpr;
+ case NodeType.TypeExpression:
+ TypeExpression tExpr = (TypeExpression)type.Clone();
+ tExpr.Expression = this.VisitExpression(tExpr.Expression);
+ tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
+ return tExpr;
+ case NodeType.TypeIntersectionExpression:
+ TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type.Clone();
+ tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
+ return tiExpr;
+ case NodeType.TypeUnionExpression:
+ TypeUnionExpression tyuExpr = (TypeUnionExpression)type.Clone();
+ tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
+ return tyuExpr;
+#endif
+ default:
+ if (type.Template != null && type.Template != type && (type.TemplateArguments != null ||
+ (!this.RecordOriginalAsTemplate && type.ConsolidatedTemplateArguments != null && type.ConsolidatedTemplateArguments.Count > 0)))
+ {
+ TypeNode templ = this.VisitTypeReference(type.Template);
+ //^ assume templ != null;
+ if (TargetPlatform.UseGenerics)
+ {
+ if (templ.Template != null)
+ {
+ if (this.RecordOriginalAsTemplate)
+ templ = templ.Template;
+ else
+ templ = this.VisitTypeReference(templ.Template);
+ //^ assume templ != null;
+ }
+ if (type.DeclaringType != null)
+ {
+ TypeNode declType = this.VisitTypeReference(type.DeclaringType);
+ if (declType != null)
+ {
+ TypeNode templDup = declType.GetNestedType(templ.Name);
+ if (templDup == null)
+ {
+ //Can happen when templ is nested in a type that is still being duplicated
+ templDup = (TypeNode)templ.Clone();
+ templDup.DeclaringModule = this.TargetModule;
+ templDup.Template = templ;
+ declType.NestedTypes.Add(templDup);
+ templ = templDup;
+ }
+ else
+ {
+ templ = templDup;
+ if (templ.Template != null)
+ {
+ if (this.RecordOriginalAsTemplate)
+ templ = templ.Template;
+ else
+ {
+ if (templ.Template.DeclaringType == null)
+ templ.Template.DeclaringType = templ.DeclaringType.Template;
+ templ = this.VisitTypeReference(templ.Template);
+ }
+ //^ assume templ != null;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (templ.Template != null) return type;
+ }
+ bool duplicateReference = templ != type.Template;
+ TypeNodeList targs = type.TemplateArguments == null ? new TypeNodeList() : type.TemplateArguments.Clone();
+ if (!this.RecordOriginalAsTemplate)
+ targs = type.ConsolidatedTemplateArguments == null ? new TypeNodeList() : type.ConsolidatedTemplateArguments.Clone();
+ for (int i = 0, n = targs == null ? 0 : targs.Count; i < n; i++)
+ {
+ TypeNode targ = targs[i];
+ if (targ == null) continue;
+ TypeNode targDup = this.VisitTypeReference(targ);
+ if (targ != targDup) duplicateReference = true;
+ targs[i] = targDup;
+ }
+ if (!duplicateReference) return type;
+ if (!this.RecordOriginalAsTemplate)
+ dup = templ.GetGenericTemplateInstance(this.TargetModule, targs);
+ else
+ dup = templ.GetTemplateInstance(this.TargetModule, this.TargetType, type.DeclaringType, targs);
+ this.DuplicateFor[type.UniqueKey] = dup;
+ return dup;
+ }
+ if (this.TypesToBeDuplicated[type.UniqueKey] == null) return type;
+ TypeNode savedTargetType = this.TargetType;
+ TypeNode declaringType = this.VisitTypeReference(type.DeclaringType);
+ if (declaringType != null)
+ {
+ dup = (TypeNode)this.DuplicateFor[type.UniqueKey];
+ if (dup != null) return dup;
+ if (declaringType == type.DeclaringType)
+ {
+ //Trying to duplicate a nested type into a type that is not the duplicate of the declaring type.
+ //In this case, type is being duplicated into the original target type.
+ declaringType = this.OriginalTargetType;
+ }
+ }
+ this.TargetType = declaringType;
+ dup = (TypeNode)this.Visit(type);
+ this.TargetType = savedTargetType;
+ break;
+ }
+ this.DuplicateFor[type.UniqueKey] = dup;
+ return dup;
+ }
+ public override TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences)
+ {
+ if (typeReferences == null) return null;
+ return base.VisitTypeReferenceList(typeReferences.Clone());
+ }
+ public override Expression VisitUnaryExpression(UnaryExpression unaryExpression)
+ {
+ if (unaryExpression == null) return null;
+ unaryExpression = (UnaryExpression)base.VisitUnaryExpression((UnaryExpression)unaryExpression.Clone());
+ return unaryExpression;
+ }
+#if !MinimalReader
+ public override Statement VisitVariableDeclaration(VariableDeclaration variableDeclaration)
+ {
+ if (variableDeclaration == null) return null;
+ return base.VisitVariableDeclaration((VariableDeclaration)variableDeclaration.Clone());
+ }
+ public override UsedNamespace VisitUsedNamespace(UsedNamespace usedNamespace)
+ {
+ if (usedNamespace == null) return null;
+ return base.VisitUsedNamespace((UsedNamespace)usedNamespace.Clone());
+ }
+ public override UsedNamespaceList VisitUsedNamespaceList(UsedNamespaceList usedNspaces)
+ {
+ if (usedNspaces == null) return null;
+ return base.VisitUsedNamespaceList(usedNspaces.Clone());
+ }
+ public override Statement VisitWhile(While While)
+ {
+ if (While == null) return null;
+ return base.VisitWhile((While)While.Clone());
+ }
+ public override Statement VisitYield(Yield Yield)
+ {
+ if (Yield == null) return null;
+ return base.VisitYield((Yield)Yield.Clone());
+ }
+#endif
+#if ExtendedRuntime
+ // query nodes
+ public override Node VisitQueryAggregate(QueryAggregate qa){
+ if (qa == null) return null;
+ return base.VisitQueryAggregate((QueryAggregate)qa.Clone());
+ }
+ public override Node VisitQueryAlias(QueryAlias alias){
+ if (alias == null) return null;
+ return base.VisitQueryAlias((QueryAlias)alias.Clone());
+ }
+ public override Node VisitQueryAxis(QueryAxis axis){
+ if (axis == null) return null;
+ return base.VisitQueryAxis((QueryAxis)axis.Clone());
+ }
+ public override Node VisitQueryCommit(QueryCommit qc){
+ if (qc == null) return null;
+ return base.VisitQueryCommit((QueryCommit)qc.Clone());
+ }
+ public override Node VisitQueryContext(QueryContext context){
+ if (context == null) return null;
+ return base.VisitQueryContext((QueryContext)context.Clone());
+ }
+ public override Node VisitQueryDelete(QueryDelete delete){
+ if (delete == null) return null;
+ return base.VisitQueryDelete((QueryDelete)delete.Clone());
+ }
+ public override Node VisitQueryDifference(QueryDifference diff){
+ if (diff == null) return null;
+ return base.VisitQueryDifference((QueryDifference)diff.Clone());
+ }
+ public override Node VisitQueryDistinct(QueryDistinct distinct){
+ if (distinct == null) return null;
+ return base.VisitQueryDistinct((QueryDistinct)distinct.Clone());
+ }
+ public override Node VisitQueryExists(QueryExists exists){
+ if (exists == null) return null;
+ return base.VisitQueryExists((QueryExists)exists.Clone());
+ }
+ public override Node VisitQueryFilter(QueryFilter filter){
+ if (filter == null) return null;
+ return base.VisitQueryFilter((QueryFilter)filter.Clone());
+ }
+ public override Node VisitQueryGroupBy(QueryGroupBy groupby){
+ if (groupby == null) return null;
+ return base.VisitQueryGroupBy((QueryGroupBy)groupby.Clone());
+ }
+ public override Statement VisitQueryGeneratedType(QueryGeneratedType qgt){
+ if (qgt == null) return null;
+ return base.VisitQueryGeneratedType((QueryGeneratedType)qgt.Clone());
+ }
+ public override Node VisitQueryInsert(QueryInsert insert){
+ if (insert == null) return null;
+ return base.VisitQueryInsert((QueryInsert)insert.Clone());
+ }
+ public override Node VisitQueryIntersection(QueryIntersection intersection){
+ if (intersection == null) return intersection;
+ return base.VisitQueryIntersection((QueryIntersection)intersection.Clone());
+ }
+ public override Node VisitQueryIterator(QueryIterator xiterator){
+ if (xiterator == null) return xiterator;
+ return base.VisitQueryIterator((QueryIterator)xiterator.Clone());
+ }
+ public override Node VisitQueryJoin(QueryJoin join){
+ if (join == null) return null;
+ return base.VisitQueryJoin((QueryJoin)join.Clone());
+ }
+ public override Node VisitQueryLimit(QueryLimit limit){
+ if (limit == null) return null;
+ return base.VisitQueryLimit((QueryLimit)limit.Clone());
+ }
+ public override Node VisitQueryOrderBy(QueryOrderBy orderby){
+ if (orderby == null) return null;
+ return base.VisitQueryOrderBy((QueryOrderBy)orderby.Clone());
+ }
+ public override Node VisitQueryOrderItem(QueryOrderItem item){
+ if (item == null) return null;
+ return base.VisitQueryOrderItem((QueryOrderItem)item.Clone());
+ }
+ public override Node VisitQueryPosition(QueryPosition position){
+ if (position == null) return null;
+ return base.VisitQueryPosition((QueryPosition)position.Clone());
+ }
+ public override Node VisitQueryProject(QueryProject project){
+ if (project == null) return null;
+ return base.VisitQueryProject((QueryProject)project.Clone());
+ }
+ public override Node VisitQueryRollback(QueryRollback qr){
+ if (qr == null) return null;
+ return base.VisitQueryRollback((QueryRollback)qr.Clone());
+ }
+ public override Node VisitQueryQuantifier(QueryQuantifier qq){
+ if (qq == null) return null;
+ return base.VisitQueryQuantifier((QueryQuantifier)qq.Clone());
+ }
+ public override Node VisitQueryQuantifiedExpression(QueryQuantifiedExpression qqe){
+ if (qqe == null) return null;
+ return base.VisitQueryQuantifiedExpression((QueryQuantifiedExpression)qqe.Clone());
+ }
+ public override Node VisitQuerySelect(QuerySelect select){
+ if (select == null) return null;
+ return base.VisitQuerySelect((QuerySelect)select.Clone());
+ }
+ public override Node VisitQuerySingleton(QuerySingleton singleton){
+ if (singleton == null) return null;
+ return base.VisitQuerySingleton((QuerySingleton)singleton.Clone());
+ }
+ public override Node VisitQueryTransact(QueryTransact qt){
+ if (qt == null) return null;
+ return base.VisitQueryTransact((QueryTransact)qt.Clone());
+ }
+ public override Node VisitQueryTypeFilter(QueryTypeFilter filter){
+ if (filter == null) return null;
+ return base.VisitQueryTypeFilter((QueryTypeFilter)filter.Clone());
+ }
+ public override Node VisitQueryUnion(QueryUnion union){
+ if (union == null) return null;
+ return base.VisitQueryUnion((QueryUnion)union.Clone());
+ }
+ public override Node VisitQueryUpdate(QueryUpdate update){
+ if (update == null) return null;
+ return base.VisitQueryUpdate((QueryUpdate)update.Clone());
+ }
+ public override Node VisitQueryYielder(QueryYielder yielder){
+ if (yielder == null) return null;
+ return base.VisitQueryYielder((QueryYielder)yielder.Clone());
+ }
+#endif
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/ExceptionStrings.cs b/tools/Sandcastle/Source/CCI/ExceptionStrings.cs
new file mode 100644
index 0000000..cad0038
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/ExceptionStrings.cs
@@ -0,0 +1,480 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Resources;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ sealed class ExceptionStrings
+ {
+ private readonly static WeakReference/*!*/ resMgr = new WeakReference(null);
+
+ private ExceptionStrings()
+ {
+ }
+
+ internal static System.Resources.ResourceManager/*!*/ ResourceManager
+ {
+ get
+ {
+ System.Resources.ResourceManager rMgr = ExceptionStrings.resMgr.Target as System.Resources.ResourceManager;
+ if (rMgr == null)
+ {
+
+ rMgr = new System.Resources.ResourceManager("CCI.ExceptionStrings", typeof(ExceptionStrings).Assembly);
+ /*
+ #if CCINamespace
+ rMgr = new System.Resources.ResourceManager("Microsoft.Cci.ExceptionStrings", typeof(ExceptionStrings).Assembly);
+ #else
+ rMgr = new System.Resources.ResourceManager("System.Compiler.ExceptionStrings", typeof(ExceptionStrings).Assembly);
+ #endif
+ */
+ ExceptionStrings.resMgr.Target = rMgr;
+ }
+ return rMgr;
+ }
+ }
+ internal static string/*!*/ AssemblyReferenceNotResolved
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("AssemblyReferenceNotResolved", null);
+ }
+ }
+ internal static string/*!*/ BadBlobHeapIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadBlobHeapIndex", null);
+ }
+ }
+ internal static string/*!*/ BadCLIHeader
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadCLIHeader", null);
+ }
+ }
+ internal static string/*!*/ BadCOFFHeaderSignature
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadCOFFHeaderSignature", null);
+ }
+ }
+ internal static string/*!*/ BadConstantParentIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadConstantParentIndex", null);
+ }
+ }
+ internal static string/*!*/ BadCustomAttributeTypeEncodedToken
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadCustomAttributeTypeEncodedToken", null);
+ }
+ }
+ internal static string/*!*/ BaddCalliSignature
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BaddCalliSignature", null);
+ }
+ }
+ internal static string/*!*/ BadExceptionHandlerType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadExceptionHandlerType", null);
+ }
+ }
+ internal static string/*!*/ BadGuidHeapIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadGuidHeapIndex", null);
+ }
+ }
+ internal static string/*!*/ BadMagicNumber
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMagicNumber", null);
+ }
+ }
+ internal static string/*!*/ BadMemberToken
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMemberToken", null);
+ }
+ }
+ internal static string/*!*/ BadMetadataHeaderSignature
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataHeaderSignature", null);
+ }
+ }
+ internal static string/*!*/ BadMetadataInExportTypeTableNoSuchAssemblyReference
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataInExportTypeTableNoSuchAssemblyReference", null);
+ }
+ }
+ internal static string/*!*/ BadMetadataInExportTypeTableNoSuchParentType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMetadataInExportTypeTableNoSuchParentType", null);
+ }
+ }
+ internal static string/*!*/ BadMethodHeaderSection
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMethodHeaderSection", null);
+ }
+ }
+ internal static string/*!*/ BadMethodTypeParameterInPosition
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadMethodTypeParameterInPosition", null);
+ }
+ }
+ internal static string/*!*/ BadPEHeaderMagicNumber
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadPEHeaderMagicNumber", null);
+ }
+ }
+ internal static string/*!*/ BadSecurityPermissionSetBlob
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadSecurityPermissionSetBlob", null);
+ }
+ }
+ internal static string/*!*/ BadSerializedTypeName
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadSerializedTypeName", null);
+ }
+ }
+ internal static string/*!*/ BadStringHeapIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadStringHeapIndex", null);
+ }
+ }
+ internal static string BadTargetPlatformLocation
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadTargetPlatformLocation", null);
+ }
+ }
+ internal static string BadTypeDefOrRef
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadTypeDefOrRef", null);
+ }
+ }
+ internal static string/*!*/ BadTypeParameterInPositionForType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadTypeParameterInPositionForType", null);
+ }
+ }
+ internal static string/*!*/ BadUserStringHeapIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("BadUserStringHeapIndex", null);
+ }
+ }
+ internal static string/*!*/ CannotLoadTypeExtension
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CannotLoadTypeExtension", null);
+ }
+ }
+ internal static string/*!*/ CollectionIsReadOnly
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CollectionIsReadOnly", null);
+ }
+ }
+ internal static string CouldNotFindExportedNestedTypeInType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedNestedTypeInType", null);
+ }
+ }
+ internal static string/*!*/ CouldNotFindExportedTypeInAssembly
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedTypeInAssembly", null);
+ }
+ }
+ internal static string CouldNotFindExportedTypeInModule
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindExportedTypeInModule", null);
+ }
+ }
+ internal static string/*!*/ CouldNotFindReferencedModule
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotFindReferencedModule", null);
+ }
+ }
+ internal static string/*!*/ CouldNotResolveMemberReference
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotResolveMemberReference", null);
+ }
+ }
+ internal static string/*!*/ CouldNotResolveType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CouldNotResolveType", null);
+ }
+ }
+ internal static string CouldNotResolveTypeReference
+ {
+ get
+ {
+ return ResourceManager.GetString("CouldNotResolveTypeReference", null);
+ }
+ }
+ internal static string/*!*/ CreateFileMappingReturnedErrorCode
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("CreateFileMappingReturnedErrorCode", null);
+ }
+ }
+ internal static string/*!*/ ENCLogTableEncountered
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("ENCLogTableEncountered", null);
+ }
+ }
+ internal static string/*!*/ ENCMapTableEncountered
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("ENCMapTableEncountered", null);
+ }
+ }
+ internal static string/*!*/ FileTooBig
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("FileTooBig", null);
+ }
+ }
+ internal static string/*!*/ GetReaderForFileReturnedUnexpectedHResult
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("GetReaderForFileReturnedUnexpectedHResult", null);
+ }
+ }
+ internal static string/*!*/ InternalCompilerError
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InternalCompilerError", null);
+ }
+ }
+ internal static string/*!*/ InvalidBaseClass
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidBaseClass", null);
+ }
+ }
+ internal static string/*!*/ InvalidFatMethodHeader
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidFatMethodHeader", null);
+ }
+ }
+ internal static string/*!*/ InvalidLocalSignature
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidLocalSignature", null);
+ }
+ }
+ internal static string InvalidModuleTable
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidModuleTable", null);
+ }
+ }
+ internal static string/*!*/ InvalidTypeTableIndex
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidTypeTableIndex", null);
+ }
+ }
+ internal static string MalformedSignature
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("MalformedSignature", null);
+ }
+ }
+ internal static string/*!*/ MapViewOfFileReturnedErrorCode
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("MapViewOfFileReturnedErrorCode", null);
+ }
+ }
+ internal static string/*!*/ ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary", null);
+ }
+ }
+ internal static string/*!*/ ModuleError
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("ModuleError", null);
+ }
+ }
+ internal static string/*!*/ NoMetadataStream
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("NoMetadataStream", null);
+ }
+ }
+ internal static string/*!*/ PdbAssociatedWithFileIsOutOfDate
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("PdbAssociatedWithFileIsOutOfDate", null);
+ }
+ }
+ internal static string/*!*/ SecurityAttributeTypeDoesNotHaveADefaultConstructor
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("SecurityAttributeTypeDoesNotHaveADefaultConstructor", null);
+ }
+ }
+ internal static string/*!*/ TooManyMethodHeaderSections
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("TooManyMethodHeaderSections", null);
+ }
+ }
+ internal static string/*!*/ UnexpectedTypeInCustomAttribute
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnexpectedTypeInCustomAttribute", null);
+ }
+ }
+ internal static string/*!*/ UnknownConstantType
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnknownConstantType", null);
+ }
+ }
+ internal static string/*!*/ UnknownOpCode
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnknownOpCode", null);
+ }
+ }
+ internal static string/*!*/ UnknownOpCodeEncountered
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnknownOpCodeEncountered", null);
+ }
+ }
+ internal static string/*!*/ UnknownVirtualAddress
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnknownVirtualAddress", null);
+ }
+ }
+ internal static string/*!*/ UnresolvedAssemblyReferenceNotAllowed
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnresolvedAssemblyReferenceNotAllowed", null);
+ }
+ }
+ internal static string/*!*/ UnresolvedModuleReferenceNotAllowed
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnresolvedModuleReferenceNotAllowed", null);
+ }
+ }
+ internal static string/*!*/ UnsupportedTableEncountered
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("UnsupportedTableEncountered", null);
+ }
+ }
+ internal static string/*!*/ InvalidAssemblyStrongName
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("InvalidAssemblyStrongName", null);
+ }
+ }
+ internal static string/*!*/ KeyNeedsToBeGreaterThanZero
+ {
+ get
+ {
+ return /*^ (!) ^*/ ResourceManager.GetString("KeyNeedsToBeGreaterThanZero", null);
+ }
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/ExceptionStrings.resx b/tools/Sandcastle/Source/CCI/ExceptionStrings.resx
new file mode 100644
index 0000000..e801ddf
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/ExceptionStrings.resx
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<root>
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="ResMimeType">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="Version">
+ <value>1.0.0.0</value>
+ </resheader>
+ <resheader name="Reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="Writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="BadBlobHeapIndex">
+ <value>Bad blob heap index.</value>
+ </data>
+ <data name="BadTargetPlatformLocation">
+ <value>Assembly {0} at platform assembly location {1} has version {2} which does not match the target platform version {3}.</value>
+ </data>
+ <data name="UnknownVirtualAddress">
+ <value>Unknown virtual address {0}.</value>
+ </data>
+ <data name="UnknownConstantType">
+ <value>Unknown constant type.</value>
+ </data>
+ <data name="BadGuidHeapIndex">
+ <value>Bad guid heap index.</value>
+ </data>
+ <data name="BadStringHeapIndex">
+ <value>Bad string heap index.</value>
+ </data>
+ <data name="BadUserStringHeapIndex">
+ <value>Bad user string heap index.</value>
+ </data>
+ <data name="NoMetadataStream">
+ <value>No metadata stream.</value>
+ </data>
+ <data name="ENCLogTableEncountered">
+ <value>ENCLog Table encountered.</value>
+ </data>
+ <data name="ENCMapTableEncountered">
+ <value>ENCMap Table encountered.</value>
+ </data>
+ <data name="UnsupportedTableEncountered">
+ <value>Unsupported table encountered.</value>
+ </data>
+ <data name="BadCLIHeader">
+ <value>Bad CLI header.</value>
+ </data>
+ <data name="BadMagicNumber">
+ <value>Bad magic number.</value>
+ </data>
+ <data name="BadMetadataHeaderSignature">
+ <value>Bad metadata header signature.</value>
+ </data>
+ <data name="BadCOFFHeaderSignature">
+ <value>Bad COFF header signature.</value>
+ </data>
+ <data name="BadPEHeaderMagicNumber">
+ <value>Bad PE header magic number.</value>
+ </data>
+ <data name="FileTooBig">
+ <value>File too big.</value>
+ </data>
+ <data name="CreateFileMappingReturnedErrorCode">
+ <value>CreateFileMapping returned error code {0}.</value>
+ </data>
+ <data name="MapViewOfFileReturnedErrorCode">
+ <value>MapViewOfFile returned error code {0}.</value>
+ </data>
+ <data name="PdbAssociatedWithFileIsOutOfDate">
+ <value>The pdb associated with {0} is out of date.</value>
+ </data>
+ <data name="GetReaderForFileReturnedUnexpectedHResult">
+ <value>GetReaderForFile returned an unexpected HResult: 0x{0}.</value>
+ </data>
+ <data name="InvalidModuleTable">
+ <value>Invalid module table.</value>
+ </data>
+ <data name="ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary">
+ <value>Module or assembly depends on a version of core library that is newer than the one the Reader uses to resolve system types.</value>
+ </data>
+ <data name="BadTypeDefOrRef">
+ <value>Bad TypeDefOrRef.</value>
+ </data>
+ <data name="AssemblyReferenceNotResolved">
+ <value>Assembly reference not resolved: {0}.</value>
+ </data>
+ <data name="MalformedSignature">
+ <value>Malformed signature.</value>
+ </data>
+ <data name="BadSecurityPermissionSetBlob">
+ <value>Bad security permission set blob.</value>
+ </data>
+ <data name="CouldNotResolveType">
+ <value>Could not resolve type: {0}.</value>
+ </data>
+ <data name="SecurityAttributeTypeDoesNotHaveADefaultConstructor">
+ <value>Security attribute type does not have a default constructor: {0}.</value>
+ </data>
+ <data name="UnexpectedTypeInCustomAttribute">
+ <value>Unexpected type in custom attribute.</value>
+ </data>
+ <data name="BadSerializedTypeName">
+ <value>Bad serialized type name.</value>
+ </data>
+ <data name="BadConstantParentIndex">
+ <value>Bad constant parent index.</value>
+ </data>
+ <data name="InvalidLocalSignature">
+ <value>Invalid local signature.</value>
+ </data>
+ <data name="BadCustomAttributeTypeEncodedToken">
+ <value>Bad CustomAttributeType encoded token.</value>
+ </data>
+ <data name="BadMemberToken">
+ <value>Bad member token.</value>
+ </data>
+ <data name="CouldNotResolveMemberReference">
+ <value>Could not resolve member reference: {0}.</value>
+ </data>
+ <data name="InvalidBaseClass">
+ <value>Invalid base class.</value>
+ </data>
+ <data name="CannotLoadTypeExtension">
+ <value>Can't load type extension for {0}. Assembly {1} not found.</value>
+ </data>
+ <data name="CollectionIsReadOnlye">
+ <value>Collection is read-only.</value>
+ </data>
+ <data name="CouldNotResolveTypeReference">
+ <value>Could not resolve type reference: {0}.</value>
+ </data>
+ <data name="CouldNotFindReferencedModule">
+ <value>Could not find referenced module: {0}.</value>
+ </data>
+ <data name="CouldNotFindExportedTypeInModule">
+ <value>Could not find exported type: {0} in module {1}.</value>
+ </data>
+ <data name="BadMetadataInExportTypeTableNoSuchAssemblyReference">
+ <value>Bad metadata in export type table: no such assembly reference.</value>
+ </data>
+ <data name="CouldNotFindExportedTypeInAssembly">
+ <value>Could not find exported type: {0} in assembly.</value>
+ </data>
+ <data name="BadMetadataInExportTypeTableNoSuchParentType">
+ <value>Bad metadata in export type table: no such parent type.</value>
+ </data>
+ <data name="CouldNotFindExportedNestedTypeInType">
+ <value>Could not find exported nested type: {0} in type {1}.</value>
+ </data>
+ <data name="InvalidTypeTableIndex">
+ <value>Invalid type table index.</value>
+ </data>
+ <data name="BadTypeParameterInPositionForType">
+ <value>Bad type parameter in position {0} for type</value>
+ </data>
+ <data name="BadMethodTypeParameterInPosition">
+ <value>Bad method type parameter in position {0}.</value>
+ </data>
+ <data name="InvalidFatMethodHeader">
+ <value>Invalid fat method header.</value>
+ </data>
+ <data name="BadMethodHeaderSection">
+ <value>Bad method header section.</value>
+ </data>
+ <data name="TooManyMethodHeaderSections">
+ <value>Too many method header sections.</value>
+ </data>
+ <data name="BadExceptionHandlerType">
+ <value>Bad exception handler type.</value>
+ </data>
+ <data name="BaddCalliSignature">
+ <value>Bad calli signature.</value>
+ </data>
+ <data name="UnknownOpCode">
+ <value>Unknown opcode.</value>
+ </data>
+ <data name="UnknownOpCodeEncountered">
+ <value>Unknown opCode encountered: {0}.</value>
+ </data>
+ <data name="InternalCompilerError">
+ <value>Internal compiler error.</value>
+ </data>
+ <data name="UnresolvedAssemblyReferenceNotAllowed">
+ <value>Unresolved assembly reference not allowed: {0}.</value>
+ </data>
+ <data name="UnresolvedModuleReferenceNotAllowed">
+ <value>Unresolved module reference not allowed.</value>
+ </data>
+ <data name="InvalidAssemblyStrongName">
+ <value>Invalid assembly strong name: {0}.</value>
+ </data>
+ <data name="KeyNeedsToBeGreaterThanZero">
+ <value>Key needs to be greater than 0.</value>
+ </data>
+ <data name="ModuleError">
+ <value>The following error was encountered while reading module '{0}': {1}</value>
+ </data>
+</root>
diff --git a/tools/Sandcastle/Source/CCI/FastFileIO.cs b/tools/Sandcastle/Source/CCI/FastFileIO.cs
new file mode 100644
index 0000000..865932c
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/FastFileIO.cs
@@ -0,0 +1,606 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Diagnostics;
+#if CCINamespace
+using Microsoft.Cci.Metadata;
+#else
+using System.Compiler.Metadata;
+#endif
+using System.Globalization;
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !(FxCop || NoWriter)
+ /// <summary>
+ /// High performance replacement for System.IO.BinaryWriter.
+ /// </summary>
+ public sealed class BinaryWriter
+ {
+ public MemoryStream/*!*/ BaseStream;
+ private bool UTF8 = true;
+ public BinaryWriter(MemoryStream/*!*/ output)
+ {
+ this.BaseStream = output;
+ //^ base();
+ }
+ public BinaryWriter(MemoryStream/*!*/ output, Encoding/*!*/ encoding)
+ {
+ Debug.Assert(encoding == Encoding.Unicode);
+ this.BaseStream = output;
+ this.UTF8 = false;
+ //^ base();
+ }
+ public void Write(bool value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)(value ? 1 : 0);
+ }
+ public void Write(byte value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = value;
+ }
+ public void Write(sbyte value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)value;
+ }
+ public void Write(byte[] buffer)
+ {
+ if (buffer == null) return;
+ this.BaseStream.Write(buffer, 0, buffer.Length);
+ }
+ public void Write(char ch)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)ch;
+ }
+ else
+ this.Write(new char[] { ch });
+ }
+ else
+ {
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ buffer[i] = (byte)(ch >> 8);
+ }
+ }
+ public void Write(char[] chars)
+ {
+ if (chars == null) return;
+ MemoryStream m = this.BaseStream;
+ int n = chars.Length;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ m.Position = i + n;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = chars[j];
+ if ((ch & 0x80) != 0) goto writeUTF8;
+ buffer[i++] = (byte)ch;
+ }
+ return;
+ writeUTF8:
+ int ch32 = 0;
+ for (int j = n - (m.Position - i); j < n; j++)
+ {
+ char ch = chars[j];
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ }
+ else if (ch < 0x800)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 6) & 0x1F) | 0xC0);
+ buffer[i] = (byte)((ch & 0x3F) | 0x80);
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ ch32 = (ch & 0x3FF) << 10;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ ch32 |= ch & 0x3FF;
+ m.Position = i + 4;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch32 >> 18) & 0x7) | 0xF0);
+ buffer[i++] = (byte)(((ch32 >> 12) & 0x3F) | 0x80);
+ buffer[i++] = (byte)(((ch32 >> 6) & 0x3F) | 0x80);
+ buffer[i] = (byte)((ch32 & 0x3F) | 0x80);
+ }
+ else
+ {
+ m.Position = i + 3;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 12) & 0xF) | 0xE0);
+ buffer[i++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ buffer[i] = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ }
+ else
+ {
+ m.Position = i + n * 2;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = chars[j];
+ buffer[i++] = (byte)ch;
+ buffer[i++] = (byte)(ch >> 8);
+ }
+ }
+ }
+ public unsafe void Write(double value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ fixed (byte* b = m.Buffer)
+ *((double*)(b + i)) = value;
+ }
+ public void Write(short value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i] = (byte)(value >> 8);
+ }
+ public unsafe void Write(ushort value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i] = (byte)(value >> 8);
+ }
+ public void Write(int value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i++] = (byte)(value >> 8);
+ buffer[i++] = (byte)(value >> 16);
+ buffer[i] = (byte)(value >> 24);
+ }
+ public void Write(uint value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i++] = (byte)(value >> 8);
+ buffer[i++] = (byte)(value >> 16);
+ buffer[i] = (byte)(value >> 24);
+ }
+ public void Write(long value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ byte[] buffer = m.Buffer;
+ uint lo = (uint)value;
+ uint hi = (uint)(value >> 32);
+ buffer[i++] = (byte)lo;
+ buffer[i++] = (byte)(lo >> 8);
+ buffer[i++] = (byte)(lo >> 16);
+ buffer[i++] = (byte)(lo >> 24);
+ buffer[i++] = (byte)hi;
+ buffer[i++] = (byte)(hi >> 8);
+ buffer[i++] = (byte)(hi >> 16);
+ buffer[i] = (byte)(hi >> 24);
+ }
+ public unsafe void Write(ulong value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ byte[] buffer = m.Buffer;
+ uint lo = (uint)value;
+ uint hi = (uint)(value >> 32);
+ buffer[i++] = (byte)lo;
+ buffer[i++] = (byte)(lo >> 8);
+ buffer[i++] = (byte)(lo >> 16);
+ buffer[i++] = (byte)(lo >> 24);
+ buffer[i++] = (byte)hi;
+ buffer[i++] = (byte)(hi >> 8);
+ buffer[i++] = (byte)(hi >> 16);
+ buffer[i] = (byte)(hi >> 24);
+ }
+ public unsafe void Write(float value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ fixed (byte* b = m.Buffer)
+ *((float*)(b + i)) = value;
+ }
+ public void Write(string str)
+ {
+ this.Write(str, false);
+ }
+ public void Write(string str, bool emitNullTerminator)
+ {
+ if (str == null)
+ {
+ Debug.Assert(!emitNullTerminator);
+ this.Write((byte)0xff);
+ return;
+ }
+ int n = str.Length;
+ if (!emitNullTerminator)
+ {
+ if (this.UTF8)
+ Ir2md.WriteCompressedInt(this, this.GetUTF8ByteCount(str));
+ else
+ Ir2md.WriteCompressedInt(this, n * 2);
+ }
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ m.Position = i + n;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = str[j];
+ if (ch >= 0x80) goto writeUTF8;
+ buffer[i++] = (byte)ch;
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i] = 0;
+ }
+ return;
+ writeUTF8:
+ int ch32 = 0;
+ for (int j = n - (m.Position - i); j < n; j++)
+ {
+ char ch = str[j];
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ }
+ else if (ch < 0x800)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 6) & 0x1F) | 0xC0);
+ buffer[i++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ ch32 = (ch & 0x3FF) << 10;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ ch32 |= ch & 0x3FF;
+ m.Position = i + 4;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch32 >> 18) & 0x7) | 0xF0);
+ buffer[i++] = (byte)(((ch32 >> 12) & 0x3F) | 0x80);
+ buffer[i++] = (byte)(((ch32 >> 6) & 0x3F) | 0x80);
+ buffer[i++] = (byte)((ch32 & 0x3F) | 0x80);
+ }
+ else
+ {
+ m.Position = i + 3;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 12) & 0xF) | 0xE0);
+ buffer[i++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ buffer[i++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i] = 0;
+ }
+ }
+ else
+ {
+ m.Position = i + n * 2;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = str[j];
+ buffer[i++] = (byte)ch;
+ buffer[i++] = (byte)(ch >> 8);
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = 0;
+ buffer[i] = 0;
+ }
+ }
+ }
+ public int GetUTF8ByteCount(string str)
+ {
+ int count = 0;
+ for (int i = 0, n = str == null ? 0 : str.Length; i < n; i++)
+ {
+ //^ assume str != null;
+ char ch = str[i];
+ if (ch < 0x80)
+ {
+ count += 1;
+ }
+ else if (ch < 0x800)
+ {
+ count += 2;
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ count += 2;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ count += 2;
+ }
+ else
+ {
+ count += 3;
+ }
+ }
+ return count;
+ }
+ }
+ public sealed class MemoryStream
+ {
+ public byte[]/* ! */ Buffer;
+ public int Length;
+ public int position;
+ public int Position
+ {
+ get { return this.position; }
+ set
+ {
+ byte[] myBuffer = this.Buffer;
+ int n = myBuffer.Length;
+ if (value >= n) this.Grow(myBuffer, n, value);
+ if (value > this.Length) this.Length = value;
+ this.position = value;
+ }
+ }
+ public MemoryStream()
+ {
+ this.Buffer = new byte[64];
+ this.Length = 0;
+ this.position = 0;
+ //^ base();
+ }
+ public MemoryStream(byte[]/*!*/ bytes)
+ {
+ if (bytes == null) { Debug.Fail(""); }
+ this.Buffer = bytes;
+ this.Length = bytes.Length;
+ this.position = 0;
+ //^ base();
+ }
+ private void Grow(byte[]/*!*/ myBuffer, int n, int m)
+ {
+ if (myBuffer == null) { Debug.Fail(""); return; }
+ int n2 = n * 2;
+ while (m >= n2) n2 = n2 * 2;
+ byte[] newBuffer = this.Buffer = new byte[n2];
+ for (int i = 0; i < n; i++)
+ newBuffer[i] = myBuffer[i]; //TODO: optimize this
+ }
+ public void Seek(long offset, SeekOrigin loc)
+ {
+ Debug.Assert(loc == SeekOrigin.Begin);
+ Debug.Assert(offset <= int.MaxValue);
+ this.Position = (int)offset;
+ }
+ public byte[]/*!*/ ToArray()
+ {
+ int n = this.Length;
+ byte[] source = this.Buffer;
+ if (source.Length == n) return this.Buffer; //unlikely, but the check is cheap
+ byte[] result = new byte[n];
+ for (int i = 0; i < n; i++)
+ result[i] = source[i]; //TODO: optimize this
+ return result;
+ }
+ public void Write(byte[]/*!*/ buffer, int index, int count)
+ {
+ int p = this.position;
+ this.Position = p + count;
+ byte[] myBuffer = this.Buffer;
+ for (int i = 0, j = p, k = index; i < count; i++)
+ myBuffer[j++] = buffer[k++]; //TODO: optimize this
+ }
+ public void WriteTo(MemoryStream/*!*/ stream)
+ {
+ stream.Write(this.Buffer, 0, this.Length);
+ }
+ public void WriteTo(System.IO.Stream/*!*/ stream)
+ {
+ stream.Write(this.Buffer, 0, this.Length);
+ }
+ }
+ public enum SeekOrigin { Begin, Current, End }
+#endif
+ /// <summary>
+ /// A version of System.IO.Path that does not throw exceptions.
+ /// </summary>
+#if FxCop || NoWriter
+ internal sealed class BetterPath {
+#else
+ public sealed class BetterPath
+ {
+#endif
+ public static readonly char AltDirectorySeparatorChar = System.IO.Path.AltDirectorySeparatorChar;
+ public static readonly char DirectorySeparatorChar = System.IO.Path.DirectorySeparatorChar;
+ public static readonly char VolumeSeparatorChar = System.IO.Path.VolumeSeparatorChar;
+
+ public static string ChangeExtension(string path, string extension)
+ {
+ if (path == null) return null;
+ string text1 = path;
+ int num1 = path.Length;
+ while (--num1 >= 0)
+ {
+ char ch1 = path[num1];
+ if (ch1 == '.')
+ {
+ text1 = path.Substring(0, num1);
+ break;
+ }
+ if (((ch1 == BetterPath.DirectorySeparatorChar) || (ch1 == BetterPath.AltDirectorySeparatorChar)) || (ch1 == BetterPath.VolumeSeparatorChar))
+ break;
+ }
+ if (extension == null || path.Length == 0) return text1;
+ if (extension.Length == 0 || extension[0] != '.')
+ text1 = text1 + ".";
+ return text1 + extension;
+ }
+ public static string Combine(string path1, string path2)
+ {
+ if (path1 == null || path1.Length == 0) return path2;
+ if (path2 == null || path2.Length == 0) return path1;
+ char ch = path2[0];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || (path2.Length >= 2 && path2[1] == BetterPath.VolumeSeparatorChar))
+ return path2;
+ ch = path1[path1.Length - 1];
+ if (ch != BetterPath.DirectorySeparatorChar && ch != BetterPath.AltDirectorySeparatorChar && ch != BetterPath.VolumeSeparatorChar)
+ return (path1 + BetterPath.DirectorySeparatorChar + path2);
+ return path1 + path2;
+ }
+ public static string GetExtension(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == '.')
+ {
+ if (i != length - 1)
+ return path.Substring(i, length - i);
+ else
+ return String.Empty;
+ }
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ break;
+ }
+ return string.Empty;
+ }
+ public static String GetFileName(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ return path.Substring(i + 1);
+ }
+ return path;
+ }
+ public static string GetFileNameWithoutExtension(string path)
+ {
+ int num1;
+ path = BetterPath.GetFileName(path);
+ if (path == null) return null;
+ if ((num1 = path.LastIndexOf('.')) == -1) return path;
+ return path.Substring(0, num1);
+ }
+ public static String GetDirectoryName(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ return path.Substring(0, i);
+ }
+ return path;
+ }
+ public static char[] GetInvalidFileNameChars()
+ {
+#if WHIDBEY
+ return System.IO.Path.GetInvalidFileNameChars();
+#else
+ return System.IO.Path.InvalidPathChars;
+#endif
+ }
+ public static char[] GetInvalidPathChars()
+ {
+#if WHIDBEY
+ return System.IO.Path.GetInvalidPathChars();
+#else
+ return System.IO.Path.InvalidPathChars;
+#endif
+ }
+ public static string GetTempFileName()
+ {
+ return System.IO.Path.GetTempFileName();
+ }
+ public static bool HasExtension(string path)
+ {
+ if (path != null)
+ {
+ int num1 = path.Length;
+ while (--num1 >= 0)
+ {
+ char ch1 = path[num1];
+ if (ch1 == '.')
+ {
+ if (num1 != (path.Length - 1))
+ {
+ return true;
+ }
+ return false;
+ }
+ if (((ch1 == BetterPath.DirectorySeparatorChar) || (ch1 == BetterPath.AltDirectorySeparatorChar)) || (ch1 == BetterPath.VolumeSeparatorChar))
+ {
+ break;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/ILGenerator.cs b/tools/Sandcastle/Source/CCI/ILGenerator.cs
new file mode 100644
index 0000000..6010762
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/ILGenerator.cs
@@ -0,0 +1,1152 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !NoReflection && !MinimalReader && WHIDBEY
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection.Emit;
+
+#if CCINamespace
+using Microsoft.Cci.Metadata;
+namespace Microsoft.Cci{
+#else
+using System.Compiler.Metadata;
+using ElementType = System.Compiler.Metadata.ElementType;
+namespace System.Compiler
+{
+#endif
+
+ public class ReGenerator
+ {
+ protected TrivialHashtable/*!*/ exceptionStartCount = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ catchStart = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ catchTypeNode = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ finallyStart = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ exceptionEndCount = new TrivialHashtable();
+ protected ILGenerator/*!*/ ILGenerator;
+ protected TrivialHashtable/*!*/ labelIndex = new TrivialHashtable();
+ protected List<LocalBuilder/*!*/>/*!*/ locals = new List<LocalBuilder/*!*/>();
+ protected TrivialHashtable/*!*/ localsIndex = new TrivialHashtable();
+
+ public ReGenerator(ILGenerator/*!*/ ilGenerator)
+ {
+ this.ILGenerator = ilGenerator;
+ //^ base();
+ }
+
+ public virtual void VisitMethod(Method method)
+ {
+ if (method == null) { Debug.Assert(false); return; }
+ this.VisitExceptionHandlers(method.ExceptionHandlers);
+ this.VisitBlock(method.Body);
+ }
+
+ protected virtual void VisitExceptionHandlers(ExceptionHandlerList ehandlers)
+ {
+ //TODO: the list of ehandlers is sorted so that nested blocks always come first
+ //When a handler does not have exactly the same start and end blocks as the previous handler, it is either a parent or a sibling.
+ //When this transition occurs an end exception can be emitted when processing the last handler block of the previous handler.
+ //Need to keep counts of the number of times a block starts a handler protected region and the number of times that a block
+ //is the one following a handler exceptional region.
+ }
+
+ protected virtual Label GetLabel(Block/*!*/ block)
+ {
+ object label = this.labelIndex[block.UniqueKey];
+ if (label == null)
+ {
+ label = this.ILGenerator.DefineLabel();
+ this.labelIndex[block.UniqueKey] = label;
+ }
+ return (Label)label;
+ }
+ protected virtual int GetLocalVarIndex(Local/*!*/ loc)
+ {
+ object index = this.localsIndex[loc.UniqueKey];
+ if (index is int) return (int)index;
+ Type ltype = loc.Type == null ? null : loc.Type.GetRuntimeType();
+ if (ltype == null) { Debug.Fail(""); return 0; }
+ LocalBuilder locb = this.ILGenerator.DeclareLocal(ltype, loc.Pinned);
+ int i = this.locals.Count;
+ this.locals.Add(locb);
+ this.localsIndex[loc.UniqueKey] = i;
+ return i;
+ }
+
+ protected virtual void Visit(Node node)
+ {
+ if (node == null) return;
+ switch (node.NodeType)
+ {
+ case NodeType.AddressDereference:
+ this.VisitAddressDereference((AddressDereference)node); return;
+ case NodeType.Arglist:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.AssignmentStatement:
+ this.VisitAssignmentStatement((AssignmentStatement)node); return;
+ case NodeType.Base:
+ this.VisitBase((Base)node); return;
+ case NodeType.Block:
+ this.VisitBlock((Block)node); return;
+ case NodeType.BlockExpression:
+ this.VisitBlockExpression((BlockExpression)node); return;
+ case NodeType.Branch:
+ this.VisitBranch((Branch)node); return;
+ case NodeType.DebugBreak:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.Call:
+ case NodeType.Calli:
+ case NodeType.Callvirt:
+ case NodeType.Jmp:
+ case NodeType.MethodCall:
+ this.VisitMethodCall((MethodCall)node); return;
+ case NodeType.Construct:
+ this.VisitConstruct((Construct)node); return;
+ case NodeType.ConstructArray:
+ this.VisitConstructArray((ConstructArray)node); return;
+ case NodeType.Dup:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.EndFilter:
+ this.VisitEndFilter((EndFilter)node); return;
+ case NodeType.EndFinally:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.ExpressionStatement:
+ this.VisitExpressionStatement((ExpressionStatement)node); return;
+ case NodeType.Indexer:
+ this.VisitIndexer((Indexer)node); return;
+ case NodeType.Literal:
+ this.VisitLiteral((Literal)node); return;
+ case NodeType.Local:
+ this.VisitLocal((Local)node); return;
+ case NodeType.MemberBinding:
+ this.VisitMemberBinding((MemberBinding)node); return;
+ case NodeType.Nop:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.Parameter:
+ this.VisitParameter((Parameter)node); return;
+ case NodeType.Pop:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.Rethrow:
+ case NodeType.Throw:
+ this.VisitThrow((Throw)node); return;
+ case NodeType.Return:
+ this.VisitReturn((Return)node); return;
+ case NodeType.SwitchCaseBottom:
+ return;
+ case NodeType.SwitchInstruction:
+ this.VisitSwitchInstruction((SwitchInstruction)node); return;
+ case NodeType.This:
+ this.VisitThis((This)node); return;
+ case NodeType.Cpblk:
+ case NodeType.Initblk:
+ this.VisitTernaryExpression((TernaryExpression)node); return;
+ case NodeType.Add:
+ case NodeType.Add_Ovf:
+ case NodeType.Add_Ovf_Un:
+ case NodeType.And:
+ case NodeType.Box:
+ case NodeType.Castclass:
+ case NodeType.Ceq:
+ case NodeType.Cgt:
+ case NodeType.Cgt_Un:
+ case NodeType.Clt:
+ case NodeType.Clt_Un:
+ case NodeType.Div:
+ case NodeType.Div_Un:
+ case NodeType.Eq:
+ case NodeType.Ge:
+ case NodeType.Gt:
+ case NodeType.Is:
+ case NodeType.Isinst:
+ case NodeType.Ldvirtftn:
+ case NodeType.Le:
+ case NodeType.Lt:
+ case NodeType.Mkrefany:
+ case NodeType.Mul:
+ case NodeType.Mul_Ovf:
+ case NodeType.Mul_Ovf_Un:
+ case NodeType.Ne:
+ case NodeType.Or:
+ case NodeType.Refanyval:
+ case NodeType.Rem:
+ case NodeType.Rem_Un:
+ case NodeType.Shl:
+ case NodeType.Shr:
+ case NodeType.Shr_Un:
+ case NodeType.Sub:
+ case NodeType.Sub_Ovf:
+ case NodeType.Sub_Ovf_Un:
+ case NodeType.Unbox:
+ case NodeType.UnboxAny:
+ case NodeType.Xor:
+ this.VisitBinaryExpression((BinaryExpression)node); return;
+ case NodeType.AddressOf:
+ case NodeType.OutAddress:
+ case NodeType.RefAddress:
+ case NodeType.ReadOnlyAddressOf:
+ this.VisitAddressOf((UnaryExpression)node); return;
+ case NodeType.Ckfinite:
+ case NodeType.Conv_I:
+ case NodeType.Conv_I1:
+ case NodeType.Conv_I2:
+ case NodeType.Conv_I4:
+ case NodeType.Conv_I8:
+ case NodeType.Conv_Ovf_I:
+ case NodeType.Conv_Ovf_I1:
+ case NodeType.Conv_Ovf_I1_Un:
+ case NodeType.Conv_Ovf_I2:
+ case NodeType.Conv_Ovf_I2_Un:
+ case NodeType.Conv_Ovf_I4:
+ case NodeType.Conv_Ovf_I4_Un:
+ case NodeType.Conv_Ovf_I8:
+ case NodeType.Conv_Ovf_I8_Un:
+ case NodeType.Conv_Ovf_I_Un:
+ case NodeType.Conv_Ovf_U:
+ case NodeType.Conv_Ovf_U1:
+ case NodeType.Conv_Ovf_U1_Un:
+ case NodeType.Conv_Ovf_U2:
+ case NodeType.Conv_Ovf_U2_Un:
+ case NodeType.Conv_Ovf_U4:
+ case NodeType.Conv_Ovf_U4_Un:
+ case NodeType.Conv_Ovf_U8:
+ case NodeType.Conv_Ovf_U8_Un:
+ case NodeType.Conv_Ovf_U_Un:
+ case NodeType.Conv_R4:
+ case NodeType.Conv_R8:
+ case NodeType.Conv_R_Un:
+ case NodeType.Conv_U:
+ case NodeType.Conv_U1:
+ case NodeType.Conv_U2:
+ case NodeType.Conv_U4:
+ case NodeType.Conv_U8:
+ case NodeType.Ldftn:
+ case NodeType.Ldlen:
+ case NodeType.Ldtoken:
+ case NodeType.Localloc:
+ case NodeType.Neg:
+ case NodeType.Not:
+ case NodeType.Refanytype:
+ case NodeType.Sizeof:
+ this.VisitUnaryExpression((UnaryExpression)node); return;
+ default:
+ Debug.Assert(false, "invalid node: " + node.NodeType.ToString());
+ return;
+ }
+ }
+
+ protected virtual void VisitAddressDereference(AddressDereference adr)
+ {
+ if (adr == null) return;
+ this.Visit(adr.Address);
+ if (adr.Alignment > 0)
+ this.ILGenerator.Emit(OpCodes.Unaligned, (byte)adr.Alignment);
+ if (adr.Volatile)
+ this.ILGenerator.Emit(OpCodes.Volatile);
+ if (adr.Type == null) return;
+ switch (adr.Type.typeCode)
+ {
+ case ElementType.Int8: this.ILGenerator.Emit(OpCodes.Ldind_I1); return;
+ case ElementType.UInt8: this.ILGenerator.Emit(OpCodes.Ldind_U1); return;
+ case ElementType.Int16: this.ILGenerator.Emit(OpCodes.Ldind_I2); return;
+ case ElementType.Char:
+ case ElementType.UInt16: this.ILGenerator.Emit(OpCodes.Ldind_U2); return;
+ case ElementType.Int32: this.ILGenerator.Emit(OpCodes.Ldind_I4); return;
+ case ElementType.UInt32: this.ILGenerator.Emit(OpCodes.Ldind_U4); return;
+ case ElementType.Int64:
+ case ElementType.UInt64: this.ILGenerator.Emit(OpCodes.Ldind_I8); return;
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: this.ILGenerator.Emit(OpCodes.Ldind_I); return;
+ case ElementType.Single: this.ILGenerator.Emit(OpCodes.Ldind_R4); return;
+ case ElementType.Double: this.ILGenerator.Emit(OpCodes.Ldind_R8); return;
+ default:
+ if (adr.Type.IsValueType && !(adr.Type is TypeParameter))
+ {
+ this.ILGenerator.Emit(OpCodes.Ldobj, adr.Type.GetRuntimeType());
+ return;
+ }
+ else if (TypeNode.StripModifiers(adr.Type) is Pointer)
+ {
+ this.ILGenerator.Emit(OpCodes.Ldind_I);
+ return;
+ }
+ this.ILGenerator.Emit(OpCodes.Ldind_Ref);
+ return;
+ }
+ }
+ protected virtual void VisitAddressOf(UnaryExpression expr)
+ {
+ if (expr == null) return;
+ Expression operand = expr.Operand;
+ if (operand == null) return;
+ switch (operand.NodeType)
+ {
+ case NodeType.Indexer:
+ Indexer indexer = (Indexer)operand;
+ this.Visit(indexer.Object);
+ if (indexer.Operands != null && indexer.Operands.Count == 1)
+ this.Visit(indexer.Operands[0]);
+ if (expr.NodeType == NodeType.ReadOnlyAddressOf)
+ this.ILGenerator.Emit(OpCodes.Readonly);
+ if (indexer.ElementType != null)
+ this.ILGenerator.Emit(OpCodes.Ldelema, indexer.ElementType.GetRuntimeType());
+ return;
+ case NodeType.Local:
+ int li = this.GetLocalVarIndex((Local)operand);
+ if (li < 256)
+ this.ILGenerator.Emit(OpCodes.Ldloca_S, this.locals[li]);
+ else
+ this.ILGenerator.Emit(OpCodes.Ldloca, this.locals[li]);
+ return;
+ case NodeType.MemberBinding:
+ MemberBinding mb = (MemberBinding)operand;
+ Field f = mb.BoundMember as Field;
+ if (f == null) { Debug.Fail(""); return; }
+ System.Reflection.FieldInfo fieldInfo = f.GetFieldInfo();
+ if (fieldInfo == null) { Debug.Fail(""); return; }
+ if (mb.TargetObject != null)
+ {
+ this.Visit(mb.TargetObject);
+ this.ILGenerator.Emit(OpCodes.Ldflda, fieldInfo);
+ }
+ else
+ {
+ this.ILGenerator.Emit(OpCodes.Ldsflda, fieldInfo);
+ }
+ return;
+ case NodeType.Parameter:
+ ParameterBinding pb = operand as ParameterBinding;
+ if (pb != null) operand = pb.BoundParameter;
+ int pi = ((Parameter)operand).ArgumentListIndex;
+ if (pi < 256)
+ this.ILGenerator.Emit(OpCodes.Ldarga_S, (byte)pi);
+ else
+ this.ILGenerator.Emit(OpCodes.Ldarga, (ushort)pi);
+ return;
+ }
+ }
+ protected virtual void VisitAssignmentStatement(AssignmentStatement assignment)
+ {
+ if (assignment == null) return;
+ Expression target = assignment.Target;
+ if (target == null) { Debug.Fail(""); return; }
+ switch (target.NodeType)
+ {
+ case NodeType.Local:
+ Local loc = (Local)target;
+ this.Visit(assignment.Source);
+ int li = this.GetLocalVarIndex(loc);
+ switch (li)
+ {
+ case 0: this.ILGenerator.Emit(OpCodes.Stloc_0); return;
+ case 1: this.ILGenerator.Emit(OpCodes.Stloc_1); return;
+ case 2: this.ILGenerator.Emit(OpCodes.Stloc_2); return;
+ case 3: this.ILGenerator.Emit(OpCodes.Stloc_3); return;
+ default:
+ if (li < 256)
+ this.ILGenerator.Emit(OpCodes.Stloc_S, this.locals[li]);
+ else
+ this.ILGenerator.Emit(OpCodes.Stloc, this.locals[li]);
+ return;
+ }
+ case NodeType.MemberBinding:
+ MemberBinding mb = (MemberBinding)target;
+ Field f = mb.BoundMember as Field;
+ if (f == null) { Debug.Fail(""); return; }
+ System.Reflection.FieldInfo fieldInfo = f.GetFieldInfo();
+ if (fieldInfo == null) { Debug.Fail(""); return; }
+ if (mb.TargetObject != null) this.Visit(mb.TargetObject);
+ this.Visit(assignment.Source);
+ if (mb.TargetObject != null)
+ {
+ if (mb.Alignment != -1)
+ this.ILGenerator.Emit(OpCodes.Unaligned, (byte)mb.Alignment);
+ if (mb.Volatile)
+ this.ILGenerator.Emit(OpCodes.Volatile);
+ this.ILGenerator.Emit(OpCodes.Stfld, fieldInfo);
+ }
+ else
+ this.ILGenerator.Emit(OpCodes.Stsfld, fieldInfo);
+ return;
+ case NodeType.Parameter:
+ ParameterBinding pb = target as ParameterBinding;
+ if (pb != null) target = pb.BoundParameter;
+ Parameter par = (Parameter)target;
+ this.Visit(assignment.Source);
+ int pi = par.ArgumentListIndex;
+ if (pi < 256)
+ this.ILGenerator.Emit(OpCodes.Starg_S, (byte)pi);
+ else
+ this.ILGenerator.Emit(OpCodes.Starg, (ushort)pi);
+ return;
+ case NodeType.Indexer:
+ Indexer indexer = (Indexer)target;
+ this.Visit(indexer.Object);
+ if (indexer.Operands != null && indexer.Operands.Count == 1)
+ this.Visit(indexer.Operands[0]);
+ this.Visit(assignment.Source);
+ Type elementType = indexer.ElementType == null ? null : indexer.ElementType.GetRuntimeType();
+ if (elementType == null) { Debug.Fail(""); return; }
+ this.ILGenerator.Emit(OpCodes.Ldelema, elementType);
+ System.Reflection.Emit.OpCode opCode;
+ //^ assert indexer.ElementType != null;
+ switch (indexer.ElementType.typeCode)
+ {
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: opCode = OpCodes.Stelem_I; break;
+ case ElementType.Boolean:
+ case ElementType.Int8:
+ case ElementType.UInt8: opCode = OpCodes.Stelem_I1; break;
+ case ElementType.Char:
+ case ElementType.Int16:
+ case ElementType.UInt16: opCode = OpCodes.Stelem_I2; break;
+ case ElementType.Int32:
+ case ElementType.UInt32: opCode = OpCodes.Stelem_I4; break;
+ case ElementType.Int64:
+ case ElementType.UInt64: opCode = OpCodes.Stelem_I8; break;
+ case ElementType.Single: opCode = OpCodes.Stelem_R4; break;
+ case ElementType.Double: opCode = OpCodes.Stelem_R8; break;
+ default:
+ if (indexer.ElementType.NodeType == NodeType.TypeParameter || indexer.ElementType.NodeType == NodeType.ClassParameter)
+ opCode = OpCodes.Stelem;
+ else if (TypeNode.StripModifiers(indexer.ElementType) is Pointer)
+ opCode = OpCodes.Stelem_I;
+ else
+ opCode = OpCodes.Stelem_Ref;
+ break;
+ }
+ if (opCode.Name == OpCodes.Stelem.Name)
+ this.ILGenerator.Emit(opCode, indexer.ElementType.GetRuntimeType());
+ else
+ this.ILGenerator.Emit(opCode);
+ return;
+ case NodeType.AddressDereference:
+ AddressDereference adr = (AddressDereference)target;
+ if (adr.Type == null) { Debug.Fail(""); return; }
+ this.Visit(adr.Address);
+ if (adr.Type.IsValueType || adr.Type is TypeParameter)
+ {
+ Literal lit = assignment.Source as Literal;
+ if (lit != null && lit.Value == null)
+ {
+ this.ILGenerator.Emit(OpCodes.Initobj, adr.Type.GetRuntimeType());
+ return;
+ }
+ }
+ this.Visit(assignment.Source);
+ if (adr.Alignment > 0)
+ this.ILGenerator.Emit(OpCodes.Unaligned, (byte)adr.Alignment);
+ if (adr.Volatile)
+ this.ILGenerator.Emit(OpCodes.Volatile);
+ TypeNode adrType = TypeNode.StripModifiers(adr.Type);
+ //^ assert adrType != null;
+ switch (adrType.typeCode)
+ {
+ case ElementType.Int8:
+ case ElementType.UInt8: this.ILGenerator.Emit(OpCodes.Stind_I1); return;
+ case ElementType.Int16:
+ case ElementType.UInt16: this.ILGenerator.Emit(OpCodes.Stind_I2); return;
+ case ElementType.Int32:
+ case ElementType.UInt32: this.ILGenerator.Emit(OpCodes.Stind_I4); return;
+ case ElementType.Int64:
+ case ElementType.UInt64: this.ILGenerator.Emit(OpCodes.Stind_I8); return;
+ case ElementType.Single: this.ILGenerator.Emit(OpCodes.Stind_R4); return;
+ case ElementType.Double: this.ILGenerator.Emit(OpCodes.Stind_R8); return;
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: this.ILGenerator.Emit(OpCodes.Stind_I); return;
+ default:
+ if (adrType != null && (adrType.IsValueType ||
+ adrType.NodeType == NodeType.TypeParameter || adrType.NodeType == NodeType.ClassParameter))
+ {
+ this.ILGenerator.Emit(OpCodes.Stobj, adrType.GetRuntimeType());
+ return;
+ }
+ if (adrType.NodeType == NodeType.Pointer)
+ {
+ this.ILGenerator.Emit(OpCodes.Stind_I);
+ return;
+ }
+ this.ILGenerator.Emit(OpCodes.Stind_Ref);
+ return;
+ }
+ default:
+ Debug.Assert(false, "unexpected assignment target");
+ return;
+ }
+ }
+ protected virtual void VisitBase(Base Base)
+ {
+ this.ILGenerator.Emit(OpCodes.Ldarg_0);
+ }
+ protected virtual void VisitBinaryExpression(BinaryExpression binaryExpression)
+ {
+ if (binaryExpression == null) return;
+ System.Reflection.Emit.OpCode opCode = OpCodes.Nop;
+ this.Visit(binaryExpression.Operand1);
+ switch (binaryExpression.NodeType)
+ {
+ case NodeType.Castclass: opCode = OpCodes.Castclass; goto writeOpCodeAndToken;
+ case NodeType.Isinst: opCode = OpCodes.Isinst; goto writeOpCodeAndToken;
+ case NodeType.Unbox: opCode = OpCodes.Unbox; goto writeOpCodeAndToken;
+ case NodeType.UnboxAny: opCode = OpCodes.Unbox_Any; goto writeOpCodeAndToken;
+ case NodeType.Box: opCode = OpCodes.Box; goto writeOpCodeAndToken;
+ case NodeType.Refanyval: opCode = OpCodes.Refanyval; goto writeOpCodeAndToken;
+ case NodeType.Mkrefany: opCode = OpCodes.Mkrefany; goto writeOpCodeAndToken;
+ writeOpCodeAndToken:
+ Literal lit = binaryExpression.Operand2 as Literal;
+ if (lit != null)
+ this.ILGenerator.Emit(opCode, ((TypeNode)lit.Value).GetRuntimeType());
+ else
+ this.ILGenerator.Emit(opCode, ((TypeNode)((MemberBinding)binaryExpression.Operand2).BoundMember).GetRuntimeType());
+ return;
+ case NodeType.Ldvirtftn:
+ System.Reflection.MethodInfo meth = ((Method)((MemberBinding)binaryExpression.Operand2).BoundMember).GetMethodInfo();
+ if (meth == null) { Debug.Fail(""); return; }
+ this.ILGenerator.Emit(OpCodes.Ldvirtftn, meth);
+ return;
+ }
+ this.Visit(binaryExpression.Operand2);
+ switch (binaryExpression.NodeType)
+ {
+ case NodeType.Add: opCode = OpCodes.Add; break;
+ case NodeType.Sub: opCode = OpCodes.Sub; break;
+ case NodeType.Mul: opCode = OpCodes.Mul; break;
+ case NodeType.Div: opCode = OpCodes.Div; break;
+ case NodeType.Div_Un: opCode = OpCodes.Div_Un; break;
+ case NodeType.Rem: opCode = OpCodes.Rem; break;
+ case NodeType.Rem_Un: opCode = OpCodes.Rem_Un; break;
+ case NodeType.And: opCode = OpCodes.And; break;
+ case NodeType.Or: opCode = OpCodes.Or; break;
+ case NodeType.Xor: opCode = OpCodes.Xor; break;
+ case NodeType.Shl: opCode = OpCodes.Shl; break;
+ case NodeType.Shr: opCode = OpCodes.Shr; break;
+ case NodeType.Shr_Un: opCode = OpCodes.Shr_Un; break;
+ case NodeType.Add_Ovf: opCode = OpCodes.Add_Ovf; break;
+ case NodeType.Add_Ovf_Un: opCode = OpCodes.Add_Ovf_Un; break;
+ case NodeType.Mul_Ovf: opCode = OpCodes.Mul_Ovf; break;
+ case NodeType.Mul_Ovf_Un: opCode = OpCodes.Mul_Ovf_Un; break;
+ case NodeType.Sub_Ovf: opCode = OpCodes.Sub_Ovf; break;
+ case NodeType.Sub_Ovf_Un: opCode = OpCodes.Sub_Ovf_Un; break;
+ case NodeType.Ceq: opCode = OpCodes.Ceq; break;
+ case NodeType.Cgt: opCode = OpCodes.Cgt; break;
+ case NodeType.Cgt_Un: opCode = OpCodes.Cgt_Un; break;
+ case NodeType.Clt: opCode = OpCodes.Clt; break;
+ case NodeType.Clt_Un: opCode = OpCodes.Clt_Un; break;
+ }
+ this.ILGenerator.Emit(opCode);
+ }
+ protected virtual void VisitBlock(Block block)
+ {
+ if (block == null) return;
+ if (this.catchStart[block.UniqueKey] != null)
+ this.ILGenerator.BeginCatchBlock((Type)this.catchTypeNode[block.UniqueKey]);
+ else if (this.finallyStart[block.UniqueKey] != null)
+ this.ILGenerator.BeginFinallyBlock();
+ else
+ {
+ object count = this.exceptionEndCount[block.UniqueKey];
+ for (int i = 0, n = count == null ? 0 : (int)count; i < n; i++)
+ this.ILGenerator.EndExceptionBlock();
+ count = this.exceptionStartCount[block.UniqueKey];
+ for (int i = 0, n = count == null ? 0 : (int)count; i < n; i++)
+ this.ILGenerator.BeginExceptionBlock();
+ }
+ Label label = this.GetLabel(block);
+ this.ILGenerator.MarkLabel(label);
+ StatementList statements = block.Statements;
+ if (statements == null) return;
+ if (block.HasLocals) this.ILGenerator.BeginScope();
+ for (int i = 0, n = statements.Count; i < n; i++)
+ this.Visit(statements[i]);
+ if (block.HasLocals) this.ILGenerator.EndScope();
+ }
+ protected virtual void VisitBlockExpression(BlockExpression blockExpression)
+ {
+ if (blockExpression == null) return;
+ this.VisitBlock(blockExpression.Block);
+ }
+ protected virtual void VisitBranch(Branch branch)
+ {
+ if (branch == null) return;
+ BinaryExpression bex = branch.Condition as BinaryExpression;
+ UnaryExpression uex = null;
+ NodeType typeOfCondition = NodeType.Nop;
+ if (bex != null)
+ {
+ switch (bex.NodeType)
+ {
+ case NodeType.Eq:
+ case NodeType.Ge:
+ case NodeType.Gt:
+ case NodeType.Le:
+ case NodeType.Lt:
+ case NodeType.Ne:
+ this.Visit(bex.Operand1);
+ this.Visit(bex.Operand2);
+ if (bex.Operand1 != null && bex.Operand1.Type != null && bex.Operand1.Type.IsUnsignedPrimitiveNumeric)
+ branch.BranchIfUnordered = true; //Overloaded to mean branch if unsigned for integer operands
+ typeOfCondition = bex.NodeType;
+ break;
+ case NodeType.And:
+ case NodeType.Or:
+ case NodeType.Xor:
+ case NodeType.Isinst:
+ case NodeType.Castclass:
+ typeOfCondition = NodeType.If;
+ goto default;
+ default:
+ this.Visit(branch.Condition);
+ break;
+ }
+ }
+ else
+ {
+ uex = branch.Condition as UnaryExpression;
+ if (uex != null && uex.NodeType == NodeType.LogicalNot)
+ {
+ this.Visit(uex.Operand);
+ typeOfCondition = NodeType.LogicalNot;
+ }
+ else if (branch.Condition != null)
+ {
+ typeOfCondition = NodeType.If;
+ this.Visit(branch.Condition);
+ }
+ }
+ Label target = this.GetLabel(branch.Target);
+ System.Reflection.Emit.OpCode opCode = OpCodes.Nop;
+ if (branch.ShortOffset)
+ {
+ switch (typeOfCondition)
+ {
+ case NodeType.Nop:
+ if (branch.Condition == null)
+ {
+ if (branch.LeavesExceptionBlock)
+ opCode = OpCodes.Leave_S;
+ else
+ opCode = OpCodes.Br_S;
+ break;
+ }
+ else
+ {
+ opCode = OpCodes.Brtrue_S; break;
+ }
+ case NodeType.If:
+ opCode = OpCodes.Brtrue_S; break;
+ case NodeType.LogicalNot:
+ opCode = OpCodes.Brfalse_S; break;
+ case NodeType.Eq:
+ opCode = OpCodes.Beq_S; break;
+ case NodeType.Ge:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Bge_Un_S;
+ else
+ opCode = OpCodes.Bge_S;
+ break;
+ case NodeType.Gt:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Bgt_Un_S;
+ else
+ opCode = OpCodes.Bgt_S;
+ break;
+ case NodeType.Le:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Ble_Un_S;
+ else
+ opCode = OpCodes.Ble_S;
+ break;
+ case NodeType.Lt:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Blt_Un_S;
+ else
+ opCode = OpCodes.Blt_S;
+ break;
+ case NodeType.Ne:
+ opCode = OpCodes.Bne_Un_S;
+ break;
+ }
+ this.ILGenerator.Emit(opCode, target);
+ }
+ else
+ {
+ switch (typeOfCondition)
+ {
+ case NodeType.Nop:
+ if (branch.Condition == null)
+ {
+ if (branch.LeavesExceptionBlock)
+ opCode = OpCodes.Leave;
+ else
+ opCode = OpCodes.Br;
+ break;
+ }
+ else
+ {
+ opCode = OpCodes.Brtrue; break;
+ }
+ case NodeType.If:
+ opCode = OpCodes.Brtrue; break;
+ case NodeType.LogicalNot:
+ opCode = OpCodes.Brfalse; break;
+ case NodeType.Eq:
+ opCode = OpCodes.Beq; break;
+ case NodeType.Ge:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Bge_Un;
+ else
+ opCode = OpCodes.Bge;
+ break;
+ case NodeType.Gt:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Bgt_Un;
+ else
+ opCode = OpCodes.Bgt;
+ break;
+ case NodeType.Le:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Ble_Un;
+ else
+ opCode = OpCodes.Ble;
+ break;
+ case NodeType.Lt:
+ if (branch.BranchIfUnordered)
+ opCode = OpCodes.Blt_Un;
+ else
+ opCode = OpCodes.Blt;
+ break;
+ case NodeType.Ne:
+ opCode = OpCodes.Bne_Un; break;
+ }
+ this.ILGenerator.Emit(opCode, target);
+ }
+ }
+ protected virtual void VisitMethodCall(MethodCall call)
+ {
+ if (call == null) return;
+ MemberBinding mb = (MemberBinding)call.Callee;
+ this.Visit(mb.TargetObject);
+ ExpressionList arguments = call.Operands;
+ if (arguments == null) arguments = new ExpressionList(0);
+ this.VisitExpressionList(arguments);
+ if (call.IsTailCall)
+ this.ILGenerator.Emit(OpCodes.Tailcall);
+ else if (call.Constraint != null)
+ this.ILGenerator.Emit(OpCodes.Constrained, call.Constraint.GetRuntimeType());
+ if (call.NodeType == NodeType.Calli)
+ {
+ FunctionPointer fp = (FunctionPointer)mb.BoundMember;
+ CallingConventionFlags callConv = fp.CallingConvention & CallingConventionFlags.ArgumentConvention;
+ if (callConv != CallingConventionFlags.VarArg)
+ {
+ Type[] parameterTypes = new Type[fp.ParameterTypes.Count];
+ for (int i = 0, n = fp.ParameterTypes.Count; i < n; i++)
+ {
+ parameterTypes[i] = fp.ParameterTypes[i].GetRuntimeType();
+ }
+ this.ILGenerator.EmitCalli(OpCodes.Calli, (System.Runtime.InteropServices.CallingConvention)callConv,
+ fp.ReturnType.GetRuntimeType(), parameterTypes);
+ }
+ else
+ {
+ Type[] parameterTypes = new Type[fp.VarArgStart];
+ Type[] optionalParameterTypes = new Type[fp.ParameterTypes.Count - fp.VarArgStart];
+ for (int i = 0, n = fp.ParameterTypes.Count; i < n; i++)
+ {
+ if (i < fp.VarArgStart)
+ parameterTypes[i] = fp.ParameterTypes[i].GetRuntimeType();
+ else
+ optionalParameterTypes[i - fp.VarArgStart] = fp.ParameterTypes[i].GetRuntimeType();
+ }
+ this.ILGenerator.EmitCalli(OpCodes.Calli, (System.Reflection.CallingConventions)callConv,
+ fp.ReturnType.GetRuntimeType(), parameterTypes, optionalParameterTypes);
+ }
+ return;
+ }
+ Method method = (Method)mb.BoundMember;
+ System.Reflection.MethodInfo methodInfo = method.GetMethodInfo();
+ if (methodInfo == null) { Debug.Fail(""); return; }
+ System.Reflection.Emit.OpCode opCode;
+ switch (call.NodeType)
+ {
+ case NodeType.Callvirt: opCode = OpCodes.Callvirt; break;
+ case NodeType.Jmp: opCode = OpCodes.Jmp; break;
+ default: opCode = OpCodes.Call; break;
+ }
+ if ((method.CallingConvention & CallingConventionFlags.ArgumentConvention) == CallingConventionFlags.VarArg ||
+ (method.CallingConvention & CallingConventionFlags.ArgumentConvention) == CallingConventionFlags.C)
+ {
+ int varArgStart = method.Parameters.Count;
+ Type[] optionalParameterTypes = new Type[arguments.Count - varArgStart];
+ for (int i = varArgStart, n = arguments.Count; i < n; i++)
+ optionalParameterTypes[i - varArgStart] = arguments[i].Type.GetRuntimeType();
+ this.ILGenerator.EmitCall(opCode, methodInfo, optionalParameterTypes);
+ }
+ else
+ this.ILGenerator.EmitCall(opCode, methodInfo, null);
+ }
+ protected virtual void VisitConstruct(Construct cons)
+ {
+ if (cons == null) return;
+ ExpressionList operands = cons.Operands;
+ if (operands != null)
+ {
+ this.VisitExpressionList(cons.Operands);
+ }
+ Method method = (Method)((MemberBinding)cons.Constructor).BoundMember;
+ System.Reflection.MethodInfo methodInfo = method.GetMethodInfo();
+ if (methodInfo != null) this.ILGenerator.Emit(OpCodes.Newobj, methodInfo);
+ }
+ protected virtual void VisitConstructArray(ConstructArray consArr)
+ {
+ if (consArr == null || consArr.Operands == null || consArr.Operands.Count == 0) return;
+ this.Visit(consArr.Operands[0]);
+ this.ILGenerator.Emit(OpCodes.Newarr, consArr.ElementType.GetRuntimeType());
+ }
+ protected virtual void VisitEndFilter(EndFilter endFilter)
+ {
+ this.ILGenerator.Emit(OpCodes.Endfilter);
+ }
+ protected virtual void VisitExpression(Expression expression)
+ {
+ if (expression == null) return;
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ this.ILGenerator.Emit(OpCodes.Dup);
+ return;
+ case NodeType.Pop:
+ UnaryExpression unex = expression as UnaryExpression;
+ if (unex != null)
+ {
+ this.Visit(unex.Operand);
+ this.ILGenerator.Emit(OpCodes.Pop);
+ }
+ return;
+ case NodeType.Arglist:
+ this.ILGenerator.Emit(OpCodes.Arglist);
+ return;
+ }
+ }
+ protected virtual void VisitExpressionList(ExpressionList expressions)
+ {
+ if (expressions == null) return;
+ for (int i = 0, n = expressions.Count; i < n; i++)
+ this.Visit(expressions[i]);
+ }
+ protected virtual void VisitExpressionStatement(ExpressionStatement statement)
+ {
+ if (statement == null) return;
+ this.Visit(statement.Expression);
+ }
+ protected virtual void VisitIndexer(Indexer indexer)
+ {
+ if (indexer == null || indexer.Operands == null || indexer.Operands.Count == 0) return;
+ this.Visit(indexer.Object);
+ this.Visit(indexer.Operands[0]);
+ System.Reflection.Emit.OpCode opCode;
+ switch (indexer.ElementType.typeCode)
+ {
+ case ElementType.Boolean:
+ case ElementType.Int8: opCode = OpCodes.Ldelem_I1; break;
+ case ElementType.UInt8: opCode = OpCodes.Ldelem_U1; break;
+ case ElementType.Int16: opCode = OpCodes.Ldelem_I2; break;
+ case ElementType.Char:
+ case ElementType.UInt16: opCode = OpCodes.Ldelem_U2; break;
+ case ElementType.Int32: opCode = OpCodes.Ldelem_I4; break;
+ case ElementType.UInt32: opCode = OpCodes.Ldelem_U4; break;
+ case ElementType.Int64:
+ case ElementType.UInt64: opCode = OpCodes.Ldelem_I8; break;
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: opCode = OpCodes.Ldelem_I; break;
+ case ElementType.Single: opCode = OpCodes.Ldelem_R4; break;
+ case ElementType.Double: opCode = OpCodes.Ldelem_R8; break;
+ default:
+ if (indexer.ElementType.NodeType == NodeType.TypeParameter || indexer.ElementType.NodeType == NodeType.ClassParameter)
+ opCode = OpCodes.Ldelem;
+ else if (indexer.ElementType is Pointer)
+ opCode = OpCodes.Ldelem_I;
+ else
+ opCode = OpCodes.Ldelem_Ref;
+ break;
+ }
+ if (opCode.Name == OpCodes.Ldelem.Name)
+ this.ILGenerator.Emit(opCode, indexer.ElementType.GetRuntimeType());
+ else
+ this.ILGenerator.Emit(opCode);
+ }
+ protected virtual void VisitLocal(Local local)
+ {
+ if (local == null) return;
+ int li = this.GetLocalVarIndex(local);
+ switch (li)
+ {
+ case 0: this.ILGenerator.Emit(OpCodes.Ldloc_0); return;
+ case 1: this.ILGenerator.Emit(OpCodes.Ldloc_1); return;
+ case 2: this.ILGenerator.Emit(OpCodes.Ldloc_2); return;
+ case 3: this.ILGenerator.Emit(OpCodes.Ldloc_3); return;
+ default:
+ if (li < 256)
+ this.ILGenerator.Emit(OpCodes.Ldloc_S, (byte)li);
+ else
+ this.ILGenerator.Emit(OpCodes.Ldloc, (ushort)li);
+ return;
+ }
+ }
+ protected virtual void VisitLiteral(Literal literal)
+ {
+ if (literal == null) return;
+ IConvertible ic = literal.Value as IConvertible;
+ if (ic == null)
+ {
+ Debug.Assert(literal.Value == null && !literal.Type.IsValueType);
+ this.ILGenerator.Emit(OpCodes.Ldnull); return;
+ }
+ TypeCode tc = ic.GetTypeCode();
+ switch (tc)
+ {
+ case TypeCode.Boolean:
+ case TypeCode.SByte:
+ case TypeCode.Byte:
+ case TypeCode.Char:
+ case TypeCode.Int16:
+ case TypeCode.UInt16:
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ case TypeCode.Int64:
+ long n = ic.ToInt64(null);
+ switch (n)
+ {
+ case -1: this.ILGenerator.Emit(OpCodes.Ldc_I4_M1); break;
+ case 0: this.ILGenerator.Emit(OpCodes.Ldc_I4_0); break;
+ case 1: this.ILGenerator.Emit(OpCodes.Ldc_I4_1); break;
+ case 2: this.ILGenerator.Emit(OpCodes.Ldc_I4_2); break;
+ case 3: this.ILGenerator.Emit(OpCodes.Ldc_I4_3); break;
+ case 4: this.ILGenerator.Emit(OpCodes.Ldc_I4_4); break;
+ case 5: this.ILGenerator.Emit(OpCodes.Ldc_I4_5); break;
+ case 6: this.ILGenerator.Emit(OpCodes.Ldc_I4_6); break;
+ case 7: this.ILGenerator.Emit(OpCodes.Ldc_I4_7); break;
+ case 8: this.ILGenerator.Emit(OpCodes.Ldc_I4_8); break;
+ default:
+ if (n >= System.SByte.MinValue && n <= System.SByte.MaxValue)
+ {
+ this.ILGenerator.Emit(OpCodes.Ldc_I4_S, (byte)n);
+ }
+ else if (n >= System.Int32.MinValue && n <= System.Int32.MaxValue ||
+ n <= System.UInt32.MaxValue && (tc == TypeCode.Char || tc == TypeCode.UInt16 || tc == TypeCode.UInt32))
+ {
+ if (n == System.UInt32.MaxValue && tc != TypeCode.Int64)
+ this.ILGenerator.Emit(OpCodes.Ldc_I4_M1);
+ else
+ {
+ this.ILGenerator.Emit(OpCodes.Ldc_I4, (int)n);
+ }
+ }
+ else
+ {
+ this.ILGenerator.Emit(OpCodes.Ldc_I8, (long)n);
+ tc = TypeCode.Empty; //Suppress conversion to long
+ }
+ break;
+ }
+ if (tc == TypeCode.Int64)
+ this.ILGenerator.Emit(OpCodes.Conv_I8);
+ return;
+
+ case TypeCode.UInt64:
+ this.ILGenerator.Emit(OpCodes.Ldc_I8, ic.ToUInt64(null));
+ return;
+
+ case TypeCode.Single:
+ this.ILGenerator.Emit(OpCodes.Ldc_R4, ic.ToSingle(null));
+ return;
+
+ case TypeCode.Double:
+ this.ILGenerator.Emit(OpCodes.Ldc_R8, ic.ToDouble(null));
+ return;
+
+ case TypeCode.String:
+ this.ILGenerator.Emit(OpCodes.Ldstr, (string)literal.Value);
+ return;
+ }
+ Debug.Assert(false, "Unexpected literal type");
+ }
+ protected virtual void VisitMemberBinding(MemberBinding memberBinding)
+ {
+ if (memberBinding == null) return;
+ System.Reflection.FieldInfo fieldInfo = ((Field)memberBinding.BoundMember).GetFieldInfo();
+ if (memberBinding.TargetObject != null)
+ {
+ this.Visit(memberBinding.TargetObject);
+ this.ILGenerator.Emit(OpCodes.Ldfld, fieldInfo);
+ }
+ else
+ {
+ this.ILGenerator.Emit(OpCodes.Ldsfld, fieldInfo);
+ }
+ return;
+ }
+ protected virtual void VisitParameter(Parameter parameter)
+ {
+ if (parameter == null) return;
+ ParameterBinding pb = parameter as ParameterBinding;
+ if (pb != null) parameter = pb.BoundParameter;
+ int pi = parameter.ArgumentListIndex;
+ switch (pi)
+ {
+ case 0: this.ILGenerator.Emit(OpCodes.Ldarg_0); return;
+ case 1: this.ILGenerator.Emit(OpCodes.Ldarg_1); return;
+ case 2: this.ILGenerator.Emit(OpCodes.Ldarg_2); return;
+ case 3: this.ILGenerator.Emit(OpCodes.Ldarg_3); return;
+ default:
+ if (pi < 256)
+ this.ILGenerator.Emit(OpCodes.Ldarg_S, (byte)pi);
+ else
+ this.ILGenerator.Emit(OpCodes.Ldarg, (ushort)pi);
+ return;
+ }
+ }
+ protected virtual void VisitReturn(Return Return)
+ {
+ if (Return == null) return;
+ if (Return.Expression != null)
+ {
+ this.Visit(Return.Expression);
+ }
+ this.ILGenerator.Emit(OpCodes.Ret);
+ }
+ protected virtual void VisitStatement(Statement statement)
+ {
+ if (statement == null) return;
+ switch (statement.NodeType)
+ {
+ case NodeType.Nop: this.ILGenerator.Emit(OpCodes.Nop); break;
+ case NodeType.DebugBreak: this.ILGenerator.Emit(OpCodes.Break); break;
+ case NodeType.EndFinally: this.ILGenerator.Emit(OpCodes.Endfinally); break;
+ }
+ }
+ protected virtual void VisitSwitchInstruction(SwitchInstruction switchInstruction)
+ {
+ if (switchInstruction == null) return;
+ this.Visit(switchInstruction.Expression);
+ BlockList targets = switchInstruction.Targets;
+ int n = targets != null ? targets.Count : 0;
+ Label[] labelTable = new Label[n];
+ for (int i = 0; i < n; i++)
+ labelTable[i] = this.GetLabel(targets[i]);
+ this.ILGenerator.Emit(OpCodes.Switch, labelTable);
+ }
+ protected virtual void VisitTernaryExpression(TernaryExpression expression)
+ {
+ if (expression == null) return;
+ this.Visit(expression.Operand1);
+ this.Visit(expression.Operand2);
+ this.Visit(expression.Operand3);
+ if (expression.NodeType == NodeType.Cpblk)
+ this.ILGenerator.Emit(OpCodes.Cpblk);
+ else
+ this.ILGenerator.Emit(OpCodes.Initblk);
+ }
+ protected virtual void VisitThis(This This)
+ {
+ this.ILGenerator.Emit(OpCodes.Ldarg_0);
+ }
+ protected virtual void VisitThrow(Throw Throw)
+ {
+ if (Throw == null) return;
+ if (Throw.NodeType == NodeType.Rethrow)
+ this.ILGenerator.Emit(OpCodes.Rethrow);
+ else
+ {
+ this.Visit(Throw.Expression);
+ this.ILGenerator.Emit(OpCodes.Throw);
+ }
+ }
+ protected virtual void VisitUnaryExpression(UnaryExpression unaryExpression)
+ {
+ if (unaryExpression == null) return;
+ switch (unaryExpression.NodeType)
+ {
+ case NodeType.Ldtoken:
+ Literal lit = unaryExpression.Operand as Literal;
+ if (lit != null)
+ this.ILGenerator.Emit(OpCodes.Ldtoken, ((TypeNode)lit.Value).GetRuntimeType());
+ else
+ {
+ Member m = ((MemberBinding)unaryExpression.Operand).BoundMember;
+ Method meth = m as Method;
+ if (meth != null)
+ {
+ System.Reflection.MethodInfo methInfo = meth.GetMethodInfo();
+ if (methInfo == null) return;
+ this.ILGenerator.Emit(OpCodes.Ldtoken, methInfo);
+ }
+ else
+ {
+ System.Reflection.FieldInfo fieldInfo = ((Field)m).GetFieldInfo();
+ if (fieldInfo == null) return;
+ this.ILGenerator.Emit(OpCodes.Ldtoken, fieldInfo);
+ }
+ }
+ return;
+ case NodeType.Ldftn:
+ {
+ System.Reflection.MethodInfo methInfo = ((Method)((MemberBinding)unaryExpression.Operand).BoundMember).GetMethodInfo();
+ if (methInfo != null) this.ILGenerator.Emit(OpCodes.Ldftn, methInfo);
+ return;
+ }
+ case NodeType.Sizeof:
+ this.ILGenerator.Emit(OpCodes.Sizeof, ((TypeNode)((Literal)unaryExpression.Operand).Value).GetRuntimeType());
+ return;
+ }
+ this.Visit(unaryExpression.Operand);
+ System.Reflection.Emit.OpCode opCode = OpCodes.Nop;
+ switch (unaryExpression.NodeType)
+ {
+ case NodeType.Neg: opCode = OpCodes.Neg; break;
+ case NodeType.Not: opCode = OpCodes.Not; break;
+ case NodeType.Conv_I1: opCode = OpCodes.Conv_I1; break;
+ case NodeType.Conv_I2: opCode = OpCodes.Conv_I2; break;
+ case NodeType.Conv_I4: opCode = OpCodes.Conv_I4; break;
+ case NodeType.Conv_I8: opCode = OpCodes.Conv_I8; break;
+ case NodeType.Conv_R4: opCode = OpCodes.Conv_R4; break;
+ case NodeType.Conv_R8: opCode = OpCodes.Conv_R8; break;
+ case NodeType.Conv_U4: opCode = OpCodes.Conv_U4; break;
+ case NodeType.Conv_U8: opCode = OpCodes.Conv_U8; break;
+ case NodeType.Conv_R_Un: opCode = OpCodes.Conv_R_Un; break;
+ case NodeType.Conv_Ovf_I1_Un: opCode = OpCodes.Conv_Ovf_I1_Un; break;
+ case NodeType.Conv_Ovf_I2_Un: opCode = OpCodes.Conv_Ovf_I2_Un; break;
+ case NodeType.Conv_Ovf_I4_Un: opCode = OpCodes.Conv_Ovf_I4_Un; break;
+ case NodeType.Conv_Ovf_I8_Un: opCode = OpCodes.Conv_Ovf_I8_Un; break;
+ case NodeType.Conv_Ovf_U1_Un: opCode = OpCodes.Conv_Ovf_U1_Un; break;
+ case NodeType.Conv_Ovf_U2_Un: opCode = OpCodes.Conv_Ovf_U2_Un; break;
+ case NodeType.Conv_Ovf_U4_Un: opCode = OpCodes.Conv_Ovf_U4_Un; break;
+ case NodeType.Conv_Ovf_U8_Un: opCode = OpCodes.Conv_Ovf_U8_Un; break;
+ case NodeType.Conv_Ovf_I_Un: opCode = OpCodes.Conv_Ovf_I_Un; break;
+ case NodeType.Conv_Ovf_U_Un: opCode = OpCodes.Conv_Ovf_U_Un; break;
+ case NodeType.Ldlen: opCode = OpCodes.Ldlen; break;
+ case NodeType.Conv_Ovf_I1: opCode = OpCodes.Conv_Ovf_I1; break;
+ case NodeType.Conv_Ovf_U1: opCode = OpCodes.Conv_Ovf_U1; break;
+ case NodeType.Conv_Ovf_I2: opCode = OpCodes.Conv_Ovf_I2; break;
+ case NodeType.Conv_Ovf_U2: opCode = OpCodes.Conv_Ovf_U2; break;
+ case NodeType.Conv_Ovf_I4: opCode = OpCodes.Conv_Ovf_I4; break;
+ case NodeType.Conv_Ovf_U4: opCode = OpCodes.Conv_Ovf_U4; break;
+ case NodeType.Conv_Ovf_I8: opCode = OpCodes.Conv_Ovf_I8; break;
+ case NodeType.Conv_Ovf_U8: opCode = OpCodes.Conv_Ovf_U8; break;
+ case NodeType.Ckfinite: opCode = OpCodes.Ckfinite; break;
+ case NodeType.Conv_U2: opCode = OpCodes.Conv_U2; break;
+ case NodeType.Conv_U1: opCode = OpCodes.Conv_U1; break;
+ case NodeType.Conv_I: opCode = OpCodes.Conv_I; break;
+ case NodeType.Conv_Ovf_I: opCode = OpCodes.Conv_Ovf_I; break;
+ case NodeType.Conv_Ovf_U: opCode = OpCodes.Conv_Ovf_U; break;
+ case NodeType.Conv_U: opCode = OpCodes.Conv_U; break;
+ case NodeType.Localloc: opCode = OpCodes.Localloc; break;
+ case NodeType.Refanytype: opCode = OpCodes.Refanytype; break;
+ }
+ this.ILGenerator.Emit(opCode);
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/tools/Sandcastle/Source/CCI/ListTemplate.cs b/tools/Sandcastle/Source/CCI/ListTemplate.cs
new file mode 100644
index 0000000..4d18992
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/ListTemplate.cs
@@ -0,0 +1,4556 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !FxCop
+using System;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !MinimalReader
+ public sealed class AliasDefinitionList
+ {
+ private AliasDefinition[]/*!*/ elements;
+ private int count = 0;
+ public AliasDefinitionList()
+ {
+ this.elements = new AliasDefinition[4];
+ //^ base();
+ }
+ public AliasDefinitionList(int capacity)
+ {
+ this.elements = new AliasDefinition[capacity];
+ //^ base();
+ }
+ public void Add(AliasDefinition element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ AliasDefinition[] newElements = new AliasDefinition[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public AliasDefinitionList/*!*/ Clone()
+ {
+ AliasDefinition[] elements = this.elements;
+ int n = this.count;
+ AliasDefinitionList result = new AliasDefinitionList(n);
+ result.count = n;
+ AliasDefinition[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public AliasDefinition this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly AliasDefinitionList/*!*/ list;
+ public Enumerator(AliasDefinitionList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public AliasDefinition Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class AssemblyNodeList
+ {
+ private AssemblyNode[]/*!*/ elements;
+ private int count = 0;
+ public AssemblyNodeList()
+ {
+ this.elements = new AssemblyNode[4];
+ //^ base();
+ }
+ public AssemblyNodeList(int capacity)
+ {
+ this.elements = new AssemblyNode[capacity];
+ //^ base();
+ }
+ public AssemblyNodeList(params AssemblyNode[] elements)
+ {
+ if (elements == null) elements = new AssemblyNode[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(AssemblyNode element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ AssemblyNode[] newElements = new AssemblyNode[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public AssemblyNode this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly AssemblyNodeList/*!*/ list;
+ public Enumerator(AssemblyNodeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public AssemblyNode Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class AssemblyReferenceList
+ {
+ private AssemblyReference[]/*!*/ elements;
+ private int count = 0;
+ public AssemblyReferenceList()
+ {
+ this.elements = new AssemblyReference[4];
+ //^ base();
+ }
+ public AssemblyReferenceList(int capacity)
+ {
+ this.elements = new AssemblyReference[capacity];
+ //^ base();
+ }
+ public void Add(AssemblyReference element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ AssemblyReference[] newElements = new AssemblyReference[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public AssemblyReferenceList/*!*/ Clone()
+ {
+ AssemblyReference[] elements = this.elements;
+ int n = this.count;
+ AssemblyReferenceList result = new AssemblyReferenceList(n);
+ result.count = n;
+ AssemblyReference[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public AssemblyReference this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly AssemblyReferenceList/*!*/ list;
+ public Enumerator(AssemblyReferenceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public AssemblyReference Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class AttributeList
+ {
+ private AttributeNode[]/*!*/ elements;
+ private int count = 0;
+ public AttributeList()
+ {
+ this.elements = new AttributeNode[8];
+ //^ base();
+ }
+ public AttributeList(int capacity)
+ {
+ this.elements = new AttributeNode[capacity];
+ //^ base();
+ }
+ public AttributeList(params AttributeNode[] elements)
+ {
+ if (elements == null) elements = new AttributeNode[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(AttributeNode element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ AttributeNode[] newElements = new AttributeNode[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public AttributeList/*!*/ Clone()
+ {
+ AttributeNode[] elements = this.elements;
+ int n = this.count;
+ AttributeList result = new AttributeList(n);
+ result.count = n;
+ AttributeNode[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public AttributeNode this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly AttributeList/*!*/ list;
+ public Enumerator(AttributeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public AttributeNode Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class BlockList
+ {
+ private Block[]/*!*/ elements;
+ private int count = 0;
+ public BlockList()
+ {
+ this.elements = new Block[4];
+ //^ base();
+ }
+ public BlockList(int n)
+ {
+ this.elements = new Block[n];
+ //^ base();
+ }
+ public void Add(Block element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Block[] newElements = new Block[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public BlockList/*!*/ Clone()
+ {
+ Block[] elements = this.elements;
+ int n = this.count;
+ BlockList result = new BlockList(n);
+ result.count = n;
+ Block[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Block this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly BlockList/*!*/ list;
+ public Enumerator(BlockList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Block Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class CatchList
+ {
+ private Catch[]/*!*/ elements;
+ private int count = 0;
+ public CatchList()
+ {
+ this.elements = new Catch[4];
+ //^ base();
+ }
+ public CatchList(int n)
+ {
+ this.elements = new Catch[n];
+ //^ base();
+ }
+ public void Add(Catch element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Catch[] newElements = new Catch[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public CatchList/*!*/ Clone()
+ {
+ Catch[] elements = this.elements;
+ int n = this.count;
+ CatchList result = new CatchList(n);
+ result.count = n;
+ Catch[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Catch this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly CatchList/*!*/ list;
+ public Enumerator(CatchList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Catch Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class CompilationList
+ {
+ private Compilation[]/*!*/ elements;
+ private int count = 0;
+ public CompilationList()
+ {
+ this.elements = new Compilation[4];
+ //^ base();
+ }
+ public CompilationList(int n)
+ {
+ this.elements = new Compilation[n];
+ //^ base();
+ }
+ public CompilationList(params Compilation[] elements)
+ {
+ if (elements == null) elements = new Compilation[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Compilation element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Compilation[] newElements = new Compilation[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public CompilationList/*!*/ Clone()
+ {
+ Compilation[] elements = this.elements;
+ int n = this.count;
+ CompilationList result = new CompilationList(n);
+ result.count = n;
+ Compilation[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Compilation this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly CompilationList/*!*/ list;
+ public Enumerator(CompilationList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Compilation Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class CompilationUnitList
+ {
+ private CompilationUnit[]/*!*/ elements;
+ private int count = 0;
+ public CompilationUnitList()
+ {
+ this.elements = new CompilationUnit[4];
+ //^ base();
+ }
+ public CompilationUnitList(int n)
+ {
+ this.elements = new CompilationUnit[n];
+ //^ base();
+ }
+ public CompilationUnitList(params CompilationUnit[] elements)
+ {
+ if (elements == null) elements = new CompilationUnit[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(CompilationUnit element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ CompilationUnit[] newElements = new CompilationUnit[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public CompilationUnitList/*!*/ Clone()
+ {
+ CompilationUnit[] elements = this.elements;
+ int n = this.count;
+ CompilationUnitList result = new CompilationUnitList(n);
+ result.count = n;
+ CompilationUnit[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public CompilationUnit this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly CompilationUnitList/*!*/ list;
+ public Enumerator(CompilationUnitList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public CompilationUnit Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class CompilationUnitSnippetList
+ {
+ private CompilationUnitSnippet[]/*!*/ elements;
+ private int count = 0;
+ public CompilationUnitSnippetList()
+ {
+ this.elements = new CompilationUnitSnippet[4];
+ //^ base();
+ }
+ public CompilationUnitSnippetList(int n)
+ {
+ this.elements = new CompilationUnitSnippet[n];
+ //^ base();
+ }
+ public CompilationUnitSnippetList(params CompilationUnitSnippet[] elements)
+ {
+ if (elements == null) elements = new CompilationUnitSnippet[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(CompilationUnitSnippet element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ CompilationUnitSnippet[] newElements = new CompilationUnitSnippet[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public CompilationUnitSnippetList/*!*/ Clone()
+ {
+ CompilationUnitSnippet[] elements = this.elements;
+ int n = this.count;
+ CompilationUnitSnippetList result = new CompilationUnitSnippetList(n);
+ result.count = n;
+ CompilationUnitSnippet[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public CompilationUnitSnippet this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly CompilationUnitSnippetList/*!*/ list;
+ public Enumerator(CompilationUnitSnippetList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public CompilationUnitSnippet Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if !NoWriter
+ public sealed class EventList
+ {
+ private Event[]/*!*/ elements;
+ private int count = 0;
+ public EventList()
+ {
+ this.elements = new Event[8];
+ //^ base();
+ }
+ public EventList(int n)
+ {
+ this.elements = new Event[n];
+ //^ base();
+ }
+ public void Add(Event element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Event[] newElements = new Event[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Event this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly EventList/*!*/ list;
+ public Enumerator(EventList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Event Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if !MinimalReader
+ public sealed class ErrorNodeList
+ {
+ private ErrorNode[]/*!*/ elements;
+ private int count = 0;
+ public ErrorNodeList()
+ {
+ this.elements = new ErrorNode[8];
+ //^ base();
+ }
+ public ErrorNodeList(int n)
+ {
+ this.elements = new ErrorNode[n];
+ //^ base();
+ }
+ public void Add(ErrorNode element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ ErrorNode[] newElements = new ErrorNode[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public ErrorNode this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ErrorNodeList/*!*/ list;
+ public Enumerator(ErrorNodeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public ErrorNode Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class ExpressionList
+ {
+ private Expression[]/*!*/ elements;
+ private int count = 0;
+ public ExpressionList()
+ {
+ this.elements = new Expression[8];
+ //^ base();
+ }
+ public ExpressionList(int n)
+ {
+ this.elements = new Expression[n];
+ //^ base();
+ }
+ public ExpressionList(params Expression[] elements)
+ {
+ if (elements == null) elements = new Expression[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Expression element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Expression[] newElements = new Expression[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ExpressionList/*!*/ Clone()
+ {
+ Expression[] elements = this.elements;
+ int n = this.count;
+ ExpressionList result = new ExpressionList(n);
+ result.count = n;
+ Expression[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public Expression this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ExpressionList/*!*/ list;
+ public Enumerator(ExpressionList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Expression Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class ExceptionHandlerList
+ {
+ private ExceptionHandler[]/*!*/ elements = new ExceptionHandler[4];
+ private int count = 0;
+ public ExceptionHandlerList()
+ {
+ //^ base();
+ }
+ public ExceptionHandlerList(int n)
+ {
+ this.elements = new ExceptionHandler[n];
+ //^ base();
+ }
+ public void Add(ExceptionHandler element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ ExceptionHandler[] newElements = new ExceptionHandler[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ExceptionHandlerList/*!*/ Clone()
+ {
+ ExceptionHandler[] elements = this.elements;
+ int n = this.count;
+ ExceptionHandlerList result = new ExceptionHandlerList(n);
+ result.count = n;
+ ExceptionHandler[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public ExceptionHandler this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ExceptionHandlerList/*!*/ list;
+ public Enumerator(ExceptionHandlerList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public ExceptionHandler Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class FaultHandlerList
+ {
+ private FaultHandler[]/*!*/ elements;
+ private int count = 0;
+ public FaultHandlerList()
+ {
+ this.elements = new FaultHandler[4];
+ //^ base();
+ }
+ public FaultHandlerList(int n)
+ {
+ this.elements = new FaultHandler[n];
+ //^ base();
+ }
+ public void Add(FaultHandler element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ FaultHandler[] newElements = new FaultHandler[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public FaultHandlerList/*!*/ Clone()
+ {
+ FaultHandler[] elements = this.elements;
+ int n = this.count;
+ FaultHandlerList result = new FaultHandlerList(n);
+ result.count = n;
+ FaultHandler[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public FaultHandler this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly FaultHandlerList/*!*/ list;
+ public Enumerator(FaultHandlerList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public FaultHandler Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if !NoWriter || !MinimalReader
+ public sealed class FieldList
+ {
+ private Field[]/*!*/ elements;
+ private int count = 0;
+ public FieldList()
+ {
+ this.elements = new Field[8];
+ //^ base();
+ }
+ public FieldList(int capacity)
+ {
+ this.elements = new Field[capacity];
+ //^ base();
+ }
+ public FieldList(params Field[] elements)
+ {
+ if (elements == null) elements = new Field[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Field element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Field[] newElements = new Field[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public FieldList/*!*/ Clone()
+ {
+ Field[] elements = this.elements;
+ int n = this.count;
+ FieldList result = new FieldList(n);
+ result.count = n;
+ Field[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Field this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly FieldList/*!*/ list;
+ public Enumerator(FieldList /*!*/list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Field Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if !MinimalReader
+ public sealed class FilterList
+ {
+ private Filter[]/*!*/ elements;
+ private int count = 0;
+ public FilterList()
+ {
+ this.elements = new Filter[4];
+ //^ base();
+ }
+ public FilterList(int capacity)
+ {
+ this.elements = new Filter[capacity];
+ //^ base();
+ }
+ public void Add(Filter element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Filter[] newElements = new Filter[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public FilterList/*!*/ Clone()
+ {
+ Filter[] elements = this.elements;
+ int n = this.count;
+ FilterList result = new FilterList(n);
+ result.count = n;
+ Filter[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Filter this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly FilterList/*!*/ list;
+ public Enumerator(FilterList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Filter Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class IdentifierList
+ {
+ private Identifier[]/*!*/ elements;
+ private int count = 0;
+ public IdentifierList()
+ {
+ this.elements = new Identifier[8];
+ //^ base();
+ }
+ public IdentifierList(int capacity)
+ {
+ this.elements = new Identifier[capacity];
+ //^ base();
+ }
+ public void Add(Identifier element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Identifier[] newElements = new Identifier[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public Identifier this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly IdentifierList/*!*/ list;
+ public Enumerator(IdentifierList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Identifier Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class InstructionList
+ {
+ private Instruction[]/*!*/ elements;
+ private int count = 0;
+ public InstructionList()
+ {
+ this.elements = new Instruction[32];
+ //^ base();
+ }
+ public InstructionList(int capacity)
+ {
+ this.elements = new Instruction[capacity];
+ //^ base();
+ }
+ public void Add(Instruction element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ Instruction[] newElements = new Instruction[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public Instruction this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly InstructionList/*!*/ list;
+ public Enumerator(InstructionList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Instruction Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class InterfaceList
+ {
+ private Interface[]/*!*/ elements;
+ private int count = 0;
+ public InterfaceList()
+ {
+ this.elements = new Interface[8];
+ //^ base();
+ }
+ public InterfaceList(int capacity)
+ {
+ this.elements = new Interface[capacity];
+ //^ base();
+ }
+ public InterfaceList(params Interface[] elements)
+ {
+ if (elements == null) elements = new Interface[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Interface element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Interface[] newElements = new Interface[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public InterfaceList/*!*/ Clone()
+ {
+ Interface[] elements = this.elements;
+ int n = this.count;
+ InterfaceList result = new InterfaceList(n);
+ result.count = n;
+ Interface[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public int SearchFor(Interface element)
+ {
+ Interface[] elements = this.elements;
+ for (int i = 0, n = this.count; i < n; i++)
+ if ((object)elements[i] == (object)element) return i;
+ return -1;
+ }
+ public Interface this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly InterfaceList/*!*/ list;
+ public Enumerator(InterfaceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Interface Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if ExtendedRuntime
+ public sealed class InvariantList{
+ private Invariant[]/*!*/ elements;
+ private int count = 0;
+ public InvariantList(){
+ this.elements = new Invariant[8];
+ //^ base();
+ }
+ public InvariantList(int n){
+ this.elements = new Invariant[n];
+ //^ base();
+ }
+ public InvariantList(params Invariant[] elements){
+ if (elements == null) elements = new Invariant[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Invariant element){
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n){
+ int m = n*2; if (m < 8) m = 8;
+ Invariant[] newElements = new Invariant[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public InvariantList/*!*/ Clone() {
+ Invariant[] elements = this.elements;
+ int n = this.count;
+ InvariantList result = new InvariantList(n);
+ result.count = n;
+ Invariant[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count{
+ get{return this.count;}
+ set{this.count = value;}
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length{
+ get{return this.count;}
+ set{this.count = value;}
+ }
+ public Invariant this[int index]{
+ get{
+ return this.elements[index];
+ }
+ set{
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator(){
+ return new Enumerator(this);
+ }
+ public struct Enumerator{
+ private int index;
+ private readonly InvariantList/*!*/ list;
+ public Enumerator(InvariantList/*!*/ list) {
+ this.index = -1;
+ this.list = list;
+ }
+ public Invariant Current{
+ get{
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext(){
+ return ++this.index < this.list.count;
+ }
+ public void Reset(){
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class Int32List
+ {
+ private Int32[]/*!*/ elements;
+ private int count = 0;
+ public Int32List()
+ {
+ this.elements = new Int32[8];
+ //^ base();
+ }
+ public Int32List(int capacity)
+ {
+ this.elements = new Int32[capacity];
+ //^ base();
+ }
+ public Int32List(params Int32[] elements)
+ {
+ if (elements == null) elements = new Int32[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Int32 element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Int32[] newElements = new Int32[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Int32 this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly Int32List/*!*/ list;
+ public Enumerator(Int32List/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Int32 Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class ISourceTextList
+ {
+ private ISourceText[]/*!*/ elements = new ISourceText[4];
+ private int count = 0;
+ public ISourceTextList()
+ {
+ this.elements = new ISourceText[4];
+ //^ base();
+ }
+ public ISourceTextList(int capacity)
+ {
+ this.elements = new ISourceText[capacity];
+ //^ base();
+ }
+ public ISourceTextList(params ISourceText[] elements)
+ {
+ if (elements == null) elements = new ISourceText[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(ISourceText element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ ISourceText[] newElements = new ISourceText[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public ISourceText this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ISourceTextList/*!*/ list;
+ public Enumerator(ISourceTextList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public ISourceText Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class LocalDeclarationList
+ {
+ private LocalDeclaration[]/*!*/ elements;
+ private int count = 0;
+ public LocalDeclarationList()
+ {
+ this.elements = new LocalDeclaration[8];
+ //^ base();
+ }
+ public LocalDeclarationList(int capacity)
+ {
+ this.elements = new LocalDeclaration[capacity];
+ //^ base();
+ }
+ public void Add(LocalDeclaration element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ LocalDeclaration[] newElements = new LocalDeclaration[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public LocalDeclarationList/*!*/ Clone()
+ {
+ LocalDeclaration[] elements = this.elements;
+ int n = this.count;
+ LocalDeclarationList result = new LocalDeclarationList(n);
+ result.count = n;
+ LocalDeclaration[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public LocalDeclaration this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly LocalDeclarationList/*!*/ list;
+ public Enumerator(LocalDeclarationList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public LocalDeclaration Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if ExtendedRuntime
+ public sealed class RequiresList{
+ private Requires[]/*!*/ elements;
+ private int count = 0;
+ public RequiresList(){
+ this.elements = new Requires[8];
+ //^ base();
+ }
+ public RequiresList(int capacity){
+ this.elements = new Requires[capacity];
+ //^ base();
+ }
+ public void Add(Requires element){
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n){
+ int m = n*2; if (m < 8) m = 8;
+ Requires[] newElements = new Requires[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public RequiresList/*!*/ Clone() {
+ Requires[] elements = this.elements;
+ int n = this.count;
+ RequiresList result = new RequiresList(n);
+ result.count = n;
+ Requires[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count{
+ get{return this.count;}
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length{
+ get{return this.count;}
+ }
+ public Requires this[int index]{
+ get{
+ return this.elements[index];
+ }
+ set{
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator(){
+ return new Enumerator(this);
+ }
+ public struct Enumerator{
+ private int index;
+ private readonly RequiresList/*!*/ list;
+ public Enumerator(RequiresList/*!*/ list) {
+ this.index = -1;
+ this.list = list;
+ }
+ public Requires Current{
+ get{
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext(){
+ return ++this.index < this.list.count;
+ }
+ public void Reset(){
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class EnsuresList{
+ private Ensures[]/*!*/ elements;
+ private int count = 0;
+ public EnsuresList(){
+ this.elements = new Ensures[8];
+ //^ base();
+ }
+ public EnsuresList(int capacity){
+ this.elements = new Ensures[capacity];
+ //^ base();
+ }
+ public void Add(Ensures element){
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n){
+ int m = n*2; if (m < 8) m = 8;
+ Ensures[] newElements = new Ensures[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public EnsuresList/*!*/ Clone() {
+ Ensures[] elements = this.elements;
+ int n = this.count;
+ EnsuresList result = new EnsuresList(n);
+ result.count = n;
+ Ensures[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count{
+ get{return this.count;}
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length{
+ get{return this.count;}
+ }
+ public Ensures this[int index]{
+ get{
+ return this.elements[index];
+ }
+ set{
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator(){
+ return new Enumerator(this);
+ }
+ public struct Enumerator{
+ private int index;
+ private readonly EnsuresList/*!*/ list;
+ public Enumerator(EnsuresList/*!*/ list) {
+ this.index = -1;
+ this.list = list;
+ }
+ public Ensures Current{
+ get{
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext(){
+ return ++this.index < this.list.count;
+ }
+ public void Reset(){
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class LocalList
+ {
+ private Local[]/*!*/ elements;
+ private int count = 0;
+ public LocalList()
+ {
+ this.elements = new Local[8];
+ //^ base();
+ }
+ public LocalList(int capacity)
+ {
+ this.elements = new Local[capacity];
+ //^ base();
+ }
+ public void Add(Local element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Local[] newElements = new Local[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Local this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly LocalList/*!*/ list;
+ public Enumerator(LocalList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Local Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class MemberList
+ {
+ private Member[]/*!*/ elements;
+ private int count = 0;
+ public MemberList()
+ {
+ this.elements = new Member[16];
+ //^ base();
+ }
+ public MemberList(int capacity)
+ {
+ this.elements = new Member[capacity];
+ //^ base();
+ }
+ public MemberList(params Member[] elements)
+ {
+ if (elements == null) elements = new Member[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Member element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 16) m = 16;
+ Member[] newElements = new Member[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+#if !MinimalReader
+ public bool Contains(Member element)
+ {
+ int n = this.count;
+ for (int i = 0; i < n; i++)
+ if (elements[i] == element)
+ return true;
+ return false;
+ }
+ public void AddList(MemberList memberList)
+ {
+ if (memberList == null || memberList.Count == 0) return;
+ int n = this.elements.Length;
+ int newN = this.count + memberList.count;
+ if (newN > n)
+ {
+ int m = newN; if (m < 16) m = 16;
+ Member[] newElements = new Member[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ for (int i = this.count, j = 0; i < newN; ++i, ++j)
+ {
+ this.elements[i] = memberList.elements[j];
+ }
+ this.count = newN;
+ }
+ /// <summary>
+ /// Removes member (by nulling slot) if present
+ /// </summary>
+ public void Remove(Member member)
+ {
+ int n = this.count;
+ for (int i = 0; i < n; i++)
+ {
+ if (this.elements[i] == member)
+ {
+ this.elements[i] = null;
+ return;
+ }
+ }
+ }
+#endif
+ public void RemoveAt(int index)
+ {
+ if (index >= this.count || index < 0) return;
+ int n = this.count;
+ for (int i = index + 1; i < n; ++i)
+ this.elements[i - 1] = this.elements[i];
+ this.count--;
+ }
+ public MemberList/*!*/ Clone()
+ {
+ Member[] elements = this.elements;
+ int n = this.count;
+ MemberList result = new MemberList(n);
+ result.count = n;
+ Member[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Member this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly MemberList/*!*/ list;
+ public Enumerator(MemberList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Member Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ public Member[]/*!*/ ToArray()
+ {
+ Member[] m = new Member[this.count];
+ Array.Copy(this.elements, m, this.count);
+ return m;
+ }
+ }
+#if !MinimalReader
+ public sealed class MemberBindingList
+ {
+ private MemberBinding[]/*!*/ elements;
+ private int count = 0;
+ public MemberBindingList()
+ {
+ this.elements = new MemberBinding[8];
+ //^ base();
+ }
+ public MemberBindingList(int capacity)
+ {
+ this.elements = new MemberBinding[capacity];
+ //^ base();
+ }
+ public void Add(MemberBinding element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ MemberBinding[] newElements = new MemberBinding[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public MemberBinding this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly MemberBindingList/*!*/ list;
+ public Enumerator(MemberBindingList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public MemberBinding Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class MethodList
+ {
+ private Method[]/*!*/ elements;
+ private int count = 0;
+ public MethodList()
+ {
+ this.elements = new Method[8];
+ //^ base();
+ }
+ public MethodList(int capacity)
+ {
+ this.elements = new Method[capacity];
+ //^ base();
+ }
+ public MethodList(params Method[] elements)
+ {
+ if (elements == null) elements = new Method[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Method element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Method[] newElements = new Method[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public MethodList/*!*/ Clone()
+ {
+ Method[] elements = this.elements;
+ int n = this.count;
+ MethodList result = new MethodList(n);
+ result.count = n;
+ Method[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Method this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly MethodList/*!*/ list;
+ public Enumerator(MethodList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Method Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !NoWriter
+ public sealed class ModuleList
+ {
+ private Module[]/*!*/ elements;
+ private int count = 0;
+ public ModuleList()
+ {
+ this.elements = new Module[4];
+ //^ base();
+ }
+ public ModuleList(int capacity)
+ {
+ this.elements = new Module[capacity];
+ //^ base();
+ }
+ public void Add(Module element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Module[] newElements = new Module[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Module this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ModuleList/*!*/ list;
+ public Enumerator(ModuleList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Module Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class ModuleReferenceList
+ {
+ private ModuleReference[]/*!*/ elements;
+ private int count = 0;
+ public ModuleReferenceList()
+ {
+ this.elements = new ModuleReference[4];
+ //^ base();
+ }
+ public ModuleReferenceList(int capacity)
+ {
+ this.elements = new ModuleReference[capacity];
+ //^ base();
+ }
+ public ModuleReferenceList(params ModuleReference[] elements)
+ {
+ if (elements == null) elements = new ModuleReference[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(ModuleReference element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ ModuleReference[] newElements = new ModuleReference[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ModuleReferenceList/*!*/ Clone()
+ {
+ ModuleReference[] elements = this.elements;
+ int n = this.count;
+ ModuleReferenceList result = new ModuleReferenceList(n);
+ result.count = n;
+ ModuleReference[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public ModuleReference this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ModuleReferenceList/*!*/ list;
+ public Enumerator(ModuleReferenceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public ModuleReference Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class NamespaceList
+ {
+ private Namespace[]/*!*/ elements;
+ private int count = 0;
+ public NamespaceList()
+ {
+ this.elements = new Namespace[4];
+ //^ base();
+ }
+ public NamespaceList(int capacity)
+ {
+ this.elements = new Namespace[capacity];
+ //^ base();
+ }
+ public void Add(Namespace element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Namespace[] newElements = new Namespace[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public NamespaceList/*!*/ Clone()
+ {
+ Namespace[] elements = this.elements;
+ int n = this.count;
+ NamespaceList result = new NamespaceList(n);
+ result.count = n;
+ Namespace[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Namespace this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly NamespaceList/*!*/ list;
+ public Enumerator(NamespaceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Namespace Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !FxCop
+ public
+#endif
+ sealed class NodeList
+ {
+ private Node[]/*!*/ elements;
+ private int count = 0;
+ public NodeList()
+ {
+ this.elements = new Node[4];
+ //^ base();
+ }
+ public NodeList(int capacity)
+ {
+ this.elements = new Node[capacity];
+ //^ base();
+ }
+ public NodeList(params Node[] elements)
+ {
+ if (elements == null) elements = new Node[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Node element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Node[] newElements = new Node[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public NodeList/*!*/ Clone()
+ {
+ Node[] elements = this.elements;
+ int n = this.count;
+ NodeList result = new NodeList(n);
+ result.count = n;
+ Node[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Node this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly NodeList/*!*/ list;
+ public Enumerator(NodeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Node Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class ParameterList
+ {
+ public readonly static ParameterList/*!*/ Empty = new ParameterList(0);
+
+ private Parameter[]/*!*/ elements;
+ private int count = 0;
+ public ParameterList()
+ {
+ this.elements = new Parameter[8];
+ //^ base();
+ }
+ public ParameterList(int capacity)
+ {
+ this.elements = new Parameter[capacity];
+ //^ base();
+ }
+ public ParameterList(params Parameter[] elements)
+ {
+ if (elements == null) elements = new Parameter[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Parameter element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Parameter[] newElements = new Parameter[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ParameterList/*!*/ Clone()
+ {
+ Parameter[] elements = this.elements;
+ int n = this.count;
+ ParameterList result = new ParameterList(n);
+ result.count = n;
+ Parameter[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public Parameter this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ParameterList/*!*/ list;
+ public Enumerator(ParameterList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Parameter Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ public override string ToString()
+ {
+ string res = "";
+ for (int i = 0; i < this.count; i++)
+ {
+ if (i > 0) res += ",";
+ Parameter par = elements[i];
+ if (par == null) continue;
+ res += par.ToString();
+ }
+ return res;
+ }
+ }
+#if !NoWriter
+ public sealed class PropertyList
+ {
+ private Property[]/*!*/ elements;
+ private int count = 0;
+ public PropertyList()
+ {
+ this.elements = new Property[8];
+ //^ base();
+ }
+ public PropertyList(int capacity)
+ {
+ this.elements = new Property[capacity];
+ //^ base();
+ }
+ public void Add(Property element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ Property[] newElements = new Property[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Property this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly PropertyList/*!*/ list;
+ public Enumerator(PropertyList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Property Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class ResourceList
+ {
+ private Resource[]/*!*/ elements;
+ private int count = 0;
+ public ResourceList()
+ {
+ this.elements = new Resource[4];
+ //^ base();
+ }
+ public ResourceList(int capacity)
+ {
+ this.elements = new Resource[capacity];
+ //^ base();
+ }
+ public void Add(Resource element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Resource[] newElements = new Resource[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ResourceList/*!*/ Clone()
+ {
+ Resource[] elements = this.elements;
+ int n = this.count;
+ ResourceList result = new ResourceList(n);
+ result.count = n;
+ Resource[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Resource this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ResourceList/*!*/ list;
+ public Enumerator(ResourceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Resource Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class ScopeList
+ {
+ private Scope[]/*!*/ elements;
+ private int count = 0;
+ public ScopeList()
+ {
+ this.elements = new Scope[32];
+ //^ base();
+ }
+ public ScopeList(int capacity)
+ {
+ this.elements = new Scope[capacity];
+ //^ base();
+ }
+ public ScopeList(params Scope[] elements)
+ {
+ if (elements == null) elements = new Scope[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Scope element)
+ {
+ Scope[] elements = this.elements;
+ int n = elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ Scope[] newElements = new Scope[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ScopeList/*!*/ Clone()
+ {
+ Scope[] elements = this.elements;
+ int n = this.count;
+ ScopeList result = new ScopeList(n);
+ result.count = n;
+ Scope[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public void Insert(Scope element, int index)
+ {
+ Scope[] elements = this.elements;
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (index >= i) throw new IndexOutOfRangeException();
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ Scope[] newElements = new Scope[m];
+ for (int j = 0; j < index; j++) newElements[j] = elements[j];
+ newElements[index] = element;
+ for (int j = index; j < n; j++) newElements[j + 1] = elements[j];
+ return;
+ }
+ for (int j = index; j < i; j++)
+ {
+ Scope t = elements[j];
+ elements[j] = element;
+ element = t;
+ }
+ elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public int SearchFor(Scope element)
+ {
+ Scope[] elements = this.elements;
+ for (int i = 0, n = this.count; i < n; i++)
+ if ((object)elements[i] == (object)element) return i;
+ return -1;
+ }
+ public Scope this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly ScopeList/*!*/ list;
+ public Enumerator(ScopeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Scope Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class SecurityAttributeList
+ {
+ private SecurityAttribute[]/*!*/ elements;
+ private int count = 0;
+ public SecurityAttributeList()
+ {
+ this.elements = new SecurityAttribute[8];
+ //^ base();
+ }
+ public SecurityAttributeList(int capacity)
+ {
+ this.elements = new SecurityAttribute[capacity];
+ //^ base();
+ }
+ public void Add(SecurityAttribute element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 8) m = 8;
+ SecurityAttribute[] newElements = new SecurityAttribute[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public SecurityAttributeList/*!*/ Clone()
+ {
+ SecurityAttribute[] elements = this.elements;
+ int n = this.count;
+ SecurityAttributeList result = new SecurityAttributeList(n);
+ result.count = n;
+ SecurityAttribute[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public SecurityAttribute this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly SecurityAttributeList/*!*/ list;
+ public Enumerator(SecurityAttributeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public SecurityAttribute Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class SourceChangeList
+ {
+ private SourceChange[]/*!*/ elements;
+ private int count = 0;
+ public SourceChangeList()
+ {
+ this.elements = new SourceChange[4];
+ //^ base();
+ }
+ public SourceChangeList(int capacity)
+ {
+ this.elements = new SourceChange[capacity];
+ //^ base();
+ }
+ public SourceChangeList(params SourceChange[] elements)
+ {
+ if (elements == null) elements = new SourceChange[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(SourceChange element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ SourceChange[] newElements = new SourceChange[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public SourceChangeList/*!*/ Clone()
+ {
+ SourceChange[] elements = this.elements;
+ int n = this.count;
+ SourceChangeList result = new SourceChangeList(n);
+ result.count = n;
+ SourceChange[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public SourceChange this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly SourceChangeList/*!*/ list;
+ public Enumerator(SourceChangeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public SourceChange Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class StatementList
+ {
+ private Statement[]/*!*/ elements;
+ private int count = 0;
+ public StatementList()
+ {
+ this.elements = new Statement[32];
+ //^ base();
+ }
+ public StatementList(int capacity)
+ {
+ this.elements = new Statement[capacity];
+ //^ base();
+ }
+ public StatementList(params Statement[] elements)
+ {
+ if (elements == null) elements = new Statement[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(Statement statement)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ Statement[] newElements = new Statement[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = statement;
+ }
+ public StatementList/*!*/ Clone()
+ {
+ Statement[] elements = this.elements;
+ int n = this.count;
+ StatementList result = new StatementList(n);
+ result.count = n;
+ Statement[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public Statement this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly StatementList/*!*/ list;
+ public Enumerator(StatementList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Statement Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !NoWriter
+ public sealed class StringList
+ {
+ private string[]/*!*/ elements = new string[4];
+ private int count = 0;
+ public StringList()
+ {
+ this.elements = new string[4];
+ //^ base();
+ }
+ public StringList(int capacity)
+ {
+ this.elements = new string[capacity];
+ //^ base();
+ }
+ public StringList(params string[] elements)
+ {
+ if (elements == null) elements = new string[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public StringList(System.Collections.Specialized.StringCollection/*!*/ stringCollection)
+ {
+ int n = this.count = stringCollection == null ? 0 : stringCollection.Count;
+ string[] elements = this.elements = new string[n];
+ //^ base();
+ if (n > 0) stringCollection.CopyTo(elements, 0);
+ }
+ public void Add(string element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ String[] newElements = new String[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public string this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly StringList/*!*/ list;
+ public Enumerator(StringList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public String Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+#if !MinimalReader
+ public sealed class SwitchCaseList
+ {
+ private SwitchCase[]/*!*/ elements = new SwitchCase[16];
+ private int count = 0;
+ public SwitchCaseList()
+ {
+ this.elements = new SwitchCase[16];
+ //^ base();
+ }
+ public SwitchCaseList(int capacity)
+ {
+ this.elements = new SwitchCase[capacity];
+ //^ base();
+ }
+ public void Add(SwitchCase element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 16) m = 16;
+ SwitchCase[] newElements = new SwitchCase[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public SwitchCaseList/*!*/ Clone()
+ {
+ SwitchCase[] elements = this.elements;
+ int n = this.count;
+ SwitchCaseList result = new SwitchCaseList(n);
+ result.count = n;
+ SwitchCase[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public SwitchCase this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly SwitchCaseList/*!*/ list;
+ public Enumerator(SwitchCaseList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public SwitchCase Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class TypeNodeList
+ {
+ private TypeNode[]/*!*/ elements;
+ private int count = 0;
+ public TypeNodeList()
+ {
+ this.elements = new TypeNode[32];
+ //^ base();
+ }
+ public TypeNodeList(int capacity)
+ {
+ this.elements = new TypeNode[capacity];
+ //^ base();
+ }
+ public TypeNodeList(params TypeNode[] elements)
+ {
+ if (elements == null) elements = new TypeNode[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(TypeNode element)
+ {
+ TypeNode[] elements = this.elements;
+ int n = elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ TypeNode[] newElements = new TypeNode[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public TypeNodeList/*!*/ Clone()
+ {
+ TypeNode[] elements = this.elements;
+ int n = this.count;
+ TypeNodeList result = new TypeNodeList(n);
+ result.count = n;
+ TypeNode[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public void Insert(TypeNode element, int index)
+ {
+ TypeNode[] elements = this.elements;
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (index >= i) throw new IndexOutOfRangeException();
+ if (i == n)
+ {
+ int m = n * 2; if (m < 32) m = 32;
+ TypeNode[] newElements = new TypeNode[m];
+ for (int j = 0; j < index; j++) newElements[j] = elements[j];
+ newElements[index] = element;
+ for (int j = index; j < n; j++) newElements[j + 1] = elements[j];
+ return;
+ }
+ for (int j = index; j < i; j++)
+ {
+ TypeNode t = elements[j];
+ elements[j] = element;
+ element = t;
+ }
+ elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public int SearchFor(TypeNode element)
+ {
+ TypeNode[] elements = this.elements;
+ for (int i = 0, n = this.count; i < n; i++)
+ if ((object)elements[i] == (object)element) return i;
+ return -1;
+ }
+ public TypeNode this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly TypeNodeList/*!*/ list;
+ public Enumerator(TypeNodeList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public TypeNode Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#if !MinimalReader
+ public sealed class TypeswitchCaseList
+ {
+ private TypeswitchCase[]/*!*/ elements = new TypeswitchCase[16];
+ private int count = 0;
+ public TypeswitchCaseList()
+ {
+ this.elements = new TypeswitchCase[16];
+ //^ base();
+ }
+ public TypeswitchCaseList(int capacity)
+ {
+ this.elements = new TypeswitchCase[capacity];
+ //^ base();
+ }
+ public void Add(TypeswitchCase element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 16) m = 16;
+ TypeswitchCase[] newElements = new TypeswitchCase[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public TypeswitchCaseList/*!*/ Clone()
+ {
+ TypeswitchCase[] elements = this.elements;
+ int n = this.count;
+ TypeswitchCaseList result = new TypeswitchCaseList(n);
+ result.count = n;
+ TypeswitchCase[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public TypeswitchCase this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly TypeswitchCaseList/*!*/ list;
+ public Enumerator(TypeswitchCaseList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public TypeswitchCase Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+ public sealed class UsedNamespaceList
+ {
+ private UsedNamespace[]/*!*/ elements;
+ private int count = 0;
+ public UsedNamespaceList()
+ {
+ this.elements = new UsedNamespace[4];
+ //^ base();
+ }
+ public UsedNamespaceList(int capacity)
+ {
+ this.elements = new UsedNamespace[capacity];
+ //^ base();
+ }
+ public void Add(UsedNamespace element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ UsedNamespace[] newElements = new UsedNamespace[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public UsedNamespaceList/*!*/ Clone()
+ {
+ UsedNamespace[] elements = this.elements;
+ int n = this.count;
+ UsedNamespaceList result = new UsedNamespaceList(n);
+ result.count = n;
+ UsedNamespace[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public UsedNamespace this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly UsedNamespaceList/*!*/ list;
+ public Enumerator(UsedNamespaceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public UsedNamespace Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+
+ public sealed class VariableDeclarationList
+ {
+ private VariableDeclaration[]/*!*/ elements;
+ private int count = 0;
+ public VariableDeclarationList()
+ {
+ this.elements = new VariableDeclaration[4];
+ //^ base();
+ }
+ public VariableDeclarationList(int capacity)
+ {
+ this.elements = new VariableDeclaration[capacity];
+ //^ base();
+ }
+ public void Add(VariableDeclaration element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ VariableDeclaration[] newElements = new VariableDeclaration[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public VariableDeclaration this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly VariableDeclarationList/*!*/ list;
+ public Enumerator(VariableDeclarationList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public VariableDeclaration Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+#endif
+ public sealed class Win32ResourceList
+ {
+ private Win32Resource[]/*!*/ elements;
+ private int count = 0;
+ public Win32ResourceList()
+ {
+ this.elements = new Win32Resource[4];
+ //^ base();
+ }
+ public Win32ResourceList(int capacity)
+ {
+ this.elements = new Win32Resource[capacity];
+ //^ base();
+ }
+ public void Add(Win32Resource element)
+ {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n)
+ {
+ int m = n * 2; if (m < 4) m = 4;
+ Win32Resource[] newElements = new Win32Resource[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public Win32ResourceList/*!*/ Clone()
+ {
+ Win32Resource[] elements = this.elements;
+ int n = this.count;
+ Win32ResourceList result = new Win32ResourceList(n);
+ result.count = n;
+ Win32Resource[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count
+ {
+ get { return this.count; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length
+ {
+ get { return this.count; }
+ }
+ public Win32Resource this[int index]
+ {
+ get
+ {
+ return this.elements[index];
+ }
+ set
+ {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(this);
+ }
+ public struct Enumerator
+ {
+ private int index;
+ private readonly Win32ResourceList/*!*/ list;
+ public Enumerator(Win32ResourceList/*!*/ list)
+ {
+ this.index = -1;
+ this.list = list;
+ }
+ public Win32Resource Current
+ {
+ get
+ {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext()
+ {
+ return ++this.index < this.list.count;
+ }
+ public void Reset()
+ {
+ this.index = -1;
+ }
+ }
+ }
+}
+#else
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.Cci
+{
+ public abstract class MetadataCollection<T> : IList<T>, IList{
+ private List<T> innerList;
+ internal MetadataCollection() : this(new List<T>()){}
+ internal MetadataCollection(int capacity) : this(new List<T>(capacity)){}
+ internal MetadataCollection(List<T> innerList){
+ this.innerList = innerList;
+ }
+ internal MetadataCollection(ICollection<T> collection) : this(collection == null ? 0 : collection.Count){
+ if (collection != null){
+ this.innerList.AddRange(collection);
+ }
+ }
+ public T this[int index]{
+ get { return this.innerList[index]; }
+ internal set { this.innerList[index] = value; }
+ }
+ public int IndexOf(T item){
+ return this.innerList.IndexOf(item);
+ }
+ public bool Contains(T item){
+ return this.innerList.Contains(item);
+ }
+ public void CopyTo(T[] array, int arrayIndex){
+ this.innerList.CopyTo(array, arrayIndex);
+ }
+ public int Count{
+ get { return this.innerList.Count; }
+ }
+ public bool IsReadOnly{
+ get { return true; }
+ }
+ public Enumerator GetEnumerator(){
+ return new Enumerator(this.innerList.GetEnumerator());
+ }
+ public struct Enumerator{
+ private List<T>.Enumerator enumerator;
+ public Enumerator(List<T>.Enumerator enumerator){
+ this.enumerator = enumerator;
+ }
+ public bool MoveNext(){
+ return this.enumerator.MoveNext();
+ }
+ public T Current{
+ get { return this.enumerator.Current; }
+ }
+ }
+ internal void Add(T item){
+ this.innerList.Add(item);
+ }
+ void ICollection<T>.Add(T item){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ void ICollection<T>.Clear(){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ bool ICollection<T>.Remove(T item){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ IEnumerator<T> IEnumerable<T>.GetEnumerator(){
+ return this.innerList.GetEnumerator();
+ }
+ void IList<T>.Insert(int index, T item){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ void IList<T>.RemoveAt(int index){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ T IList<T>.this[int index]{
+ get { return this[index]; }
+ set { throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly); }
+ }
+ void ICollection.CopyTo(Array array, int index){
+ ICollection list = this.innerList;
+ list.CopyTo(array, index);
+ }
+ bool ICollection.IsSynchronized{
+ get { return false; }
+ }
+ object ICollection.SyncRoot{
+ get {
+ ICollection list = this.innerList;
+ return list.SyncRoot;
+ }
+ }
+ IEnumerator IEnumerable.GetEnumerator(){
+ IEnumerable list = this.innerList;
+ return list.GetEnumerator();
+ }
+ int IList.Add(object value){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ bool IList.Contains(object value){
+ IList list = this.innerList;
+ return list.Contains(value);
+ }
+ int IList.IndexOf(object value){
+ IList list = this.innerList;
+ return list.IndexOf(value);
+ }
+ void IList.Insert(int index, object value){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ bool IList.IsFixedSize{
+ get { return true; }
+ }
+ void IList.Remove(object value){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ void IList.RemoveAt(int index){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ object IList.this[int index]{
+ get { return this[index]; }
+ set { throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly); }
+ }
+ void IList.Clear(){
+ throw new NotSupportedException(ExceptionStrings.CollectionIsReadOnly);
+ }
+ }
+ public sealed class AssemblyNodeCollection : MetadataCollection<AssemblyNode> {
+ internal AssemblyNodeCollection() : base(){}
+ internal AssemblyNodeCollection(int capacity) : base(capacity) { }
+ internal AssemblyNodeCollection(ICollection<AssemblyNode> collection) : base(collection) { }
+ internal AssemblyNodeCollection Clone() {
+ return new AssemblyNodeCollection(this);
+ }
+ }
+ public sealed class AssemblyReferenceCollection : MetadataCollection<AssemblyReference> {
+ internal AssemblyReferenceCollection() : base(){}
+ internal AssemblyReferenceCollection(int capacity) : base(capacity){}
+ }
+ public sealed class AttributeNodeCollection : MetadataCollection<AttributeNode> {
+ internal AttributeNodeCollection() : base(){}
+ internal AttributeNodeCollection(int capacity) : base(capacity){}
+ internal AttributeNodeCollection(ICollection<AttributeNode> collection) : base(collection) { }
+ internal AttributeNodeCollection Clone() {
+ return new AttributeNodeCollection(this);
+ }
+ }
+ public sealed class BlockCollection : MetadataCollection<Block> {
+ internal BlockCollection() : base(){}
+ internal BlockCollection(int capacity) : base(capacity) { }
+ internal BlockCollection(ICollection<Block> collection) : base(collection) { }
+ internal BlockCollection Clone() {
+ return new BlockCollection(this);
+ }
+ }
+ public sealed class CatchNodeCollection : MetadataCollection<CatchNode> {
+ internal CatchNodeCollection() : base(){}
+ internal CatchNodeCollection(int capacity) : base(capacity) { }
+ }
+ public sealed class ExpressionCollection : MetadataCollection<Expression> {
+ internal ExpressionCollection() : base(){}
+ internal ExpressionCollection(int capacity) : base(capacity){}
+ internal ExpressionCollection(ICollection<Expression> collection) : base(collection) { }
+ internal ExpressionCollection Clone() {
+ return new ExpressionCollection(this);
+ }
+ }
+ public sealed class InstructionCollection : MetadataCollection<Instruction> {
+ internal InstructionCollection() : base(){}
+ internal InstructionCollection(int capacity) : base(capacity){}
+ }
+ public sealed class InterfaceCollection : MetadataCollection<InterfaceNode> {
+ internal InterfaceCollection() : base(){}
+ internal InterfaceCollection(int capacity) : base(capacity){}
+ internal InterfaceCollection(params InterfaceNode[] range) : base(range) {}
+ internal InterfaceCollection(ICollection<InterfaceNode> collection) : base(collection) { }
+ internal InterfaceCollection Clone() {
+ return new InterfaceCollection(this);
+ }
+ }
+ public sealed class LocalCollection : MetadataCollection<Local> {
+ internal LocalCollection() : base(){}
+ internal LocalCollection(int capacity) : base(capacity){}
+ }
+ public sealed class MemberCollection : MetadataCollection<Member> {
+ internal MemberCollection() : base(){}
+ internal MemberCollection(int capacity) : base(capacity){}
+ internal MemberCollection(ICollection<Member> collection) : base(collection) { }
+ internal MemberCollection Clone() {
+ return new MemberCollection(this);
+ }
+ }
+ public sealed class MethodCollection : MetadataCollection<Method> {
+ internal MethodCollection() : base(){}
+ internal MethodCollection(int capacity) : base(capacity){}
+ internal MethodCollection(params Method[] range) : base(range) {}
+ }
+ public sealed class ModuleReferenceCollection : MetadataCollection<ModuleReference> {
+ internal ModuleReferenceCollection() : base(){}
+ internal ModuleReferenceCollection(int capacity) : base(capacity){}
+ }
+ public sealed class NamespaceCollection : MetadataCollection<Namespace> {
+ internal NamespaceCollection() : base(){}
+ internal NamespaceCollection(int capacity) : base(capacity){}
+ }
+ public sealed class NodeCollection : MetadataCollection<Node> {
+ internal NodeCollection() : base(){}
+ internal NodeCollection(int capacity) : base(capacity){}
+ internal NodeCollection(ICollection<Node> collection) : base(collection) { }
+ internal NodeCollection Clone() {
+ return new NodeCollection(this);
+ }
+ }
+ public sealed class ParameterCollection : MetadataCollection<Parameter> {
+ internal ParameterCollection() : base(){}
+ internal ParameterCollection(int capacity) : base(capacity){}
+ internal ParameterCollection(ICollection<Parameter> collection) : base(collection) { }
+ internal ParameterCollection Clone() {
+ return new ParameterCollection(this);
+ }
+ }
+ public sealed class ResourceCollection : MetadataCollection<Resource> {
+ internal ResourceCollection() : base(){}
+ internal ResourceCollection(int capacity) : base(capacity){}
+ }
+ public sealed class SecurityAttributeCollection : MetadataCollection<SecurityAttribute> {
+ internal SecurityAttributeCollection() : base(){}
+ internal SecurityAttributeCollection(int capacity) : base(capacity){}
+ internal SecurityAttributeCollection(ICollection<SecurityAttribute> collection) : base(collection) { }
+ internal SecurityAttributeCollection Clone() {
+ return new SecurityAttributeCollection(this);
+ }
+ }
+ public sealed class StackVariableCollection : MetadataCollection<Local> {
+ internal StackVariableCollection() : base(){}
+ internal StackVariableCollection(int capacity) : base(capacity) { }
+ }
+ public sealed class StatementCollection : MetadataCollection<Statement> {
+ internal StatementCollection() : base(){}
+ internal StatementCollection(int capacity) : base(capacity){}
+ internal StatementCollection(ICollection<Statement> collection) : base(collection) { }
+ internal StatementCollection Clone() {
+ return new StatementCollection(this);
+ }
+ }
+ public sealed class TypeNodeCollection : MetadataCollection<TypeNode> {
+ internal TypeNodeCollection() : base(){}
+ internal TypeNodeCollection(int capacity) : base(capacity){}
+ internal TypeNodeCollection(params TypeNode[] range) : base(range) {}
+ internal TypeNodeCollection(ICollection<TypeNode> collection) : base(collection) { }
+ internal TypeNodeCollection Clone() {
+ return new TypeNodeCollection(this);
+ }
+ }
+ public sealed class Win32ResourceCollection : MetadataCollection<Win32Resource> {
+ internal Win32ResourceCollection() : base(){}
+ internal Win32ResourceCollection(int capacity) : base(capacity) { }
+ }
+}
+#endif \ No newline at end of file
diff --git a/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs b/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
new file mode 100644
index 0000000..3eb86bb
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
@@ -0,0 +1,462 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+#if CCINamespace
+using Microsoft.Cci;
+#else
+using System.Compiler;
+#endif
+using System.Diagnostics;
+using System.IO;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci.Metadata{
+#else
+namespace System.Compiler.Metadata
+{
+#endif
+ unsafe internal sealed class MemoryCursor
+ {
+ private byte* buffer, pb;
+ readonly internal int Length;
+
+#if !ROTOR
+ internal MemoryCursor(MemoryMappedFile/*!*/ memoryMap)
+ : this(memoryMap.Buffer, memoryMap.Length)
+ {
+ }
+#endif
+ internal MemoryCursor(byte* buffer, int length, int position)
+ {
+ this.buffer = buffer;
+ this.pb = buffer + position;
+ this.Length = length;
+ }
+ internal MemoryCursor(byte* buffer, int length)
+ : this(buffer, length, 0)
+ {
+ }
+ internal MemoryCursor(MemoryCursor/*!*/ c)
+ {
+ this.buffer = c.buffer;
+ this.pb = c.pb;
+ this.Length = c.Length;
+ }
+
+ internal byte* GetBuffer()
+ {
+ return this.buffer;
+ }
+
+ internal int Position
+ {
+ get { return (int)(this.pb - this.buffer); }
+ set { this.pb = this.buffer + value; }
+ }
+ internal void Align(int size)
+ {
+ Debug.Assert(size == 2 || size == 4 || size == 8 || size == 16 || size == 32 || size == 64);
+ int remainder = Position & (size - 1);
+ if (remainder != 0)
+ pb += size - remainder;
+ }
+
+ //internal System.Char Char(int i){ return *(System.Char*)(this.pb+i*sizeof(System.Char)); }
+ //internal System.SByte SByte(int i){ return *(System.SByte*)(this.pb+i*sizeof(System.SByte)); }
+ internal System.Int16 Int16(int i) { return *(System.Int16*)(this.pb + i * sizeof(System.Int16)); }
+ internal System.Int32 Int32(int i) { return *(System.Int32*)(this.pb + i * sizeof(System.Int32)); }
+ //internal System.Int64 Int64(int i){ return *(System.Int64*)(this.pb+i*sizeof(System.Int64)); }
+ internal System.Byte Byte(int i) { return *(System.Byte*)(this.pb + i * sizeof(System.Byte)); }
+ internal System.UInt16 UInt16(int i) { return *(System.UInt16*)(this.pb + i * sizeof(System.UInt16)); }
+ //internal System.UInt32 UInt32(int i){ return *(System.UInt32*)(this.pb+i*sizeof(System.UInt32)); }
+ //internal System.UInt64 UInt64(int i){ return *(System.UInt64*)(this.pb+i*sizeof(System.UInt64)); }
+ //internal System.Boolean Boolean(int i){ return *(System.Boolean*)(this.pb+i*sizeof(System.Boolean)); }
+ //internal System.Single Single(int i){ return *(System.Single*)(this.pb+i*sizeof(System.Single)); }
+ //internal System.Double Double(int i){ return *(System.Double*)(this.pb+i*sizeof(System.Double)); }
+
+ //internal void SkipChar(int c){ this.pb += c*sizeof(System.Char); }
+ //internal void SkipSByte(int c){ this.pb += c*sizeof(System.SByte); }
+ internal void SkipInt16(int c) { this.pb += c * sizeof(System.Int16); }
+ internal void SkipInt32(int c) { this.pb += c * sizeof(System.Int32); }
+ //internal void SkipInt64(int c){ this.pb += c*sizeof(System.Int64); }
+ internal void SkipByte(int c) { this.pb += c * sizeof(System.Byte); }
+ internal void SkipUInt16(int c) { this.pb += c * sizeof(System.UInt16); }
+ //internal void SkipUInt32(int c){ this.pb += c*sizeof(System.UInt32); }
+ //internal void SkipUInt64(int c){ this.pb += c*sizeof(System.UInt64); }
+ //internal void SkipBoolean(int c){ this.pb += c*sizeof(System.Boolean); }
+ //internal void SkipSingle(int c){ this.pb += c*sizeof(System.Single); }
+ //internal void SkipDouble(int c){ this.pb += c*sizeof(System.Double); }
+
+ internal System.Char ReadChar() { byte* pb = this.pb; System.Char v = *(System.Char*)pb; this.pb = pb + sizeof(System.Char); return v; }
+ internal System.SByte ReadSByte() { byte* pb = this.pb; System.SByte v = *(System.SByte*)pb; this.pb = pb + sizeof(System.SByte); return v; }
+ internal System.Int16 ReadInt16() { byte* pb = this.pb; System.Int16 v = *(System.Int16*)pb; this.pb = pb + sizeof(System.Int16); return v; }
+ internal System.Int32 ReadInt32() { byte* pb = this.pb; System.Int32 v = *(System.Int32*)pb; this.pb = pb + sizeof(System.Int32); return v; }
+ internal System.Int64 ReadInt64() { byte* pb = this.pb; System.Int64 v = *(System.Int64*)pb; this.pb = pb + sizeof(System.Int64); return v; }
+ internal System.Byte ReadByte() { byte* pb = this.pb; System.Byte v = *(System.Byte*)pb; this.pb = pb + sizeof(System.Byte); return v; }
+ internal System.UInt16 ReadUInt16() { byte* pb = this.pb; System.UInt16 v = *(System.UInt16*)pb; this.pb = pb + sizeof(System.UInt16); return v; }
+ internal System.UInt32 ReadUInt32() { byte* pb = this.pb; System.UInt32 v = *(System.UInt32*)pb; this.pb = pb + sizeof(System.UInt32); return v; }
+ internal System.UInt64 ReadUInt64() { byte* pb = this.pb; System.UInt64 v = *(System.UInt64*)pb; this.pb = pb + sizeof(System.UInt64); return v; }
+ internal System.Boolean ReadBoolean() { byte* pb = this.pb; System.Boolean v = *(System.Boolean*)pb; this.pb = pb + sizeof(System.Boolean); return v; }
+ internal System.Single ReadSingle() { byte* pb = this.pb; System.Single v = *(System.Single*)pb; this.pb = pb + sizeof(System.Single); return v; }
+ internal System.Double ReadDouble() { byte* pb = this.pb; System.Double v = *(System.Double*)pb; this.pb = pb + sizeof(System.Double); return v; }
+
+ internal System.Int32 ReadReference(int refSize)
+ {
+ if (refSize == 2) return ReadUInt16();
+ return ReadInt32();
+ }
+
+ internal int ReadCompressedInt()
+ {
+ byte headerByte = ReadByte();
+ int result;
+ if ((headerByte & 0x80) == 0x00)
+ result = headerByte;
+ else if ((headerByte & 0x40) == 0x00)
+ result = ((headerByte & 0x3f) << 8) | ReadByte();
+ else if (headerByte == 0xFF)
+ result = -1;
+ else
+ result = ((headerByte & 0x3f) << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte();
+ return result;
+ }
+
+ internal byte[]/*!*/ ReadBytes(int c)
+ {
+ byte[] result = new byte[c];
+ byte* pb = this.pb;
+ for (int i = 0; i < c; i++)
+ result[i] = *pb++;
+ this.pb = pb;
+ return result;
+ }
+
+ internal unsafe Identifier/*!*/ ReadIdentifierFromSerString()
+ {
+ byte* pb = this.pb;
+ byte headerByte = *pb++;
+ uint length = 0;
+ if ((headerByte & 0x80) == 0x00)
+ length = headerByte;
+ else if ((headerByte & 0x40) == 0x00)
+ length = (uint)((headerByte & 0x3f) << 8) | *pb++;
+ else
+ length = (uint)((headerByte & 0x3f) << 24) | (uint)(*pb++ << 16) | (uint)(*pb++ << 8) | (*pb++);
+ this.pb = pb + length;
+ return Identifier.For(pb, length/*, this.KeepAlive*/);
+ }
+
+ internal string/*!*/ ReadUTF8(int bytesToRead)
+ {
+ char[] buffer = new char[bytesToRead];
+ byte* pb = this.pb;
+ this.pb += bytesToRead;
+ int j = 0;
+ while (bytesToRead > 0)
+ {
+ byte b = *pb++; bytesToRead--;
+ if ((b & 0x80) == 0 || bytesToRead == 0)
+ {
+ buffer[j++] = (char)b;
+ continue;
+ }
+ char ch;
+ byte b1 = *pb++; bytesToRead--;
+ if ((b & 0x20) == 0)
+ ch = (char)(((b & 0x1F) << 6) | (b1 & 0x3F));
+ else
+ {
+ if (bytesToRead == 0)
+ { //Dangling lead bytes, do not decompose
+ buffer[j++] = (char)((b << 8) | b1);
+ break;
+ }
+ byte b2 = *pb++; bytesToRead--;
+ uint ch32;
+ if ((b & 0x10) == 0)
+ ch32 = (uint)(((b & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F));
+ else
+ {
+ if (bytesToRead == 0)
+ { //Dangling lead bytes, do not decompose
+ buffer[j++] = (char)((b << 8) | b1);
+ buffer[j++] = (char)b2;
+ break;
+ }
+ byte b3 = *pb++; bytesToRead--;
+ ch32 = (uint)(((b & 0x07) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+ }
+ if ((ch32 & 0xFFFF0000) == 0)
+ ch = (char)ch32;
+ else
+ { //break up into UTF16 surrogate pair
+ buffer[j++] = (char)((ch32 >> 10) | 0xD800);
+ ch = (char)((ch32 & 0x3FF) | 0xDC00);
+ }
+ }
+ buffer[j++] = ch;
+ }
+ if (j > 0 && buffer[j - 1] == 0) j--;
+ return new String(buffer, 0, j);
+ }
+
+ internal string/*!*/ ReadUTF8()
+ {
+ byte* pb = this.pb;
+ StringBuilder sb = new StringBuilder();
+ byte b = 0;
+ for (; ; )
+ {
+ b = *pb++;
+ if (b == 0) break;
+ if ((b & 0x80) == 0)
+ {
+ sb.Append((char)b);
+ continue;
+ }
+ char ch;
+ byte b1 = *pb++;
+ if (b1 == 0)
+ { //Dangling lead byte, do not decompose
+ sb.Append((char)b);
+ break;
+ }
+ if ((b & 0x20) == 0)
+ {
+ ch = (char)(((b & 0x1F) << 6) | (b1 & 0x3F));
+ }
+ else
+ {
+ byte b2 = *pb++;
+ if (b2 == 0)
+ { //Dangling lead bytes, do not decompose
+ sb.Append((char)((b << 8) | b1));
+ break;
+ }
+ uint ch32;
+ if ((b & 0x10) == 0)
+ ch32 = (uint)(((b & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F));
+ else
+ {
+ byte b3 = *pb++;
+ if (b3 == 0)
+ { //Dangling lead bytes, do not decompose
+ sb.Append((char)((b << 8) | b1));
+ sb.Append((char)b2);
+ break;
+ }
+ ch32 = (uint)(((b & 0x07) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+ }
+ if ((ch32 & 0xFFFF0000) == 0)
+ ch = (char)ch32;
+ else
+ { //break up into UTF16 surrogate pair
+ sb.Append((char)((ch32 >> 10) | 0xD800));
+ ch = (char)((ch32 & 0x3FF) | 0xDC00);
+ }
+ }
+ sb.Append(ch);
+ }
+ this.pb = pb;
+ return sb.ToString();
+ }
+
+ internal string/*!*/ ReadUTF16(int charsToRead)
+ {
+ char* pc = (char*)this.pb;
+ char[] buffer = new char[charsToRead];
+ for (int i = 0; i < charsToRead; i++)
+ buffer[i] = *pc++;
+ this.pb = (byte*)pc;
+ return new String(buffer, 0, charsToRead);
+ }
+
+ internal string/*!*/ ReadUTF16()
+ {
+ string result = new string((char*)this.pb);
+ this.pb += (result.Length + 1) * 2;
+ return result;
+ }
+
+ internal string/*!*/ ReadASCII(int bytesToRead)
+ {
+ int c = bytesToRead;
+ if (bytesToRead == -1) c = 128; //buffer size
+ byte* pb = this.pb;
+ char[] buffer = new char[c];
+ int j = 0;
+ byte b = 0;
+ Restart:
+ while (j < c)
+ {
+ b = *pb++;
+ if (b == 0) break;
+ buffer[j++] = (char)b;
+ }
+ if (bytesToRead == -1)
+ {
+ if (b != 0)
+ {
+ char[] newBuffer = new char[c *= 2];
+ for (int copy = 0; copy < j; copy++)
+ newBuffer[copy] = buffer[copy];
+ buffer = newBuffer;
+ goto Restart;
+ }
+ this.pb = pb;
+ }
+ else
+ this.pb += bytesToRead;
+ return new String(buffer, 0, j);
+ }
+
+ internal string/*!*/ ReadASCII() { return ReadASCII(-1); }
+ }
+
+#if !ROTOR
+#if !FxCop
+ /// <summary>
+ /// Public only for use by the Framework. Do not use this class.
+ /// Well, if you really really must, use it only if you can tolerate keeping the file locked for at least as long as any Identifier
+ /// derived from the file stays alive.
+ /// </summary>
+ unsafe public sealed class MemoryMappedFile : IDisposable, ISourceTextBuffer
+ {
+#else
+ unsafe sealed class MemoryMappedFile : IDisposable{
+#endif
+ private byte* buffer;
+ private int length;
+
+ public MemoryMappedFile(string fileName)
+ {
+ this.OpenMap(fileName);
+ }
+ ~MemoryMappedFile()
+ {
+ this.CloseMap();
+ }
+ public void Dispose()
+ {
+ this.CloseMap();
+ GC.SuppressFinalize(this);
+ }
+
+ public byte* Buffer
+ {
+ get
+ {
+ Debug.Assert(this.buffer != null);
+ return this.buffer;
+ }
+ }
+ public int Length
+ {
+ get
+ {
+ Debug.Assert(this.buffer != null);
+ return this.length;
+ }
+ }
+#if !FxCop
+ string ISourceText.Substring(int start, int length)
+ {
+ Debug.Assert(false, "Can't use Substring on memory mapped files");
+ return null;
+ }
+ char ISourceText.this[int index]
+ {
+ get
+ {
+ Debug.Assert(false, "Can't access memory mapped files via an indexer, use Buffer");
+ return ' ';
+ }
+ }
+#endif
+ private void OpenMap(string filename)
+ {
+ IntPtr hmap;
+ int length;
+ using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ if (stream.Length > Int32.MaxValue)
+ throw new FileLoadException(ExceptionStrings.FileTooBig, filename);
+ length = unchecked((int)stream.Length);
+#if WHIDBEY && !OldWhidbey
+ hmap = CreateFileMapping(stream.SafeFileHandle.DangerousGetHandle(), IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null);
+#else
+ hmap = CreateFileMapping(stream.Handle, IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null);
+#endif
+ if (hmap == IntPtr.Zero)
+ {
+ int rc = Marshal.GetLastWin32Error();
+ throw new FileLoadException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CreateFileMappingReturnedErrorCode, rc.ToString()), filename);
+ }
+ }
+ this.buffer = (byte*)MapViewOfFile(hmap, FileMapAccess.FILE_MAP_READ, 0, 0, (IntPtr)length);
+ MemoryMappedFile.CloseHandle(hmap);
+ if (this.buffer == null)
+ {
+ int rc = Marshal.GetLastWin32Error();
+ throw new FileLoadException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.MapViewOfFileReturnedErrorCode, rc.ToString()), filename);
+ }
+ this.length = length;
+ }
+ private void CloseMap()
+ {
+ if (buffer != null)
+ {
+ UnmapViewOfFile(buffer);
+ buffer = null;
+ }
+ }
+#if !FxCop
+ void ISourceText.MakeCollectible()
+ {
+ }
+#endif
+
+ private enum PageAccess : int { PAGE_READONLY = 0x02 };
+ private enum FileMapAccess : int { FILE_MAP_READ = 0x0004 };
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern IntPtr CreateFileMapping(
+ IntPtr hFile, // handle to file
+ IntPtr lpAttributes, // security
+ PageAccess flProtect, // protection
+ int dwMaximumSizeHigh, // high-order DWORD of size
+ int dwMaximumSizeLow, // low-order DWORD of size
+ string lpName // object name
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern void* MapViewOfFile(
+ IntPtr hFileMappingObject, // handle to file-mapping object
+ FileMapAccess dwDesiredAccess, // access mode
+ int dwFileOffsetHigh, // high-order DWORD of offset
+ int dwFileOffsetLow, // low-order DWORD of offset
+ IntPtr dwNumberOfBytesToMap // number of bytes to map
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool UnmapViewOfFile(
+ void* lpBaseAddress // starting address
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool CloseHandle(
+ IntPtr hObject // handle to object
+ );
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/Metadata.cs b/tools/Sandcastle/Source/CCI/Metadata.cs
new file mode 100644
index 0000000..6272d8a
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Metadata.cs
@@ -0,0 +1,3849 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+#if FxCop
+using Win32ResourceList = Microsoft.Cci.Win32ResourceCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+#endif
+#if CCINamespace
+using Microsoft.Cci;
+#else
+using System.Compiler;
+#endif
+using System.Collections;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+//^ using Microsoft.Contracts;
+
+/* These classes help with parsing and producing PE files. They are best understood in conjunction with the ECMA 335 Specification
+ * (Common Language Infrastructure), particularly Partition II. Also see "Inside Microsoft .NET IL Assembler" by Serge Lidin. */
+
+#if CCINamespace
+namespace Microsoft.Cci.Metadata{
+#else
+namespace System.Compiler.Metadata
+{
+#endif
+ internal struct AssemblyRow
+ {
+ internal int HashAlgId;
+ internal int MajorVersion;
+ internal int MinorVersion;
+ internal int BuildNumber;
+ internal int RevisionNumber;
+ internal int Flags;
+ internal int PublicKey;
+ internal int Name;
+ internal int Culture;
+ }
+ internal struct AssemblyRefRow
+ {
+ internal int MajorVersion;
+ internal int MinorVersion;
+ internal int BuildNumber;
+ internal int RevisionNumber;
+ internal int Flags;
+ internal int PublicKeyOrToken;
+ internal int Name;
+ internal int Culture;
+ internal int HashValue;
+ internal AssemblyReference AssemblyReference;
+ }
+ internal struct ClassLayoutRow
+ {
+ internal int PackingSize;
+ internal int ClassSize;
+ internal int Parent;
+ }
+ internal struct ConstantRow
+ {
+ internal int Type;
+ internal int Parent;
+ internal int Value;
+ }
+ internal struct CustomAttributeRow
+ {
+ internal int Parent;
+ internal int Constructor;
+ internal int Value;
+ }
+ internal struct DeclSecurityRow
+ {
+ internal int Action;
+ internal int Parent;
+ internal int PermissionSet;
+ }
+ internal struct EventMapRow
+ {
+ internal int Parent;
+ internal int EventList;
+ }
+ internal struct EventPtrRow
+ {
+ internal int Event;
+ }
+ internal struct EventRow
+ {
+ internal int Flags;
+ internal int Name;
+ internal int EventType;
+ }
+ internal struct ExportedTypeRow
+ {
+ internal int Flags;
+ internal int TypeDefId;
+ internal int TypeName;
+ internal int TypeNamespace;
+ internal int Implementation;
+ }
+ internal struct FieldRow
+ {
+ internal int Flags;
+ internal int Name;
+ internal int Signature;
+ internal Field Field;
+ }
+ internal struct FieldLayoutRow
+ {
+ internal int Offset;
+ internal int Field;
+ }
+ internal struct FieldMarshalRow
+ {
+ internal int Parent;
+ internal int NativeType;
+ }
+ internal struct FieldPtrRow
+ {
+ internal int Field;
+ }
+ internal struct FieldRvaRow
+ {
+ internal int RVA;
+ internal int Field;
+ internal PESection TargetSection;
+ }
+ internal struct FileRow
+ {
+ internal int Flags;
+ internal int Name;
+ internal int HashValue;
+ }
+ internal struct GenericParamRow
+ {
+ internal int Number;
+ internal int Flags;
+ internal int Owner;
+ internal int Name;
+ internal Member GenericParameter;
+ }
+ internal struct GenericParamConstraintRow
+ {
+ internal int Param;
+ internal int Constraint;
+ }
+ internal struct ImplMapRow
+ {
+ internal int MappingFlags;
+ internal int MemberForwarded;
+ internal int ImportName;
+ internal int ImportScope;
+ }
+ internal struct InterfaceImplRow
+ {
+ internal int Class;
+ internal int Interface;
+ }
+ internal struct ManifestResourceRow
+ {
+ internal int Offset;
+ internal int Flags;
+ internal int Name;
+ internal int Implementation;
+ }
+ internal struct MemberRefRow
+ {
+ internal int Class;
+ internal int Name;
+ internal int Signature;
+ internal Member Member;
+ internal TypeNodeList VarargTypes;
+ }
+ internal struct MethodRow
+ {
+ internal int RVA;
+ internal int ImplFlags;
+ internal int Flags;
+ internal int Name;
+ internal int Signature;
+ internal int ParamList;
+ internal Method Method;
+ }
+ internal struct MethodImplRow
+ {
+ internal int Class;
+ internal int MethodBody;
+ internal int MethodDeclaration;
+ }
+ internal struct MethodPtrRow
+ {
+ internal int Method;
+ }
+ internal struct MethodSemanticsRow
+ {
+ internal int Semantics;
+ internal int Method;
+ internal int Association;
+ }
+ internal struct MethodSpecRow
+ {
+ internal int Method;
+ internal int Instantiation;
+ internal Method InstantiatedMethod;
+ }
+ internal struct ModuleRow
+ {
+ internal int Generation;
+ internal int Name;
+ internal int Mvid;
+ internal int EncId;
+ internal int EncBaseId;
+ }
+ internal struct ModuleRefRow
+ {
+ internal int Name;
+#if FxCop
+ internal ModuleNode Module;
+#else
+ internal Module Module;
+#endif
+ }
+ internal struct NestedClassRow
+ {
+ internal int NestedClass;
+ internal int EnclosingClass;
+ }
+ internal struct ParamRow
+ {
+ internal int Flags;
+ internal int Sequence;
+ internal int Name;
+ }
+ internal struct ParamPtrRow
+ {
+ internal int Param;
+ }
+ internal struct PropertyRow
+ {
+ internal int Flags;
+ internal int Name;
+ internal int Signature;
+ }
+ internal struct PropertyPtrRow
+ {
+ internal int Property;
+ }
+ internal struct PropertyMapRow
+ {
+ internal int Parent;
+ internal int PropertyList;
+ }
+ internal struct StandAloneSigRow
+ {
+ internal int Signature;
+ }
+ internal struct TypeDefRow
+ {
+ internal int Flags;
+ internal int Name;
+ internal int Namespace;
+ internal int Extends;
+ internal int FieldList;
+ internal int MethodList;
+ internal TypeNode Type;
+ internal Identifier NamespaceId;
+ internal int NamespaceKey;
+ internal int NameKey;
+ }
+ internal struct TypeRefRow
+ {
+ internal int ResolutionScope;
+ internal int Name;
+ internal int Namespace;
+ internal TypeNode Type;
+ }
+ internal struct TypeSpecRow
+ {
+ internal int Signature;
+ internal TypeNode Type;
+ }
+ [Serializable]
+ public sealed class InvalidMetadataException : System.Exception
+ {
+ public InvalidMetadataException() { }
+ public InvalidMetadataException(string message)
+ : base(message)
+ {
+ }
+ public InvalidMetadataException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ private InvalidMetadataException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+
+ internal class CLIHeader
+ {
+ internal int cb;
+ internal ushort majorRuntimeVersion;
+ internal ushort minorRuntimeVersion;
+ internal DirectoryEntry metaData;
+ internal int flags;
+ internal int entryPointToken;
+ internal DirectoryEntry resources;
+ internal DirectoryEntry strongNameSignature;
+ internal DirectoryEntry codeManagerTable;
+ internal DirectoryEntry vtableFixups;
+ internal DirectoryEntry exportAddressTableJumps;
+
+ internal CLIHeader()
+ {
+ this.cb = 72;
+ this.majorRuntimeVersion = 2;
+ this.minorRuntimeVersion = 5;
+ // initialization provided by runtime
+ //this.flags = 0;
+ //this.entryPointToken = 0;
+ }
+ }
+ internal struct DirectoryEntry
+ {
+ internal int virtualAddress;
+ internal int size;
+ }
+ internal class MetadataHeader
+ {
+ internal int signature;
+ internal ushort majorVersion;
+ internal ushort minorVersion;
+ internal int reserved;
+ internal string versionString;
+ internal int flags;
+ internal StreamHeader[] streamHeaders;
+ }
+ internal class NTHeader
+ {
+ internal int signature;
+ internal ushort machine;
+ internal ushort numberOfSections;
+ internal int timeDateStamp;
+ internal int pointerToSymbolTable;
+ internal int numberOfSymbols;
+ internal ushort sizeOfOptionalHeader;
+ internal ushort characteristics;
+ internal ushort magic;
+ internal byte majorLinkerVersion;
+ internal byte minorLinkerVersion;
+ internal int sizeOfCode;
+ internal int sizeOfInitializedData;
+ internal int sizeOfUninitializedData;
+ internal int addressOfEntryPoint;
+ internal int baseOfCode;
+ internal int baseOfData;
+ internal long imageBase;
+ internal int sectionAlignment;
+ internal int fileAlignment;
+ internal ushort majorOperatingSystemVersion;
+ internal ushort minorOperatingSystemVersion;
+ internal ushort majorImageVersion;
+ internal ushort minorImageVersion;
+ internal ushort majorSubsystemVersion;
+ internal ushort minorSubsystemVersion;
+ internal int win32VersionValue;
+ internal int sizeOfImage;
+ internal int sizeOfHeaders;
+ internal int checkSum;
+ internal ushort subsystem;
+ internal ushort dllCharacteristics;
+ internal long sizeOfStackReserve;
+ internal long sizeOfStackCommit;
+ internal long sizeOfHeapReserve;
+ internal long sizeOfHeapCommit;
+ internal int loaderFlags;
+ internal int numberOfDataDirectories;
+ internal DirectoryEntry exportTable;
+ internal DirectoryEntry importTable;
+ internal DirectoryEntry resourceTable;
+ internal DirectoryEntry exceptionTable;
+ internal DirectoryEntry certificateTable;
+ internal DirectoryEntry baseRelocationTable;
+ internal DirectoryEntry debugTable;
+ internal DirectoryEntry copyrightTable;
+ internal DirectoryEntry globalPointerTable;
+ internal DirectoryEntry threadLocalStorageTable;
+ internal DirectoryEntry loadConfigTable;
+ internal DirectoryEntry boundImportTable;
+ internal DirectoryEntry importAddressTable;
+ internal DirectoryEntry delayImportTable;
+ internal DirectoryEntry cliHeaderTable;
+ internal DirectoryEntry reserved;
+
+ internal NTHeader()
+ {
+ this.signature = 0x00004550; /* "PE\0\0" */
+ this.machine = 0x14c;
+ this.sizeOfOptionalHeader = 224;
+ this.characteristics = 0x0002 | 0x0004 | 0x008 | 0x0100;
+ this.magic = 0x10B;
+ this.majorLinkerVersion = 6;
+ this.baseOfCode = 0x2000;
+ this.imageBase = 0x400000; //TODO: make this settable
+ this.sectionAlignment = 8192;
+ this.fileAlignment = 512;
+ this.majorOperatingSystemVersion = 4;
+ this.majorSubsystemVersion = 4;
+ this.dllCharacteristics = 0x400;
+ this.sizeOfStackReserve = 1048576;
+ this.sizeOfStackCommit = 4096;
+ this.sizeOfHeapReserve = 1048576;
+ this.sizeOfHeapCommit = 4096;
+ this.numberOfDataDirectories = 16;
+
+ // initialization provided by runtime
+ //this.numberOfSections = 0;
+ //this.timeDateStamp = 0;
+ //this.pointerToSymbolTable = 0;
+ //this.numberOfSymbols = 0;
+ //this.minorLinkerVersion = 0;
+ //this.sizeOfCode = 0;
+ //this.sizeOfInitializedData = 0;
+ //this.sizeOfUninitializedData = 0;
+ //this.addressOfEntryPoint = 0;
+ //this.baseOfData = 0;
+ //this.minorOperatingSystemVersion = 0;
+ //this.majorImageVersion = 0;
+ //this.minorImageVersion = 0;
+ //this.minorSubsystemVersion = 0;
+ //this.win32VersionValue = 0;
+ //this.sizeOfImage = 0;
+ //this.sizeOfHeaders = 0;
+ //this.checkSum = 0;
+ //this.subsystem = 0;
+ //this.loaderFlags = 0x0;
+ }
+ }
+ internal struct SectionHeader
+ {
+ internal string name;
+ internal int virtualSize;
+ internal int virtualAddress;
+ internal int sizeOfRawData;
+ internal int pointerToRawData;
+ internal int pointerToRelocations;
+ internal int pointerToLinenumbers;
+ internal ushort numberOfRelocations;
+ internal ushort numberOfLinenumbers;
+ internal int characteristics;
+ }
+ internal class StreamHeader
+ {
+ internal int offset;
+ internal int size;
+ internal String name;
+ }
+ internal class TablesHeader
+ {
+ internal int reserved;
+ internal byte majorVersion;
+ internal byte minorVersion;
+ internal byte heapSizes;
+ internal byte rowId;
+ internal long maskValid;
+ internal long maskSorted;
+ internal int[] countArray;
+ }
+ internal enum TableIndices
+ {
+ Module = 0x00,
+ TypeRef = 0x01,
+ TypeDef = 0x02,
+ FieldPtr = 0x03,
+ Field = 0x04,
+ MethodPtr = 0x05,
+ Method = 0x06,
+ ParamPtr = 0x07,
+ Param = 0x08,
+ InterfaceImpl = 0x09,
+ MemberRef = 0x0A,
+ Constant = 0x0B,
+ CustomAttribute = 0x0C,
+ FieldMarshal = 0x0D,
+ DeclSecurity = 0x0E,
+ ClassLayout = 0x0F,
+ FieldLayout = 0x10,
+ StandAloneSig = 0x11,
+ EventMap = 0x12,
+ EventPtr = 0x13,
+ Event = 0x14,
+ PropertyMap = 0x15,
+ PropertyPtr = 0x16,
+ Property = 0x17,
+ MethodSemantics = 0x18,
+ MethodImpl = 0x19,
+ ModuleRef = 0x1A,
+ TypeSpec = 0x1B,
+ ImplMap = 0x1C,
+ FieldRva = 0x1D,
+ EncLog = 0x1E,
+ EncMap = 0x1F,
+ Assembly = 0x20,
+ AssemblyProcessor = 0x21,
+ AssemblyOS = 0x22,
+ AssemblyRef = 0x23,
+ AssemblyRefProcessor = 0x24,
+ AssemblyRefOS = 0x25,
+ File = 0x26,
+ ExportedType = 0x27,
+ ManifestResource = 0x28,
+ NestedClass = 0x29,
+ GenericParam = 0x2a,
+ MethodSpec = 0x2b,
+ GenericParamConstraint = 0x2c,
+ Count
+ }
+ internal enum ElementType
+ {
+ End = 0x00,
+ Void = 0x01,
+ Boolean = 0x02,
+ Char = 0x03,
+ Int8 = 0x04,
+ UInt8 = 0x05,
+ Int16 = 0x06,
+ UInt16 = 0x07,
+ Int32 = 0x08,
+ UInt32 = 0x09,
+ Int64 = 0x0a,
+ UInt64 = 0x0b,
+ Single = 0x0c,
+ Double = 0x0d,
+ String = 0x0e,
+ Pointer = 0x0f,
+ Reference = 0x10,
+ ValueType = 0x11,
+ Class = 0x12,
+ TypeParameter = 0x13,
+ Array = 0x14,
+ GenericTypeInstance = 0x15,
+ DynamicallyTypedReference = 0x16,
+ IntPtr = 0x18,
+ UIntPtr = 0x19,
+ FunctionPointer = 0x1b,
+ Object = 0x1c,
+ SzArray = 0x1d,
+ MethodParameter = 0x1e,
+ RequiredModifier = 0x1f,
+ OptionalModifier = 0x20,
+ Internal = 0x21,
+ Modifier = 0x40,
+ Sentinel = 0x41,
+ Pinned = 0x45,
+ Type = 0x50,
+ BoxedEnum = 0x51,
+ Enum = 0x55
+ }
+
+ unsafe internal class MetadataReader : IDisposable
+ {
+#if !ROTOR
+ private MemoryMappedFile memmap;
+#endif
+ private MemoryCursor/*!*/ cursor;
+ internal int entryPointToken;
+ internal int fileAlignment;
+ internal ModuleKindFlags moduleKind;
+ internal PEKindFlags peKind;
+ internal bool TrackDebugData;
+ private int mdOffset;
+ private int resourcesOffset;
+ private int win32ResourcesOffset;
+ private SectionHeader[] sectionHeaders;
+ //^ [SpecPublic]
+ private StreamHeader identifierStringHeap;
+ //^ [SpecPublic]
+ private StreamHeader generalStringHeap;
+ private StreamHeader blobHeap;
+ //^ [SpecPublic]
+ private StreamHeader guidHeap;
+ private StreamHeader tables;
+ internal TablesHeader tablesHeader;
+ internal string targetRuntimeVersion;
+ internal int linkerMajorVersion;
+ internal int linkerMinorVersion;
+ internal int metadataFormatMajorVersion;
+ internal int metadataFormatMinorVersion;
+ private int blobRefSize;
+ private int constantParentRefSize;
+ private int customAttributeParentRefSize;
+ private int customAttributeConstructorRefSize;
+ private int declSecurityParentRefSize;
+ private int fieldMarshalParentRefSize;
+ private int guidRefSize;
+ private int hasSemanticRefSize;
+ private int implementationRefSize;
+ private int methodDefOrRefSize;
+ private int memberRefParentSize;
+ private int memberForwardedRefSize;
+ private int typeDefOrRefOrSpecSize;
+ private int typeDefOrMethodDefSize;
+ private int resolutionScopeRefSize;
+ private int stringRefSize;
+ private int[] tableSize;
+ private int[] tableRefSize;
+ private int[] tableOffset;
+ internal byte[] HashValue;
+
+#if !ROTOR
+ internal MetadataReader(string path)
+ {
+ MemoryMappedFile memmap = this.memmap = new MemoryMappedFile(path);
+ try
+ {
+ this.cursor = new MemoryCursor(memmap);
+ //^ base();
+ ReadHeader();
+ }
+ catch
+ {
+ this.Dispose();
+ throw;
+ }
+ }
+#endif
+
+ internal MetadataReader(byte* buffer, int length)
+ {
+ this.cursor = new MemoryCursor(buffer, length);
+ //^ base();
+ ReadHeader();
+ }
+
+ public void Dispose()
+ {
+#if !ROTOR
+ if (this.memmap != null) this.memmap.Dispose();
+ this.memmap = null;
+#endif
+ //this.cursor = null;
+ this.sectionHeaders = null;
+ this.identifierStringHeap = null;
+ this.generalStringHeap = null;
+ this.blobHeap = null;
+ this.guidHeap = null;
+ this.tables = null;
+ this.tablesHeader = null;
+ this.targetRuntimeVersion = null;
+ this.tableSize = null;
+ this.tableRefSize = null;
+ this.tableOffset = null;
+ this.HashValue = null;
+ }
+
+ private AssemblyRow[] assemblyTable;
+ private AssemblyRefRow[] assemblyRefTable;
+ private ClassLayoutRow[] classLayoutTable;
+ private ConstantRow[] constantTable;
+ private CustomAttributeRow[] customAttributeTable;
+ private DeclSecurityRow[] declSecurityTable;
+ private EventMapRow[] eventMapTable;
+ private EventPtrRow[] eventPtrTable;
+ private EventRow[] eventTable;
+ private ExportedTypeRow[] exportedTypeTable;
+ private FieldRow[] fieldTable;
+ private FieldLayoutRow[] fieldLayoutTable;
+ private FieldMarshalRow[] fieldMarshalTable;
+ private FieldPtrRow[] fieldPtrTable;
+ private FieldRvaRow[] fieldRvaTable;
+ private FileRow[] fileTable;
+ private GenericParamRow[] genericParamTable;
+ private GenericParamConstraintRow[] genericParamConstraintTable;
+ private ImplMapRow[] implMapTable;
+ private InterfaceImplRow[] interfaceImplTable;
+ private ManifestResourceRow[] manifestResourceTable;
+ private MemberRefRow[] memberRefTable;
+ private MethodRow[] methodTable;
+ private MethodPtrRow[] methodPtrTable;
+ private MethodImplRow[] methodImplTable;
+ private MethodSemanticsRow[] methodSemanticsTable;
+ private MethodSpecRow[] methodSpecTable;
+ private ModuleRow[] moduleTable;
+ private ModuleRefRow[] moduleRefTable;
+ private NestedClassRow[] nestedClassTable;
+ private ParamRow[] paramTable;
+ private ParamPtrRow[] paramPtrTable;
+ private PropertyRow[] propertyTable;
+ private PropertyMapRow[] propertyMapTable;
+ private PropertyPtrRow[] propertyPtrTable;
+ private StandAloneSigRow[] standAloneSigTable;
+ private TypeDefRow[] typeDefTable;
+ private TypeRefRow[] typeRefTable;
+ private TypeSpecRow[] typeSpecTable;
+
+ internal AssemblyRow[]/*!*/ AssemblyTable
+ {
+ get { if (this.assemblyTable == null) this.ReadAssemblyTable(); return this.assemblyTable; }
+ }
+ internal AssemblyRefRow[]/*!*/ AssemblyRefTable
+ {
+ get { if (this.assemblyRefTable == null) this.ReadAssemblyRefTable(); return this.assemblyRefTable; }
+ }
+ internal ClassLayoutRow[]/*!*/ ClassLayoutTable
+ {
+ get { if (this.classLayoutTable == null) this.ReadClassLayoutTable(); return this.classLayoutTable; }
+ }
+ internal ConstantRow[]/*!*/ ConstantTable
+ {
+ get { if (this.constantTable == null) this.ReadConstantTable(); return this.constantTable; }
+ }
+ internal CustomAttributeRow[]/*!*/ CustomAttributeTable
+ {
+ get { if (this.customAttributeTable == null) this.ReadCustomAttributeTable(); return this.customAttributeTable; }
+ }
+ internal DeclSecurityRow[]/*!*/ DeclSecurityTable
+ {
+ get { if (this.declSecurityTable == null) this.ReadDeclSecurityTable(); return this.declSecurityTable; }
+ }
+ internal EventMapRow[]/*!*/ EventMapTable
+ {
+ get { if (this.eventMapTable == null) this.ReadEventMapTable(); return this.eventMapTable; }
+ }
+ internal EventPtrRow[]/*!*/ EventPtrTable
+ {
+ get { if (this.eventPtrTable == null) this.ReadEventPtrTable(); return this.eventPtrTable; }
+ }
+ internal EventRow[]/*!*/ EventTable
+ {
+ get { if (this.eventTable == null) this.ReadEventTable(); return this.eventTable; }
+ }
+ internal ExportedTypeRow[]/*!*/ ExportedTypeTable
+ {
+ get { if (this.exportedTypeTable == null) this.ReadExportedTypeTable(); return this.exportedTypeTable; }
+ }
+ internal FieldRow[]/*!*/ FieldTable
+ {
+ get { if (this.fieldTable == null) this.ReadFieldTable(); return this.fieldTable; }
+ }
+ internal FieldLayoutRow[]/*!*/ FieldLayoutTable
+ {
+ get { if (this.fieldLayoutTable == null) this.ReadFieldLayoutTable(); return this.fieldLayoutTable; }
+ }
+ internal FieldMarshalRow[]/*!*/ FieldMarshalTable
+ {
+ get { if (this.fieldMarshalTable == null) this.ReadFieldMarshalTable(); return this.fieldMarshalTable; }
+ }
+ internal FieldPtrRow[]/*!*/ FieldPtrTable
+ {
+ get { if (this.fieldPtrTable == null) this.ReadFieldPtrTable(); return this.fieldPtrTable; }
+ }
+ internal FieldRvaRow[]/*!*/ FieldRvaTable
+ {
+ get { if (this.fieldRvaTable == null) this.ReadFieldRvaTable(); return this.fieldRvaTable; }
+ }
+ internal FileRow[]/*!*/ FileTable
+ {
+ get { if (this.fileTable == null) this.ReadFileTable(); return this.fileTable; }
+ }
+ internal GenericParamRow[]/*!*/ GenericParamTable
+ {
+ get { if (this.genericParamTable == null) this.ReadGenericParamTable(); return this.genericParamTable; }
+ }
+ internal GenericParamConstraintRow[]/*!*/ GenericParamConstraintTable
+ {
+ get { if (this.genericParamConstraintTable == null) this.ReadGenericParamConstraintTable(); return this.genericParamConstraintTable; }
+ }
+ internal ImplMapRow[]/*!*/ ImplMapTable
+ {
+ get { if (this.implMapTable == null) this.ReadImplMapTable(); return this.implMapTable; }
+ }
+ internal InterfaceImplRow[]/*!*/ InterfaceImplTable
+ {
+ get { if (this.interfaceImplTable == null) this.ReadInterfaceImplTable(); return this.interfaceImplTable; }
+ }
+ internal ManifestResourceRow[]/*!*/ ManifestResourceTable
+ {
+ get { if (this.manifestResourceTable == null) this.ReadManifestResourceTable(); return this.manifestResourceTable; }
+ }
+ internal MemberRefRow[]/*!*/ MemberRefTable
+ {
+ get { if (this.memberRefTable == null) this.ReadMemberRefTable(); return this.memberRefTable; }
+ }
+ internal MethodRow[]/*!*/ MethodTable
+ {
+ get { if (this.methodTable == null) this.ReadMethodTable(); return this.methodTable; }
+ }
+ internal MethodImplRow[]/*!*/ MethodImplTable
+ {
+ get { if (this.methodImplTable == null) this.ReadMethodImplTable(); return this.methodImplTable; }
+ }
+ internal MethodPtrRow[]/*!*/ MethodPtrTable
+ {
+ get { if (this.methodPtrTable == null) this.ReadMethodPtrTable(); return this.methodPtrTable; }
+ }
+ internal MethodSemanticsRow[]/*!*/ MethodSemanticsTable
+ {
+ get { if (this.methodSemanticsTable == null) this.ReadMethodSemanticsTable(); return this.methodSemanticsTable; }
+ }
+ internal MethodSpecRow[]/*!*/ MethodSpecTable
+ {
+ get { if (this.methodSpecTable == null) this.ReadMethodSpecTable(); return this.methodSpecTable; }
+ }
+ internal ModuleRow[]/*!*/ ModuleTable
+ {
+ get { if (this.moduleTable == null) this.ReadModuleTable(); return this.moduleTable; }
+ }
+ internal ModuleRefRow[]/*!*/ ModuleRefTable
+ {
+ get { if (this.moduleRefTable == null) this.ReadModuleRefTable(); return this.moduleRefTable; }
+ }
+ internal NestedClassRow[]/*!*/ NestedClassTable
+ {
+ get { if (this.nestedClassTable == null) this.ReadNestedClassTable(); return this.nestedClassTable; }
+ }
+ internal ParamRow[]/*!*/ ParamTable
+ {
+ get { if (this.paramTable == null) this.ReadParamTable(); return this.paramTable; }
+ }
+ internal ParamPtrRow[]/*!*/ ParamPtrTable
+ {
+ get { if (this.paramPtrTable == null) this.ReadParamPtrTable(); return this.paramPtrTable; }
+ }
+ internal PropertyRow[]/*!*/ PropertyTable
+ {
+ get { if (this.propertyTable == null) this.ReadPropertyTable(); return this.propertyTable; }
+ }
+ internal PropertyMapRow[]/*!*/ PropertyMapTable
+ {
+ get { if (this.propertyMapTable == null) this.ReadPropertyMapTable(); return this.propertyMapTable; }
+ }
+ internal PropertyPtrRow[]/*!*/ PropertyPtrTable
+ {
+ get { if (this.propertyPtrTable == null) this.ReadPropertyPtrTable(); return this.propertyPtrTable; }
+ }
+ internal StandAloneSigRow[]/*!*/ StandAloneSigTable
+ {
+ get { if (this.standAloneSigTable == null) this.ReadStandAloneSigTable(); return this.standAloneSigTable; }
+ }
+ internal TypeDefRow[]/*!*/ TypeDefTable
+ {
+ get { if (this.typeDefTable == null) this.ReadTypeDefTable(); return this.typeDefTable; }
+ }
+ internal TypeRefRow[]/*!*/ TypeRefTable
+ {
+ get { if (this.typeRefTable == null) this.ReadTypeRefTable(); return this.typeRefTable; }
+ }
+ internal TypeSpecRow[]/*!*/ TypeSpecTable
+ {
+ get { if (this.typeSpecTable == null) this.ReadTypeSpecTable(); return this.typeSpecTable; }
+ }
+
+ internal void SetCurrentPosition(int pos)
+ {
+ this.cursor.Position = pos;
+ }
+ internal void AlignTo32BitBoundary()
+ {
+ this.cursor.Align(4);
+ }
+ internal void Skip(int bytes)
+ {
+ this.cursor.SkipByte(bytes);
+ }
+ internal byte[]/*!*/ GetBlob(int blobIndex)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = PositionOfBlob(blobIndex);
+ return c.ReadBytes(c.ReadCompressedInt());
+ }
+ internal MemoryCursor/*!*/ GetBlobCursor(int blobIndex)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = PositionOfBlob(blobIndex);
+ c.ReadCompressedInt();
+ return new MemoryCursor(c);
+ }
+ internal MemoryCursor/*!*/ GetBlobCursor(int blobIndex, out int blobLength)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = PositionOfBlob(blobIndex);
+ blobLength = c.ReadCompressedInt();
+ return new MemoryCursor(c);
+ }
+ internal System.Guid GetGuid(int guidIndex)
+ //^ requires this.guidHeap != null;
+ {
+ int guidOffset = guidIndex * 16;
+ if (guidOffset < 16 || this.guidHeap.size < guidOffset)
+ throw new System.ArgumentOutOfRangeException("guidIndex", ExceptionStrings.BadGuidHeapIndex);
+ MemoryCursor c = this.cursor;
+ c.Position = this.mdOffset + this.guidHeap.offset + guidOffset - 16;
+ return new System.Guid(c.ReadBytes(16));
+ }
+ internal Identifier/*!*/ GetIdentifier(int stringHeapIndex)
+ //^ requires this.identifierStringHeap != null;
+ {
+ int position = this.mdOffset + this.identifierStringHeap.offset + stringHeapIndex;
+ MemoryCursor c = this.cursor;
+ return Identifier.For(c.GetBuffer(), position/*, c.KeepAlive*/);
+ }
+ internal byte GetMethodBodyHeaderByte(int RVA)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = this.RvaToOffset(RVA);
+ return c.ReadByte();
+ }
+ internal MemoryCursor/*!*/ GetNewCursor()
+ {
+ return new MemoryCursor(this.cursor);
+ }
+ internal MemoryCursor/*!*/ GetNewCursor(int RVA, out PESection targetSection)
+ {
+ MemoryCursor c = new MemoryCursor(this.cursor);
+ c.Position = this.RvaToOffset(RVA, out targetSection);
+ return c;
+ }
+ internal byte GetByte()
+ {
+ MemoryCursor c = this.cursor;
+ return c.ReadByte();
+ }
+ internal int GetCurrentPosition()
+ {
+ return this.cursor.Position;
+ }
+ internal int GetInt32()
+ {
+ MemoryCursor c = this.cursor;
+ return c.ReadInt32();
+ }
+ internal short GetInt16()
+ {
+ MemoryCursor c = this.cursor;
+ return c.ReadInt16();
+ }
+ internal ushort GetUInt16()
+ {
+ MemoryCursor c = this.cursor;
+ return c.ReadUInt16();
+ }
+ internal int GetSignatureLength(int blobIndex)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = this.PositionOfBlob(blobIndex);
+ return c.ReadCompressedInt();
+ }
+ internal string/*!*/ GetString(int stringHeapIndex)
+ //^ requires this.identifierStringHeap != null;
+ {
+ if (stringHeapIndex < 0 || this.identifierStringHeap.size <= stringHeapIndex)
+ throw new System.ArgumentOutOfRangeException("stringHeapIndex", ExceptionStrings.BadStringHeapIndex);
+ MemoryCursor c = this.cursor;
+ c.Position = this.mdOffset + this.identifierStringHeap.offset + stringHeapIndex;
+ return c.ReadUTF8();
+ }
+ internal string/*!*/ GetUserString(int stringHeapIndex)
+ //^ requires this.generalStringHeap != null;
+ {
+ if (stringHeapIndex < 0 || this.generalStringHeap.size <= stringHeapIndex)
+ throw new System.ArgumentOutOfRangeException("stringHeapIndex", ExceptionStrings.BadUserStringHeapIndex);
+ MemoryCursor c = this.cursor;
+ c.Position = this.mdOffset + this.generalStringHeap.offset + stringHeapIndex;
+ int strLength = c.ReadCompressedInt();
+ return c.ReadUTF16(strLength / 2);
+ }
+ internal string/*!*/ GetBlobString(int blobIndex)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = this.PositionOfBlob(blobIndex);
+ int blobLength = c.ReadCompressedInt();
+ return c.ReadUTF16(blobLength / 2);
+ }
+ internal object GetValueFromBlob(int type, int blobIndex)
+ {
+ MemoryCursor c = this.cursor;
+ c.Position = this.PositionOfBlob(blobIndex);
+ int blobLength = c.ReadCompressedInt();
+ switch ((ElementType)type)
+ {
+ case ElementType.Boolean: return c.ReadBoolean();
+ case ElementType.Char: return (char)c.ReadUInt16();
+ case ElementType.Double: return c.ReadDouble();
+ case ElementType.Single: return c.ReadSingle();
+ case ElementType.Int16: return c.ReadInt16();
+ case ElementType.Int32: return c.ReadInt32();
+ case ElementType.Int64: return c.ReadInt64();
+ case ElementType.Int8: return c.ReadSByte();
+ case ElementType.UInt16: return c.ReadUInt16();
+ case ElementType.UInt32: return c.ReadUInt32();
+ case ElementType.UInt64: return c.ReadUInt64();
+ case ElementType.UInt8: return c.ReadByte();
+ case ElementType.Class: return null;
+ case ElementType.String: return c.ReadUTF16(blobLength / 2);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.UnknownConstantType);
+ }
+ internal byte[] GetResourceData(int resourceOffset)
+ {
+ this.cursor.Position = this.resourcesOffset + resourceOffset;
+ int length = this.cursor.ReadInt32();
+ return this.cursor.ReadBytes(length);
+ }
+ private int PositionOfBlob(int blobIndex)
+ //^ requires this.blobHeap != null;
+ {
+ if (blobIndex < 0 || this.blobHeap.size <= blobIndex)
+ throw new System.ArgumentOutOfRangeException("blobIndex", ExceptionStrings.BadBlobHeapIndex);
+ return this.mdOffset + this.blobHeap.offset + blobIndex;
+ }
+ private void ReadHeader()
+ { //TODO: break up this method
+ MemoryCursor c = this.cursor;
+ c.Position = 0;
+
+ ReadDOSHeader(c);
+ NTHeader ntHeader = ReadNTHeader(c);
+ this.linkerMajorVersion = ntHeader.majorLinkerVersion;
+ this.linkerMinorVersion = ntHeader.minorLinkerVersion;
+ this.fileAlignment = ntHeader.fileAlignment;
+ if ((ntHeader.characteristics & 0x2000) != 0)
+ this.moduleKind = ModuleKindFlags.DynamicallyLinkedLibrary;
+ else
+ this.moduleKind = ntHeader.subsystem == 0x3 ? ModuleKindFlags.ConsoleApplication : ModuleKindFlags.WindowsApplication;
+
+ int sectionCount = ntHeader.numberOfSections;
+ SectionHeader[] sectionHeaders = this.sectionHeaders = new SectionHeader[sectionCount];
+ int resourceSectionIndex = -1;
+ for (int i = 0; i < sectionCount; i++)
+ {
+ sectionHeaders[i] = ReadSectionHeader(c);
+ if (sectionHeaders[i].name == ".rsrc") resourceSectionIndex = i;
+ }
+ if (resourceSectionIndex >= 0)
+ this.win32ResourcesOffset = sectionHeaders[resourceSectionIndex].pointerToRawData;
+ else
+ this.win32ResourcesOffset = -1;
+
+ DirectoryEntry de = ntHeader.cliHeaderTable;
+ int cliHeaderOffset = this.RvaToOffset(de.virtualAddress);
+ c.Position = cliHeaderOffset;
+
+ CLIHeader cliHeader = ReadCLIHeader(c);
+ this.entryPointToken = cliHeader.entryPointToken;
+ if ((cliHeader.flags & 1) != 0)
+ this.peKind = PEKindFlags.ILonly;
+ if ((cliHeader.flags & 0x10) != 0)
+ this.entryPointToken = 0; //Native entry point. Ignore.
+ switch (ntHeader.machine)
+ {
+ case 0x0200:
+ this.peKind |= PEKindFlags.Requires64bits;
+ break;
+ case 0x8664:
+ this.peKind |= PEKindFlags.Requires64bits | PEKindFlags.AMD;
+ break;
+ default:
+ if (ntHeader.magic == 0x20B) //Optional header magic for PE32+
+ this.peKind |= PEKindFlags.Requires64bits;
+ else if ((cliHeader.flags & 2) != 0)
+ this.peKind |= PEKindFlags.Requires32bits;
+ break;
+ }
+ this.TrackDebugData = (cliHeader.flags & 0x10000) != 0;
+ if (cliHeader.resources.size > 0)
+ this.resourcesOffset = this.RvaToOffset(cliHeader.resources.virtualAddress);
+
+ int snSize = cliHeader.strongNameSignature.size;
+ if (snSize > 0)
+ {
+ long hashOffset = this.RvaToOffset(cliHeader.strongNameSignature.virtualAddress);
+ c.Position = (int)hashOffset;
+ this.HashValue = c.ReadBytes(snSize);
+ bool zeroHash = true;
+ for (int i = 0; i < snSize; i++) if (this.HashValue[i] != 0) zeroHash = false;
+ if (zeroHash) this.HashValue = null; //partially signed assembly
+ }
+
+ long mdOffset = this.mdOffset = this.RvaToOffset(cliHeader.metaData.virtualAddress);
+ c.Position = (int)mdOffset;
+ MetadataHeader mdHeader = ReadMetadataHeader(c);
+ this.targetRuntimeVersion = mdHeader.versionString;
+
+ foreach (StreamHeader sheader in mdHeader.streamHeaders)
+ {
+ //^ assume sheader != null;
+ switch (sheader.name)
+ {
+ case "#Strings": this.identifierStringHeap = sheader; continue;
+ case "#US": this.generalStringHeap = sheader; continue;
+ case "#Blob": this.blobHeap = sheader; continue;
+ case "#GUID": this.guidHeap = sheader; continue;
+ case "#~": this.tables = sheader; continue;
+ case "#-": this.tables = sheader; continue;
+ default: continue;
+ }
+ }
+ if (this.tables == null) throw new InvalidMetadataException(ExceptionStrings.NoMetadataStream);
+ c.Position = (int)(mdOffset + this.tables.offset);
+ TablesHeader tablesHeader = this.tablesHeader = ReadTablesHeader(c);
+ this.metadataFormatMajorVersion = tablesHeader.majorVersion;
+ this.metadataFormatMinorVersion = tablesHeader.minorVersion;
+
+ int[] tableSize = this.tableSize = new int[(int)TableIndices.Count];
+ int[] tableRefSize = this.tableRefSize = new int[(int)TableIndices.Count];
+ long valid = tablesHeader.maskValid;
+ int[] countArray = tablesHeader.countArray;
+ //^ assume countArray != null;
+ for (int i = 0, j = 0; i < (int)TableIndices.Count; i++)
+ {
+ if (valid % 2 == 1)
+ {
+ int m = tableSize[i] = countArray[j++];
+ tableRefSize[i] = m < 0x10000 ? 2 : 4;
+ }
+ else
+ tableRefSize[i] = 2;
+ valid /= 2;
+ }
+ int blobRefSize = this.blobRefSize = ((tablesHeader.heapSizes & 0x04) == 0 ? 2 : 4);
+ int constantParentRefSize = this.constantParentRefSize =
+ tableSize[(int)TableIndices.Param] < 0x4000 &&
+ tableSize[(int)TableIndices.Field] < 0x4000 &&
+ tableSize[(int)TableIndices.Property] < 0x4000 ? 2 : 4;
+ int customAttributeParentRefSize = 0;
+ if (this.metadataFormatMajorVersion > 1 || this.metadataFormatMinorVersion > 0)
+ {
+ customAttributeParentRefSize = this.customAttributeParentRefSize =
+ tableSize[(int)TableIndices.Method] < 0x0800 &&
+ tableSize[(int)TableIndices.Field] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeDef] < 0x0800 &&
+ tableSize[(int)TableIndices.Param] < 0x0800 &&
+ tableSize[(int)TableIndices.InterfaceImpl] < 0x0800 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x0800 &&
+ tableSize[(int)TableIndices.Module] < 0x0800 &&
+ tableSize[(int)TableIndices.DeclSecurity] < 0x0800 &&
+ tableSize[(int)TableIndices.Property] < 0x0800 &&
+ tableSize[(int)TableIndices.Event] < 0x0800 &&
+ tableSize[(int)TableIndices.StandAloneSig] < 0x0800 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x0800 &&
+ tableSize[(int)TableIndices.Assembly] < 0x0800 &&
+ tableSize[(int)TableIndices.File] < 0x0800 &&
+ tableSize[(int)TableIndices.ExportedType] < 0x0800 &&
+ tableSize[(int)TableIndices.ManifestResource] < 0x0800 &&
+ tableSize[(int)TableIndices.GenericParam] < 0x0800 &&
+ tableSize[(int)TableIndices.MethodSpec] < 0x0800 &&
+ tableSize[(int)TableIndices.GenericParamConstraint] < 0x0800 ? 2 : 4;
+ }
+ else
+ {
+ customAttributeParentRefSize = this.customAttributeParentRefSize =
+ tableSize[(int)TableIndices.Method] < 0x0800 &&
+ tableSize[(int)TableIndices.Field] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeDef] < 0x0800 &&
+ tableSize[(int)TableIndices.Param] < 0x0800 &&
+ tableSize[(int)TableIndices.InterfaceImpl] < 0x0800 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x0800 &&
+ tableSize[(int)TableIndices.Module] < 0x0800 &&
+ tableSize[(int)TableIndices.DeclSecurity] < 0x0800 &&
+ tableSize[(int)TableIndices.Property] < 0x0800 &&
+ tableSize[(int)TableIndices.Event] < 0x0800 &&
+ tableSize[(int)TableIndices.StandAloneSig] < 0x0800 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x0800 &&
+ tableSize[(int)TableIndices.Assembly] < 0x0800 &&
+ tableSize[(int)TableIndices.File] < 0x0800 &&
+ tableSize[(int)TableIndices.ExportedType] < 0x0800 &&
+ tableSize[(int)TableIndices.ManifestResource] < 0x0800 ? 2 : 4;
+ }
+ int customAttributeConstructorRefSize = this.customAttributeConstructorRefSize =
+ tableSize[(int)TableIndices.Method] < 0x2000 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x2000 ? 2 : 4;
+ int declSecurityParentRefSize = this.declSecurityParentRefSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x4000 &&
+ tableSize[(int)TableIndices.Method] < 0x4000 &&
+ tableSize[(int)TableIndices.Assembly] < 0x4000 ? 2 : 4;
+ int fieldMarshalParentRefSize = this.fieldMarshalParentRefSize =
+ tableSize[(int)TableIndices.Field] < 0x8000 &&
+ tableSize[(int)TableIndices.Param] < 0x8000 ? 2 : 4;
+ int guidRefSize = this.guidRefSize = ((tablesHeader.heapSizes & 0x02) == 0 ? 2 : 4);
+ int hasSemanticRefSize = this.hasSemanticRefSize =
+ tableSize[(int)TableIndices.Event] < 0x8000 &&
+ tableSize[(int)TableIndices.Property] < 0x8000 ? 2 : 4;
+ int implementationRefSize = this.implementationRefSize =
+ tableSize[(int)TableIndices.File] < 0x4000 &&
+ tableSize[(int)TableIndices.AssemblyRef] < 0x4000 &&
+ tableSize[(int)TableIndices.ExportedType] < 0x4000 ? 2 : 4;
+ int methodDefOrRefSize = this.methodDefOrRefSize =
+ tableSize[(int)TableIndices.Method] < 0x8000 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x8000 ? 2 : 4;
+ int memberRefParentSize = this.memberRefParentSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x2000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x2000 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x2000 &&
+ tableSize[(int)TableIndices.Method] < 0x2000 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x2000 ? 2 : 4;
+ int memberForwardedRefSize = this.memberForwardedRefSize =
+ tableSize[(int)TableIndices.Field] < 0x8000 &&
+ tableSize[(int)TableIndices.Method] < 0x8000 ? 2 : 4;
+ int typeDefOrMethodDefSize = this.typeDefOrMethodDefSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x8000 &&
+ tableSize[(int)TableIndices.Method] < 0x8000 ? 2 : 4;
+ int typeDefOrRefOrSpecSize = this.typeDefOrRefOrSpecSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x4000 ? 2 : 4;
+ int resolutionScopeRefSize = this.resolutionScopeRefSize =
+ tableSize[(int)TableIndices.Module] < 0x4000 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x4000 &&
+ tableSize[(int)TableIndices.AssemblyRef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x4000 ? 2 : 4;
+ int stringRefSize = this.stringRefSize = ((tablesHeader.heapSizes & 0x01) == 0 ? 2 : 4);
+
+ int[] tableOffset = this.tableOffset = new int[(int)TableIndices.Count];
+ int offset = this.mdOffset + this.tables.offset + 24 + countArray.Length * 4;
+ for (int i = 0; i < (int)TableIndices.Count; i++)
+ {
+ int m = tableSize[i];
+ if (m == 0) continue;
+ tableOffset[i] = offset;
+ switch ((TableIndices)i)
+ {
+ case TableIndices.Module: offset += m * (2 + stringRefSize + 3 * guidRefSize); break;
+ case TableIndices.TypeRef: offset += m * (resolutionScopeRefSize + 2 * stringRefSize); break;
+ case TableIndices.TypeDef: offset += m * (4 + 2 * stringRefSize + typeDefOrRefOrSpecSize + tableRefSize[(int)TableIndices.Field] + tableRefSize[(int)TableIndices.Method]); break;
+ case TableIndices.FieldPtr: offset += m * (tableRefSize[(int)TableIndices.Field]); break;
+ case TableIndices.Field: offset += m * (2 + stringRefSize + blobRefSize); break;
+ case TableIndices.MethodPtr: offset += m * (tableRefSize[(int)TableIndices.Method]); break;
+ case TableIndices.Method: offset += m * (8 + stringRefSize + blobRefSize + tableRefSize[(int)TableIndices.Param]); break;
+ case TableIndices.ParamPtr: offset += m * (tableRefSize[(int)TableIndices.Param]); break;
+ case TableIndices.Param: offset += m * (4 + stringRefSize); break;
+ case TableIndices.InterfaceImpl: offset += m * (tableRefSize[(int)TableIndices.TypeDef] + typeDefOrRefOrSpecSize); break;
+ case TableIndices.MemberRef: offset += m * (memberRefParentSize + stringRefSize + blobRefSize); break;
+ case TableIndices.Constant: offset += m * (2 + constantParentRefSize + blobRefSize); break;
+ case TableIndices.CustomAttribute: offset += m * (customAttributeParentRefSize + customAttributeConstructorRefSize + blobRefSize); break;
+ case TableIndices.FieldMarshal: offset += m * (fieldMarshalParentRefSize + blobRefSize); break;
+ case TableIndices.DeclSecurity: offset += m * (2 + declSecurityParentRefSize + blobRefSize); break;
+ case TableIndices.ClassLayout: offset += m * (6 + tableRefSize[(int)TableIndices.TypeDef]); break;
+ case TableIndices.FieldLayout: offset += m * (4 + tableRefSize[(int)TableIndices.Field]); break;
+ case TableIndices.StandAloneSig: offset += m * (blobRefSize); break;
+ case TableIndices.EventMap: offset += m * (tableRefSize[(int)TableIndices.TypeDef] + tableRefSize[(int)TableIndices.Event]); break;
+ case TableIndices.EventPtr: offset += m * (tableRefSize[(int)TableIndices.Event]); break;
+ case TableIndices.Event: offset += m * (2 + stringRefSize + typeDefOrRefOrSpecSize); break;
+ case TableIndices.PropertyMap: offset += m * (tableRefSize[(int)TableIndices.TypeDef] + tableRefSize[(int)TableIndices.Property]); break;
+ case TableIndices.PropertyPtr: offset += m * (tableRefSize[(int)TableIndices.Property]); break;
+ case TableIndices.Property: offset += m * (2 + stringRefSize + blobRefSize); break;
+ case TableIndices.MethodSemantics: offset += m * (2 + tableRefSize[(int)TableIndices.Method] + hasSemanticRefSize); break;
+ case TableIndices.MethodImpl: offset += m * (tableRefSize[(int)TableIndices.TypeDef] + 2 * methodDefOrRefSize); break;
+ case TableIndices.ModuleRef: offset += m * (stringRefSize); break;
+ case TableIndices.TypeSpec: offset += m * (blobRefSize); break;
+ case TableIndices.ImplMap: offset += m * (2 + memberForwardedRefSize + stringRefSize + tableRefSize[(int)TableIndices.ModuleRef]); break;
+ case TableIndices.FieldRva: offset += m * (4 + tableRefSize[(int)TableIndices.Field]); break;
+ case TableIndices.EncLog: throw new InvalidMetadataException(ExceptionStrings.ENCLogTableEncountered);
+ case TableIndices.EncMap: throw new InvalidMetadataException(ExceptionStrings.ENCMapTableEncountered);
+ case TableIndices.Assembly: offset += m * (16 + blobRefSize + 2 * stringRefSize); break;
+ case TableIndices.AssemblyProcessor: offset += m * (4); break;
+ case TableIndices.AssemblyOS: offset += m * (12); break;
+ case TableIndices.AssemblyRef: offset += m * (12 + 2 * blobRefSize + 2 * stringRefSize); break;
+ case TableIndices.AssemblyRefProcessor: offset += m * (4 + tableRefSize[(int)TableIndices.AssemblyRef]); break;
+ case TableIndices.AssemblyRefOS: offset += m * (12 + tableRefSize[(int)TableIndices.AssemblyRef]); break;
+ case TableIndices.File: offset += m * (4 + stringRefSize + blobRefSize); break;
+ case TableIndices.ExportedType: offset += m * (8 + 2 * stringRefSize + implementationRefSize); break;
+ case TableIndices.ManifestResource: offset += m * (8 + stringRefSize + implementationRefSize); break;
+ case TableIndices.NestedClass: offset += m * (2 * tableRefSize[(int)TableIndices.TypeDef]); break;
+ case TableIndices.GenericParam:
+ if (this.metadataFormatMajorVersion == 1 && this.metadataFormatMinorVersion == 0)
+ offset += m * (6 + typeDefOrMethodDefSize + stringRefSize + typeDefOrRefOrSpecSize);
+ else if (this.metadataFormatMajorVersion == 1 && this.metadataFormatMinorVersion == 1)
+ offset += m * (4 + typeDefOrMethodDefSize + stringRefSize + typeDefOrRefOrSpecSize);
+ else
+ offset += m * (4 + typeDefOrMethodDefSize + stringRefSize);
+ break;
+ case TableIndices.MethodSpec: offset += m * (methodDefOrRefSize + blobRefSize); break;
+ case TableIndices.GenericParamConstraint: offset += m * (tableRefSize[(int)TableIndices.GenericParam] + typeDefOrRefOrSpecSize); break;
+ default: throw new InvalidMetadataException(ExceptionStrings.UnsupportedTableEncountered);
+ }
+ }
+ }
+ internal Win32ResourceList ReadWin32Resources()
+ {
+ Win32ResourceList rs = new Win32ResourceList();
+ int startPos = this.win32ResourcesOffset;
+ if (startPos < 0) return rs;
+ MemoryCursor c = this.cursor;
+ c.Position = startPos;
+ int sizeOfTypeDirectory = ReadWin32ResourceDirectoryHeader(c);
+ for (int i = 0; i < sizeOfTypeDirectory; i++)
+ {
+ string TypeName = null;
+ int TypeID = c.ReadInt32();
+ if (TypeID < 0)
+ {
+ MemoryCursor nac = new MemoryCursor(c);
+ nac.Position = startPos + (TypeID & 0x7FFFFFFF);
+ int strLength = nac.ReadUInt16();
+ TypeName = nac.ReadUTF16(strLength);
+ }
+ int offset = c.ReadInt32();
+ if (offset >= 0)
+ rs.Add(this.ReadWin32ResourceDataEntry(c, startPos + offset, TypeName, TypeID, null, 0, 0));
+ else
+ {
+ MemoryCursor nc = new MemoryCursor(c);
+ nc.Position = startPos + (offset & 0x7FFFFFFF);
+ int sizeOfNameDirectory = ReadWin32ResourceDirectoryHeader(nc);
+ for (int j = 0; j < sizeOfNameDirectory; j++)
+ {
+ string Name = null;
+ int ID = nc.ReadInt32();
+ if (ID < 0)
+ {
+ MemoryCursor nac = new MemoryCursor(c);
+ int strLength = nac.ReadUInt16();
+ Name = nac.ReadUTF16(strLength);
+ }
+ offset = nc.ReadInt32();
+ if (offset >= 0)
+ rs.Add(this.ReadWin32ResourceDataEntry(c, startPos + offset, TypeName, TypeID, Name, ID, 0));
+ else
+ {
+ MemoryCursor lc = new MemoryCursor(c);
+ lc.Position = startPos + (offset & 0x7FFFFFFF);
+ int sizeOfLanguageDirectory = ReadWin32ResourceDirectoryHeader(lc);
+ for (int k = 0; k < sizeOfLanguageDirectory; k++)
+ {
+ int LanguageID = lc.ReadInt32();
+ offset = lc.ReadInt32();
+ rs.Add(this.ReadWin32ResourceDataEntry(c, startPos + offset, TypeName, TypeID, Name, ID, LanguageID));
+ }
+ }
+ }
+ }
+ }
+ return rs;
+ }
+ private static int ReadWin32ResourceDirectoryHeader(MemoryCursor/*!*/ c)
+ {
+ c.ReadInt32(); //Characteristics
+ c.ReadInt32(); //TimeDate stamp
+ c.ReadInt32(); //Version
+ int numberOfNamedEntries = c.ReadUInt16();
+ int numberOfIdEntries = c.ReadUInt16();
+ return numberOfNamedEntries + numberOfIdEntries;
+ }
+ private Win32Resource ReadWin32ResourceDataEntry(MemoryCursor/*!*/ c, int position,
+ string TypeName, int TypeID, string Name, int ID, int LanguageID)
+ {
+ Win32Resource rsrc = new Win32Resource();
+ rsrc.TypeName = TypeName;
+ rsrc.TypeId = TypeID;
+ rsrc.Name = Name;
+ rsrc.Id = ID;
+ rsrc.LanguageId = LanguageID;
+ c = new MemoryCursor(c);
+ c.Position = position;
+ int dataRVA = c.ReadInt32();
+ int dataSize = c.ReadInt32();
+ rsrc.CodePage = c.ReadInt32();
+ c.Position = this.RvaToOffset(dataRVA);
+ rsrc.Data = c.ReadBytes(dataSize);
+ return rsrc;
+ }
+ private void ReadAssemblyTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Assembly];
+ AssemblyRow[] result = this.assemblyTable = new AssemblyRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Assembly];
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyRow row;
+ row.HashAlgId = c.ReadInt32();
+ row.MajorVersion = c.ReadUInt16();
+ row.MinorVersion = c.ReadUInt16();
+ row.BuildNumber = c.ReadUInt16();
+ row.RevisionNumber = c.ReadUInt16();
+ row.Flags = c.ReadInt32();
+ row.PublicKey = c.ReadReference(this.blobRefSize);
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Culture = c.ReadReference(this.stringRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadAssemblyRefTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.AssemblyRef];
+ AssemblyRefRow[] result = this.assemblyRefTable = new AssemblyRefRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.AssemblyRef];
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyRefRow row;
+ row.MajorVersion = c.ReadUInt16();
+ row.MinorVersion = c.ReadUInt16();
+ row.BuildNumber = c.ReadUInt16();
+ row.RevisionNumber = c.ReadUInt16();
+ row.Flags = c.ReadInt32();
+ row.PublicKeyOrToken = c.ReadReference(this.blobRefSize);
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Culture = c.ReadReference(this.stringRefSize);
+ row.HashValue = c.ReadReference(this.blobRefSize);
+ row.AssemblyReference = null;
+ result[i] = row;
+ }
+ }
+ private void ReadClassLayoutTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ClassLayout];
+ ClassLayoutRow[] result = this.classLayoutTable = new ClassLayoutRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ClassLayout];
+ for (int i = 0; i < n; i++)
+ {
+ ClassLayoutRow row;
+ row.PackingSize = c.ReadUInt16();
+ row.ClassSize = c.ReadInt32();
+ row.Parent = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ result[i] = row;
+ }
+ }
+ private void ReadConstantTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Constant];
+ ConstantRow[] result = this.constantTable = new ConstantRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Constant];
+ for (int i = 0; i < n; i++)
+ {
+ ConstantRow row;
+ row.Type = c.ReadByte();
+ c.ReadByte();
+ row.Parent = c.ReadReference(this.constantParentRefSize);
+ row.Value = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadCustomAttributeTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.CustomAttribute];
+ CustomAttributeRow[] result = this.customAttributeTable = new CustomAttributeRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.CustomAttribute];
+ for (int i = 0; i < n; i++)
+ {
+ CustomAttributeRow row;
+ row.Parent = c.ReadReference(this.customAttributeParentRefSize);
+ row.Constructor = c.ReadReference(this.customAttributeConstructorRefSize);
+ row.Value = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadDeclSecurityTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.DeclSecurity];
+ DeclSecurityRow[] result = this.declSecurityTable = new DeclSecurityRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.DeclSecurity];
+ for (int i = 0; i < n; i++)
+ {
+ DeclSecurityRow row;
+ row.Action = c.ReadUInt16();
+ row.Parent = c.ReadReference(this.declSecurityParentRefSize);
+ row.PermissionSet = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadEventMapTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.EventMap];
+ EventMapRow[] result = this.eventMapTable = new EventMapRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.EventMap];
+ for (int i = 0; i < n; i++)
+ {
+ EventMapRow row;
+ row.Parent = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ row.EventList = c.ReadReference(this.tableRefSize[(int)TableIndices.Event]);
+ result[i] = row;
+ }
+ }
+ private void ReadEventPtrTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.EventPtr];
+ EventPtrRow[] result = this.eventPtrTable = new EventPtrRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.EventPtr];
+ for (int i = 0; i < n; i++)
+ {
+ EventPtrRow row;
+ row.Event = c.ReadReference(this.tableRefSize[(int)TableIndices.Event]);
+ result[i] = row;
+ }
+ }
+ private void ReadEventTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Event];
+ EventRow[] result = this.eventTable = new EventRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Event];
+ for (int i = 0; i < n; i++)
+ {
+ EventRow row;
+ row.Flags = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.EventType = c.ReadReference(this.typeDefOrRefOrSpecSize);
+ result[i] = row;
+ }
+ }
+ private void ReadExportedTypeTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ExportedType];
+ ExportedTypeRow[] result = this.exportedTypeTable = new ExportedTypeRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ExportedType];
+ for (int i = 0; i < n; i++)
+ {
+ ExportedTypeRow row;
+ row.Flags = c.ReadInt32();
+ row.TypeDefId = c.ReadInt32();
+ row.TypeName = c.ReadReference(this.stringRefSize);
+ row.TypeNamespace = c.ReadReference(this.stringRefSize);
+ row.Implementation = c.ReadReference(this.implementationRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadFieldTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Field];
+ FieldRow[] result = this.fieldTable = new FieldRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Field];
+ for (int i = 0; i < n; i++)
+ {
+ FieldRow row;
+ row.Flags = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Signature = c.ReadReference(this.blobRefSize);
+ row.Field = null;
+ result[i] = row;
+ }
+ }
+ private void ReadFieldLayoutTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldLayout];
+ FieldLayoutRow[] result = this.fieldLayoutTable = new FieldLayoutRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.FieldLayout];
+ for (int i = 0; i < n; i++)
+ {
+ FieldLayoutRow row;
+ row.Offset = c.ReadInt32();
+ row.Field = c.ReadReference(this.tableRefSize[(int)TableIndices.Field]);
+ result[i] = row;
+ }
+ }
+ private void ReadFieldMarshalTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldMarshal];
+ FieldMarshalRow[] result = this.fieldMarshalTable = new FieldMarshalRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.FieldMarshal];
+ for (int i = 0; i < n; i++)
+ {
+ FieldMarshalRow row;
+ row.Parent = c.ReadReference(this.fieldMarshalParentRefSize);
+ row.NativeType = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadFieldPtrTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldPtr];
+ FieldPtrRow[] result = this.fieldPtrTable = new FieldPtrRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.FieldPtr];
+ for (int i = 0; i < n; i++)
+ {
+ FieldPtrRow row;
+ row.Field = c.ReadReference(this.tableRefSize[(int)TableIndices.Field]);
+ result[i] = row;
+ }
+ }
+ private void ReadFieldRvaTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldRva];
+ FieldRvaRow[] result = this.fieldRvaTable = new FieldRvaRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.FieldRva];
+ for (int i = 0; i < n; i++)
+ {
+ FieldRvaRow row;
+ row.RVA = c.ReadInt32();
+ row.Field = c.ReadReference(this.tableRefSize[(int)TableIndices.Field]);
+ row.TargetSection = 0; //Ignored on reading
+ result[i] = row;
+ }
+ }
+ private void ReadFileTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.File];
+ FileRow[] result = this.fileTable = new FileRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.File];
+ for (int i = 0; i < n; i++)
+ {
+ FileRow row;
+ row.Flags = c.ReadInt32();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.HashValue = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadGenericParamTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.GenericParam];
+ GenericParamRow[] result = this.genericParamTable = new GenericParamRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.GenericParam];
+ bool reallyOldGenericsFileFormat = this.metadataFormatMajorVersion == 1 && this.metadataFormatMinorVersion == 0;
+ bool oldGenericsFileFormat = this.metadataFormatMajorVersion == 1 && this.metadataFormatMinorVersion == 1;
+ for (int i = 0; i < n; i++)
+ {
+ GenericParamRow row;
+ row.Number = c.ReadUInt16();
+ row.Flags = c.ReadUInt16();
+ row.Owner = c.ReadReference(this.typeDefOrMethodDefSize);
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.GenericParameter = null;
+ if (oldGenericsFileFormat) c.ReadReference(this.typeDefOrRefOrSpecSize);
+ if (reallyOldGenericsFileFormat) c.ReadInt16();
+ result[i] = row;
+ }
+ }
+ private void ReadGenericParamConstraintTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.GenericParamConstraint];
+ GenericParamConstraintRow[] result = this.genericParamConstraintTable = new GenericParamConstraintRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.GenericParamConstraint];
+ for (int i = 0; i < n; i++)
+ {
+ GenericParamConstraintRow row;
+ row.Param = c.ReadReference(this.tableRefSize[(int)TableIndices.GenericParam]);
+ row.Constraint = c.ReadReference(this.typeDefOrRefOrSpecSize);
+ result[i] = row;
+ }
+ }
+ private void ReadImplMapTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ImplMap];
+ ImplMapRow[] result = this.implMapTable = new ImplMapRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ImplMap];
+ for (int i = 0; i < n; i++)
+ {
+ ImplMapRow row;
+ row.MappingFlags = c.ReadUInt16();
+ row.MemberForwarded = c.ReadReference(this.memberForwardedRefSize);
+ row.ImportName = c.ReadReference(this.stringRefSize);
+ row.ImportScope = c.ReadReference(this.tableRefSize[(int)TableIndices.ModuleRef]);
+ result[i] = row;
+ }
+ }
+ private void ReadInterfaceImplTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.InterfaceImpl];
+ InterfaceImplRow[] result = this.interfaceImplTable = new InterfaceImplRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.InterfaceImpl];
+ for (int i = 0; i < n; i++)
+ {
+ InterfaceImplRow row;
+ row.Class = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ row.Interface = c.ReadReference(this.typeDefOrRefOrSpecSize);
+ result[i] = row;
+ }
+ }
+ private void ReadManifestResourceTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ManifestResource];
+ ManifestResourceRow[] result = this.manifestResourceTable = new ManifestResourceRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ManifestResource];
+ for (int i = 0; i < n; i++)
+ {
+ ManifestResourceRow row;
+ row.Offset = c.ReadInt32();
+ row.Flags = c.ReadInt32();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Implementation = c.ReadReference(this.implementationRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadMemberRefTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MemberRef];
+ MemberRefRow[] result = this.memberRefTable = new MemberRefRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.MemberRef];
+ for (int i = 0; i < n; i++)
+ {
+ MemberRefRow row;
+ row.Class = c.ReadReference(this.memberRefParentSize);
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Signature = c.ReadReference(this.blobRefSize);
+ row.Member = null;
+ row.VarargTypes = null;
+ result[i] = row;
+ }
+ }
+ private void ReadMethodTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Method];
+ MethodRow[] result = this.methodTable = new MethodRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Method];
+ for (int i = 0; i < n; i++)
+ {
+ MethodRow row;
+ row.RVA = c.ReadInt32();
+ row.ImplFlags = c.ReadUInt16();
+ row.Flags = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Signature = c.ReadReference(this.blobRefSize);
+ row.ParamList = c.ReadReference(this.tableRefSize[(int)TableIndices.Param]);
+ row.Method = null;
+ result[i] = row;
+ }
+ }
+ private void ReadMethodImplTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodImpl];
+ MethodImplRow[] result = this.methodImplTable = new MethodImplRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.MethodImpl];
+ for (int i = 0; i < n; i++)
+ {
+ MethodImplRow row;
+ row.Class = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ row.MethodBody = c.ReadReference(this.methodDefOrRefSize);
+ row.MethodDeclaration = c.ReadReference(this.methodDefOrRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadMethodPtrTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodPtr];
+ MethodPtrRow[] result = this.methodPtrTable = new MethodPtrRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.MethodPtr];
+ for (int i = 0; i < n; i++)
+ {
+ MethodPtrRow row;
+ row.Method = c.ReadReference(this.tableRefSize[(int)TableIndices.Method]);
+ result[i] = row;
+ }
+ }
+ private void ReadMethodSemanticsTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodSemantics];
+ MethodSemanticsRow[] result = this.methodSemanticsTable = new MethodSemanticsRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.MethodSemantics];
+ for (int i = 0; i < n; i++)
+ {
+ MethodSemanticsRow row;
+ row.Semantics = c.ReadUInt16();
+ row.Method = c.ReadReference(this.tableRefSize[(int)TableIndices.Method]);
+ row.Association = c.ReadReference(this.hasSemanticRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadMethodSpecTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodSpec];
+ MethodSpecRow[] result = this.methodSpecTable = new MethodSpecRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.MethodSpec];
+ for (int i = 0; i < n; i++)
+ {
+ MethodSpecRow row;
+ row.Method = c.ReadReference(this.methodDefOrRefSize);
+ row.Instantiation = c.ReadReference(this.blobRefSize);
+ row.InstantiatedMethod = null;
+ result[i] = row;
+ }
+ }
+ private void ReadModuleTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Module];
+ ModuleRow[] result = this.moduleTable = new ModuleRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Module];
+ for (int i = 0; i < n; i++)
+ {
+ ModuleRow row;
+ row.Generation = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Mvid = c.ReadReference(this.guidRefSize);
+ row.EncId = c.ReadReference(this.guidRefSize);
+ row.EncBaseId = c.ReadReference(this.guidRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadModuleRefTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ModuleRef];
+ ModuleRefRow[] result = this.moduleRefTable = new ModuleRefRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ModuleRef];
+ for (int i = 0; i < n; i++)
+ {
+ ModuleRefRow row;
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Module = null;
+ result[i] = row;
+ }
+ }
+ private void ReadNestedClassTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.NestedClass];
+ NestedClassRow[] result = this.nestedClassTable = new NestedClassRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.NestedClass];
+ for (int i = 0; i < n; i++)
+ {
+ NestedClassRow row;
+ row.NestedClass = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ row.EnclosingClass = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ result[i] = row;
+ }
+ }
+ private void ReadParamTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Param];
+ ParamRow[] result = this.paramTable = new ParamRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Param];
+ for (int i = 0; i < n; i++)
+ {
+ ParamRow row;
+ row.Flags = c.ReadUInt16();
+ row.Sequence = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadParamPtrTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ParamPtr];
+ ParamPtrRow[] result = this.paramPtrTable = new ParamPtrRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.ParamPtr];
+ for (int i = 0; i < n; i++)
+ {
+ ParamPtrRow row;
+ row.Param = c.ReadReference(this.tableRefSize[(int)TableIndices.Param]);
+ result[i] = row;
+ }
+ }
+ private void ReadPropertyTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Property];
+ PropertyRow[] result = this.propertyTable = new PropertyRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.Property];
+ for (int i = 0; i < n; i++)
+ {
+ PropertyRow row;
+ row.Flags = c.ReadUInt16();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Signature = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadPropertyMapTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.PropertyMap];
+ PropertyMapRow[] result = this.propertyMapTable = new PropertyMapRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.PropertyMap];
+ for (int i = 0; i < n; i++)
+ {
+ PropertyMapRow row;
+ row.Parent = c.ReadReference(this.tableRefSize[(int)TableIndices.TypeDef]);
+ row.PropertyList = c.ReadReference(this.tableRefSize[(int)TableIndices.Property]);
+ result[i] = row;
+ }
+ }
+ private void ReadPropertyPtrTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.PropertyPtr];
+ PropertyPtrRow[] result = this.propertyPtrTable = new PropertyPtrRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.PropertyPtr];
+ for (int i = 0; i < n; i++)
+ {
+ PropertyPtrRow row;
+ row.Property = c.ReadReference(this.tableRefSize[(int)TableIndices.Property]);
+ result[i] = row;
+ }
+ }
+ private void ReadStandAloneSigTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.StandAloneSig];
+ StandAloneSigRow[] result = this.standAloneSigTable = new StandAloneSigRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.StandAloneSig];
+ for (int i = 0; i < n; i++)
+ {
+ StandAloneSigRow row;
+ row.Signature = c.ReadReference(this.blobRefSize);
+ result[i] = row;
+ }
+ }
+ private void ReadTypeDefTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeDef];
+ TypeDefRow[] result = this.typeDefTable = new TypeDefRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.TypeDef];
+ for (int i = 0; i < n; i++)
+ {
+ TypeDefRow row;
+ row.Flags = c.ReadInt32();
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Namespace = c.ReadReference(this.stringRefSize);
+ row.Extends = c.ReadReference(this.typeDefOrRefOrSpecSize);
+ row.FieldList = c.ReadReference(this.tableRefSize[(int)TableIndices.Field]);
+ row.MethodList = c.ReadReference(this.tableRefSize[(int)TableIndices.Method]);
+ row.Type = null;
+ row.NameKey = 0;
+ row.NamespaceId = null;
+ row.NamespaceKey = 0;
+ result[i] = row;
+ }
+ for (int i = 0; i < n; i++)
+ {
+ result[i].NameKey = this.GetIdentifier(result[i].Name).UniqueIdKey;
+ result[i].NamespaceId = this.GetIdentifier(result[i].Namespace);
+ //^ assume result[i].NamespaceId != null;
+ result[i].NamespaceKey = result[i].NamespaceId.UniqueIdKey;
+ }
+ }
+ private void ReadTypeRefTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeRef];
+ TypeRefRow[] result = this.typeRefTable = new TypeRefRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.TypeRef];
+ for (int i = 0; i < n; i++)
+ {
+ TypeRefRow row;
+ row.ResolutionScope = c.ReadReference(this.resolutionScopeRefSize);
+ row.Name = c.ReadReference(this.stringRefSize);
+ row.Namespace = c.ReadReference(this.stringRefSize);
+ row.Type = null;
+ result[i] = row;
+ }
+ }
+ private void ReadTypeSpecTable()
+ //^ requires this.tableSize != null;
+ //^ requires this.tableOffset != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeSpec];
+ TypeSpecRow[] result = this.typeSpecTable = new TypeSpecRow[n];
+ if (n == 0) return;
+ MemoryCursor c = this.cursor;
+ c.Position = this.tableOffset[(int)TableIndices.TypeSpec];
+ for (int i = 0; i < n; i++)
+ {
+ TypeSpecRow row;
+ row.Signature = c.ReadReference(this.blobRefSize);
+ row.Type = null;
+ result[i] = row;
+ }
+ }
+ internal int GetOffsetToEndOfSection(int virtualAddress)
+ {
+ foreach (SectionHeader section in this.sectionHeaders)
+ if (virtualAddress >= section.virtualAddress && virtualAddress < section.virtualAddress + section.sizeOfRawData)
+ return (section.sizeOfRawData - (virtualAddress - section.virtualAddress));
+ return -1;
+ }
+ internal bool NoOffsetFor(int virtualAddress)
+ {
+ foreach (SectionHeader section in this.sectionHeaders)
+ if (virtualAddress >= section.virtualAddress && virtualAddress < section.virtualAddress + section.sizeOfRawData)
+ return false;
+ return true;
+ }
+ private int RvaToOffset(int virtualAddress)
+ {
+ foreach (SectionHeader section in this.sectionHeaders)
+ if (virtualAddress >= section.virtualAddress && virtualAddress < section.virtualAddress + section.sizeOfRawData)
+ return (virtualAddress - section.virtualAddress + section.pointerToRawData);
+ throw new InvalidMetadataException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.UnknownVirtualAddress, virtualAddress));
+ }
+ private int RvaToOffset(int virtualAddress, out PESection targetSection)
+ {
+ foreach (SectionHeader section in this.sectionHeaders)
+ if (virtualAddress >= section.virtualAddress && virtualAddress < section.virtualAddress + section.sizeOfRawData)
+ {
+ if (section.name == ".tls") targetSection = PESection.TLS;
+ else if (section.name == ".sdata") targetSection = PESection.SData;
+ else targetSection = PESection.Text;
+ return (virtualAddress - section.virtualAddress + section.pointerToRawData);
+ }
+ throw new InvalidMetadataException(String.Format(
+ CultureInfo.CurrentCulture, ExceptionStrings.UnknownVirtualAddress, +virtualAddress));
+ }
+ private static CLIHeader/*!*/ ReadCLIHeader(MemoryCursor/*!*/ c)
+ {
+ CLIHeader header = new CLIHeader();
+ header.cb = c.Int32(0); c.SkipInt32(1);
+ header.majorRuntimeVersion = c.UInt16(0);
+ header.minorRuntimeVersion = c.UInt16(1); c.SkipUInt16(2);
+ header.metaData = ReadDirectoryEntry(c);
+ header.flags = c.Int32(0);
+ header.entryPointToken = c.Int32(1); c.SkipInt32(2);
+ header.resources = ReadDirectoryEntry(c);
+ header.strongNameSignature = ReadDirectoryEntry(c);
+ header.codeManagerTable = ReadDirectoryEntry(c);
+ header.vtableFixups = ReadDirectoryEntry(c);
+ header.exportAddressTableJumps = ReadDirectoryEntry(c);
+ if (header.majorRuntimeVersion < 2)
+ throw new InvalidMetadataException(ExceptionStrings.BadCLIHeader);
+ return header;
+ }
+ private static DirectoryEntry ReadDirectoryEntry(MemoryCursor/*!*/ c)
+ {
+ DirectoryEntry entry = new DirectoryEntry();
+ entry.virtualAddress = c.Int32(0);
+ entry.size = c.Int32(1); c.SkipInt32(2);
+ return entry;
+ }
+ internal static void ReadDOSHeader(MemoryCursor/*!*/ c)
+ {
+ c.Position = 0;
+ int magicNumber = c.UInt16(0);
+ if (magicNumber != 0x5a4d) throw new InvalidMetadataException(ExceptionStrings.BadMagicNumber);
+ c.Position = 0x3c;
+ int ntHeaderOffset = c.Int32(0);
+ c.Position = ntHeaderOffset;
+ }
+ private static MetadataHeader/*!*/ ReadMetadataHeader(MemoryCursor/*!*/ c)
+ {
+ MetadataHeader header = new MetadataHeader();
+ header.signature = c.ReadInt32();
+ if (header.signature != 0x424a5342)
+ throw new InvalidMetadataException(ExceptionStrings.BadMetadataHeaderSignature);
+ header.majorVersion = c.ReadUInt16();
+ header.minorVersion = c.ReadUInt16();
+ header.reserved = c.ReadInt32();
+ int len = c.ReadInt32();
+ header.versionString = c.ReadASCII(len);
+ while (len++ % 4 != 0) c.ReadByte();
+ header.flags = c.ReadUInt16();
+ int n = c.ReadUInt16();
+ StreamHeader[] streamHeaders = header.streamHeaders = new StreamHeader[n];
+ for (int i = 0; i < n; i++)
+ streamHeaders[i] = ReadStreamHeader(c);
+ return header;
+ }
+ internal static NTHeader/*!*/ ReadNTHeader(MemoryCursor/*!*/ c)
+ {
+ NTHeader header = new NTHeader();
+ header.signature = c.ReadInt32();
+ header.machine = c.ReadUInt16();
+ header.numberOfSections = c.ReadUInt16();
+ header.timeDateStamp = c.ReadInt32();
+ header.pointerToSymbolTable = c.ReadInt32();
+ header.numberOfSymbols = c.ReadInt32();
+ header.sizeOfOptionalHeader = c.ReadUInt16();
+ header.characteristics = c.ReadUInt16();
+ header.magic = c.ReadUInt16();
+ header.majorLinkerVersion = c.ReadByte();
+ header.minorLinkerVersion = c.ReadByte();
+ header.sizeOfCode = c.ReadInt32();
+ header.sizeOfInitializedData = c.ReadInt32();
+ header.sizeOfUninitializedData = c.ReadInt32();
+ header.addressOfEntryPoint = c.ReadInt32();
+ header.baseOfCode = c.ReadInt32();
+ if (header.magic == 0x10B)
+ {
+ header.baseOfData = c.ReadInt32();
+ header.imageBase = c.ReadInt32();
+ }
+ else
+ {
+ header.baseOfData = 0;
+ header.imageBase = c.ReadInt64();
+ }
+ header.sectionAlignment = c.ReadInt32();
+ header.fileAlignment = c.ReadInt32();
+ header.majorOperatingSystemVersion = c.ReadUInt16();
+ header.minorOperatingSystemVersion = c.ReadUInt16();
+ header.majorImageVersion = c.ReadUInt16();
+ header.minorImageVersion = c.ReadUInt16();
+ header.majorSubsystemVersion = c.ReadUInt16();
+ header.minorSubsystemVersion = c.ReadUInt16();
+ header.win32VersionValue = c.ReadInt32();
+ header.sizeOfImage = c.ReadInt32();
+ header.sizeOfHeaders = c.ReadInt32();
+ header.checkSum = c.ReadInt32();
+ header.subsystem = c.ReadUInt16();
+ header.dllCharacteristics = c.ReadUInt16();
+ if (header.magic == 0x10B)
+ {
+ header.sizeOfStackReserve = c.ReadInt32();
+ header.sizeOfStackCommit = c.ReadInt32();
+ header.sizeOfHeapReserve = c.ReadInt32();
+ header.sizeOfHeapCommit = c.ReadInt32();
+ }
+ else
+ {
+ header.sizeOfStackReserve = c.ReadInt64();
+ header.sizeOfStackCommit = c.ReadInt64();
+ header.sizeOfHeapReserve = c.ReadInt64();
+ header.sizeOfHeapCommit = c.ReadInt64();
+ }
+ header.loaderFlags = c.ReadInt32();
+ header.numberOfDataDirectories = c.ReadInt32();
+
+ // Verify that the header signature and magic number are valid
+ if (header.signature != 0x00004550 /* "PE\0\0" */)
+ throw new InvalidMetadataException(ExceptionStrings.BadCOFFHeaderSignature);
+ if (header.magic != 0x010B && header.magic != 0x020B)
+ throw new InvalidMetadataException(ExceptionStrings.BadPEHeaderMagicNumber);
+
+ //Read the data directories
+ header.exportTable = ReadDirectoryEntry(c);
+ header.importTable = ReadDirectoryEntry(c);
+ header.resourceTable = ReadDirectoryEntry(c);
+ header.exceptionTable = ReadDirectoryEntry(c);
+ header.certificateTable = ReadDirectoryEntry(c);
+ header.baseRelocationTable = ReadDirectoryEntry(c);
+ header.debugTable = ReadDirectoryEntry(c);
+ header.copyrightTable = ReadDirectoryEntry(c);
+ header.globalPointerTable = ReadDirectoryEntry(c);
+ header.threadLocalStorageTable = ReadDirectoryEntry(c);
+ header.loadConfigTable = ReadDirectoryEntry(c);
+ header.boundImportTable = ReadDirectoryEntry(c);
+ header.importAddressTable = ReadDirectoryEntry(c);
+ header.delayImportTable = ReadDirectoryEntry(c);
+ header.cliHeaderTable = ReadDirectoryEntry(c);
+ header.reserved = ReadDirectoryEntry(c);
+
+ return header;
+ }
+ internal static SectionHeader ReadSectionHeader(MemoryCursor/*!*/ c)
+ {
+ SectionHeader header = new SectionHeader();
+ header.name = c.ReadASCII(8);
+ header.virtualSize = c.Int32(0);
+ header.virtualAddress = c.Int32(1);
+ header.sizeOfRawData = c.Int32(2);
+ header.pointerToRawData = c.Int32(3);
+ header.pointerToRelocations = c.Int32(4);
+ header.pointerToLinenumbers = c.Int32(5); c.SkipInt32(6);
+ header.numberOfRelocations = c.UInt16(0);
+ header.numberOfLinenumbers = c.UInt16(1); c.SkipInt16(2);
+ header.characteristics = c.Int32(0); c.SkipInt32(1);
+ return header;
+ }
+ private static StreamHeader ReadStreamHeader(MemoryCursor/*!*/ c)
+ {
+ StreamHeader header = new StreamHeader();
+ header.offset = c.ReadInt32();
+ header.size = c.ReadInt32();
+ header.name = c.ReadASCII();
+ int n = header.name.Length + 1;
+ c.Position += (4 - (n % 4)) % 4;
+ return header;
+ }
+ private static TablesHeader/*!*/ ReadTablesHeader(MemoryCursor/*!*/ c)
+ {
+ TablesHeader header = new TablesHeader();
+ header.reserved = c.ReadInt32(); // Must be zero
+ header.majorVersion = c.ReadByte(); // Must be one
+ header.minorVersion = c.ReadByte(); // Must be zero
+ header.heapSizes = c.ReadByte(); // Bits for heap sizes
+ header.rowId = c.ReadByte(); // log-base-2 of largest rowId
+ header.maskValid = c.ReadInt64(); // Present table counts
+ header.maskSorted = c.ReadInt64(); // Sorted tables
+ int n = 0;
+ ulong mask = (ulong)header.maskValid;
+ while (mask != 0)
+ {
+ if (mask % 2 == 1) n++;
+ mask /= 2;
+ }
+ int[] countArray = header.countArray = new int[n];
+ for (int i = 0; i < n; i++)
+ countArray[i] = c.ReadInt32();
+ return header;
+ }
+ }
+#if !NoWriter
+ internal class MetadataWriter
+ {
+ internal MemoryStream StringHeap;
+ internal MemoryStream BlobHeap;
+ internal MemoryStream UserstringHeap;
+ internal MemoryStream ResourceDataHeap;
+ internal MemoryStream SdataHeap;
+ internal MemoryStream TlsHeap;
+ internal Guid[] GuidHeap;
+ internal MemoryStream MethodBodiesHeap;
+ internal Win32ResourceList Win32Resources;
+ internal AssemblyRow[] assemblyTable;
+ internal AssemblyRefRow[] assemblyRefTable;
+ internal ClassLayoutRow[] classLayoutTable;
+ internal ConstantRow[] constantTable;
+ internal CustomAttributeRow[] customAttributeTable;
+ internal DeclSecurityRow[] declSecurityTable;
+ internal EventMapRow[] eventMapTable;
+ internal EventRow[] eventTable;
+ internal ExportedTypeRow[] exportedTypeTable = null;
+ internal FieldRow[] fieldTable;
+ internal FieldLayoutRow[] fieldLayoutTable;
+ internal FieldMarshalRow[] fieldMarshalTable = null;
+ internal FieldRvaRow[] fieldRvaTable = null;
+ internal FileRow[] fileTable;
+ internal GenericParamRow[] genericParamTable;
+ internal GenericParamConstraintRow[] genericParamConstraintTable;
+ internal ImplMapRow[] implMapTable;
+ internal InterfaceImplRow[] interfaceImplTable;
+ internal ManifestResourceRow[] manifestResourceTable = null;
+ internal MemberRefRow[] memberRefTable;
+ internal MethodRow[] methodTable;
+ internal MethodImplRow[] methodImplTable;
+ internal MethodSemanticsRow[] methodSemanticsTable;
+ internal MethodSpecRow[] methodSpecTable;
+ internal ModuleRow[] moduleTable;
+ internal ModuleRefRow[] moduleRefTable;
+ internal NestedClassRow[] nestedClassTable;
+ internal ParamRow[] paramTable;
+ internal PropertyRow[] propertyTable;
+ internal PropertyMapRow[] propertyMapTable;
+ internal StandAloneSigRow[] standAloneSigTable;
+ internal TypeDefRow[] typeDefTable;
+ internal TypeRefRow[] typeRefTable;
+ internal TypeSpecRow[] typeSpecTable;
+ internal int entryPointToken;
+ internal int fileAlignment;
+ internal ModuleKindFlags moduleKind;
+ internal PEKindFlags peKind;
+ internal bool TrackDebugData;
+ internal bool UseGenerics = false;
+ internal byte[] PublicKey;
+
+ private int blobRefSize;
+ private int constantParentRefSize;
+ private int customAttributeParentRefSize;
+ private int customAttributeConstructorRefSize;
+ private int declSecurityParentRefSize;
+ private int fieldMarshalParentRefSize;
+ private int guidRefSize;
+ private int hasSemanticRefSize;
+ private int implementationRefSize;
+ private int methodDefOrRefSize;
+ private int memberRefParentSize;
+ private int memberForwardedRefSize;
+ private int typeDefOrMethodDefSize;
+ private int typeDefOrRefOrSpecSize;
+ private int resolutionScopeRefSize;
+ private int stringRefSize;
+#if !ROTOR
+ private ISymUnmanagedWriter symWriter;
+#endif
+ private int[] tableRefSize;
+ private int[] tableSize;
+ private long validMask;
+
+#if !ROTOR
+ internal MetadataWriter(ISymUnmanagedWriter symWriter)
+ {
+ this.symWriter = symWriter;
+ }
+#else
+ internal MetadataWriter(){
+ }
+#endif
+
+ private void SerializeMetadata(BinaryWriter/*!*/ writer, int virtualAddressBase, Fixup/*!*/ sdataFixup, Fixup/*!*/ tlsFixup)
+ //^ requires this.MethodBodiesHeap != null;
+ //^ requires this.ResourceDataHeap != null;
+ //^ requires this.StringHeap != null;
+ //^ requires this.UserstringHeap != null;
+ //^ requires this.BlobHeap != null;
+ //^ requires this.GuidHeap != null;
+ //^ requires TargetPlatform.TargetRuntimeVersion != null;
+ {
+ int tableOffset = 0;
+ tableOffset += (int)this.MethodBodiesHeap.Length;
+ this.MethodBodiesHeap.WriteTo(writer.BaseStream);
+ while (tableOffset % 4 != 0) { writer.Write((byte)0); tableOffset++; }
+ if (this.PublicKey != null && 0 < this.PublicKey.Length)
+ {
+ this.cliHeader.strongNameSignature.virtualAddress = virtualAddressBase + 72 + tableOffset;
+ int keysize = this.PublicKey.Length - 32;
+ if (keysize < 128) keysize = 128;
+ this.cliHeader.strongNameSignature.size = keysize;
+ tableOffset += keysize;
+ writer.BaseStream.Position += keysize;
+ }
+ if (this.ResourceDataHeap.Length > 0)
+ {
+ this.cliHeader.resources.virtualAddress = virtualAddressBase + 72 + tableOffset;
+ this.ResourceDataHeap.WriteTo(writer.BaseStream);
+ int sizeOfResources = (int)this.ResourceDataHeap.Length;
+ while (sizeOfResources % 4 != 0) { writer.Write((byte)0); sizeOfResources++; }
+ this.cliHeader.resources.size = sizeOfResources;
+ tableOffset += sizeOfResources;
+ }
+ this.cliHeader.metaData.virtualAddress = virtualAddressBase + 72 + tableOffset;
+ int startPos = (int)writer.BaseStream.Position;
+ writer.Write((int)0x424a5342); //Magic signature
+ writer.Write((short)1); //Major version
+ writer.Write((short)1); //Minor version
+ writer.Write((int)0); //Reserved
+ writer.Write((int)12); // version must be 12 chars
+ char[] version = new char[12];
+ char[] aversion = TargetPlatform.TargetRuntimeVersion.ToCharArray();
+ Array.Copy(aversion, 0, version, 0, Math.Min(12, aversion.Length));
+ writer.Write(version);
+ writer.Write((short)0); //flags
+ writer.Write((short)5); //number of streams
+ int offsetFromStartOfMetadata = 108;
+ writer.Write((int)offsetFromStartOfMetadata);
+ int cbStringHeapPad = 0;
+ offsetFromStartOfMetadata += (int)this.StringHeap.Length;
+ while (offsetFromStartOfMetadata % 4 != 0)
+ {
+ offsetFromStartOfMetadata++;
+ cbStringHeapPad++;
+ }
+ writer.Write((int)this.StringHeap.Length + cbStringHeapPad);
+ writer.Write(new char[] { '#', 'S', 't', 'r', 'i', 'n', 'g', 's', '\0', '\0', '\0', '\0' });
+
+ writer.Write((int)offsetFromStartOfMetadata);
+ offsetFromStartOfMetadata += (int)this.UserstringHeap.Length;
+ int cbUserStringHeapPad = 0;
+ while (offsetFromStartOfMetadata % 4 != 0)
+ {
+ offsetFromStartOfMetadata++;
+ cbUserStringHeapPad++;
+ }
+
+ writer.Write((int)this.UserstringHeap.Length + cbUserStringHeapPad);
+ writer.Write(new char[] { '#', 'U', 'S', '\0' });
+
+ writer.Write((int)offsetFromStartOfMetadata);
+ writer.Write((int)this.BlobHeap.Length);
+ writer.Write(new char[] { '#', 'B', 'l', 'o', 'b', '\0', '\0', '\0' });
+ offsetFromStartOfMetadata += (int)this.BlobHeap.Length;
+ while (offsetFromStartOfMetadata % 4 != 0) offsetFromStartOfMetadata++;
+ writer.Write((int)offsetFromStartOfMetadata);
+ writer.Write((int)this.GuidHeap.Length * 16);
+ writer.Write(new char[] { '#', 'G', 'U', 'I', 'D', '\0', '\0', '\0' });
+ offsetFromStartOfMetadata += this.GuidHeap.Length * 16;
+ writer.Write((int)offsetFromStartOfMetadata);
+ int tabsL = this.TablesLength();
+ writer.Write((int)tabsL);
+ writer.Write(new char[] { '#', '~', '\0', '\0' });
+ this.StringHeap.WriteTo(writer.BaseStream);
+ int p = (int)this.StringHeap.Length;// +cbStringHeapPad;
+ while (p % 4 != 0) { writer.Write((byte)0); p++; }
+ this.UserstringHeap.WriteTo(writer.BaseStream);
+ p = (int)this.UserstringHeap.Length;// +cbUserStringHeapPad;
+ while (p % 4 != 0) { writer.Write((byte)0); p++; }
+ this.BlobHeap.WriteTo(writer.BaseStream);
+ p = (int)this.BlobHeap.Length;
+ while (p % 4 != 0) { writer.Write((byte)0); p++; }
+ for (int i = 0, n = this.GuidHeap.Length; i < n; i++)
+ writer.Write(this.GuidHeap[i].ToByteArray());
+ this.SerializeTables(writer, virtualAddressBase + 72, sdataFixup, tlsFixup);
+ this.cliHeader.metaData.size = ((int)writer.BaseStream.Position) - startPos;
+ }
+#if !ROTOR
+ private unsafe void WriteReferenceToPDBFile(BinaryWriter/*!*/ writer, int virtualAddressBase, int fileBase)
+ //^ requires this.symWriter != null;
+ {
+ int startPos = writer.BaseStream.Position;
+ this.ntHeader.debugTable.virtualAddress = startPos - fileBase + virtualAddressBase;
+ this.ntHeader.debugTable.size = 28;
+ ImageDebugDirectory debugDir = new ImageDebugDirectory(true);
+ uint pcData = 0;
+ this.symWriter.GetDebugInfo(ref debugDir, 0, out pcData, IntPtr.Zero);
+ byte[] data = new byte[pcData];
+ fixed (byte* pb = data)
+ {
+ this.symWriter.GetDebugInfo(ref debugDir, pcData, out pcData, (IntPtr)pb);
+ }
+ writer.Write((int)debugDir.Characteristics);
+ writer.Write(this.ntHeader.timeDateStamp);
+ writer.Write((ushort)debugDir.MajorVersion);
+ writer.Write((ushort)debugDir.MinorVersion);
+ writer.Write((int)debugDir.Type);
+ writer.Write((int)debugDir.SizeOfData);
+ writer.Write((int)startPos + 28 - fileBase + virtualAddressBase); //AddressOfRawData
+ writer.Write((int)startPos + 28); //PointerToRawData
+ writer.Write((byte[])data);
+ }
+#endif
+ private void SerializeTables(BinaryWriter/*!*/ writer, int mbRVAOffset, Fixup/*!*/ sdataFixup, Fixup/*!*/ tlsFixup)
+ //^ requires this.StringHeap != null;
+ //^ requires this.GuidHeap != null;
+ //^ requires this.BlobHeap != null;
+ //^ requires this.tableSize != null;
+ //^ requires this.tableRefSize != null;
+ {
+ writer.Write((int)0); //Reserved
+ writer.Write((byte)TargetPlatform.MajorVersion);
+ writer.Write((byte)TargetPlatform.MinorVersion);
+ byte heapSizes = 0;
+ if (this.StringHeap.Length >= 0x10000) heapSizes |= 0x01;
+ if (this.GuidHeap.Length >= 0x10000) heapSizes |= 0x02;
+ if (this.BlobHeap.Length >= 0x10000) heapSizes |= 0x04;
+ writer.Write(heapSizes);
+ writer.Write((byte)0); //Reserved
+ writer.Write(this.validMask); //Tables that are present
+ if (this.UseGenerics)
+ writer.Write((long)0x16003301fa00); //Tables that are sorted
+ else
+ writer.Write((long)0x02003301fa00); //Tables that are sorted
+ int[] tableSize = this.tableSize;
+ for (int i = 0, n = 0; i < (int)TableIndices.Count; i++)
+ if ((n = tableSize[i]) > 0) writer.Write(n);
+ if (this.moduleTable != null) this.SerializeModuleTable(writer);
+ if (this.typeRefTable != null) this.SerializeTypeRefTable(writer);
+ if (this.typeDefTable != null) this.SerializeTypeDefTable(writer);
+ if (this.fieldTable != null) this.SerializeFieldTable(writer);
+ if (this.methodTable != null) this.SerializeMethodTable(writer, mbRVAOffset);
+ if (this.paramTable != null) this.SerializeParamTable(writer);
+ if (this.interfaceImplTable != null) this.SerializeInterfaceImplTable(writer);
+ if (this.memberRefTable != null) this.SerializeMemberRefTable(writer);
+ if (this.constantTable != null) this.SerializeConstantTable(writer);
+ if (this.customAttributeTable != null) this.SerializeCustomAttributeTable(writer);
+ if (this.fieldMarshalTable != null) this.SerializeFieldMarshalTable(writer);
+ if (this.declSecurityTable != null) this.SerializeDeclSecurityTable(writer);
+ if (this.classLayoutTable != null) this.SerializeClassLayoutTable(writer);
+ if (this.fieldLayoutTable != null) this.SerializeFieldLayoutTable(writer);
+ if (this.standAloneSigTable != null) this.SerializeStandAloneSigTable(writer);
+ if (this.eventMapTable != null) this.SerializeEventMapTable(writer);
+ if (this.eventTable != null) this.SerializeEventTable(writer);
+ if (this.propertyMapTable != null) this.SerializePropertyMapTable(writer);
+ if (this.propertyTable != null) this.SerializePropertyTable(writer);
+ if (this.methodSemanticsTable != null) this.SerializeMethodSemanticsTable(writer);
+ if (this.methodImplTable != null) this.SerializeMethodImplTable(writer);
+ if (this.moduleRefTable != null) this.SerializeModuleRefTable(writer);
+ if (this.typeSpecTable != null) this.SerializeTypeSpecTable(writer);
+ if (this.implMapTable != null) this.SerializeImplMapTable(writer);
+ if (this.fieldRvaTable != null) this.SerializeFieldRvaTable(writer, mbRVAOffset, sdataFixup, tlsFixup);
+ if (this.assemblyTable != null) this.SerializeAssemblyTable(writer);
+ if (this.assemblyRefTable != null) this.SerializeAssemblyRefTable(writer);
+ if (this.fileTable != null) this.SerializeFileTable(writer);
+ if (this.exportedTypeTable != null) this.SerializeExportedTypeTable(writer);
+ if (this.manifestResourceTable != null) this.SerializeManifestResourceTable(writer);
+ if (this.nestedClassTable != null) this.SerializeNestedClassTable(writer);
+ if (this.genericParamTable != null) this.SerializeGenericParamTable(writer);
+ if (this.methodSpecTable != null) this.SerializeMethodSpecTable(writer);
+ if (this.genericParamConstraintTable != null) this.SerializeGenericParamConstraintTable(writer);
+ }
+ private void SerializeAssemblyTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.assemblyTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Assembly];
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyRow row = this.assemblyTable[i];
+ writer.Write((int)row.HashAlgId);
+ writer.Write((short)row.MajorVersion);
+ writer.Write((short)row.MinorVersion);
+ writer.Write((short)row.BuildNumber);
+ writer.Write((short)row.RevisionNumber);
+ writer.Write((int)row.Flags);
+ this.WriteReference(writer, row.PublicKey, this.blobRefSize);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Culture, this.stringRefSize);
+ }
+ }
+ private void SerializeAssemblyRefTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.assemblyRefTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.AssemblyRef];
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyRefRow row = this.assemblyRefTable[i];
+ writer.Write((short)row.MajorVersion);
+ writer.Write((short)row.MinorVersion);
+ writer.Write((short)row.BuildNumber);
+ writer.Write((short)row.RevisionNumber);
+ writer.Write((int)row.Flags);
+ this.WriteReference(writer, row.PublicKeyOrToken, this.blobRefSize);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Culture, this.stringRefSize);
+ this.WriteReference(writer, row.HashValue, this.blobRefSize);
+ }
+ }
+ private void SerializeClassLayoutTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.classLayoutTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ClassLayout];
+ for (int i = 0; i < n; i++)
+ {
+ ClassLayoutRow row = this.classLayoutTable[i];
+ writer.Write((short)row.PackingSize);
+ writer.Write((int)row.ClassSize);
+ this.WriteReference(writer, row.Parent, this.tableRefSize[(int)TableIndices.TypeDef]);
+ }
+ }
+ private void SerializeConstantTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.constantTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Constant];
+ for (int i = 0; i < n; i++)
+ {
+ ConstantRow row = this.constantTable[i];
+ writer.Write((byte)row.Type);
+ writer.Write((byte)0);
+ this.WriteReference(writer, row.Parent, this.constantParentRefSize);
+ this.WriteReference(writer, row.Value, this.blobRefSize);
+ }
+ }
+ private void SerializeCustomAttributeTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.customAttributeTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.CustomAttribute];
+ for (int i = 0; i < n; i++)
+ {
+ CustomAttributeRow row = this.customAttributeTable[i];
+ this.WriteReference(writer, row.Parent, this.customAttributeParentRefSize);
+ this.WriteReference(writer, row.Constructor, this.customAttributeConstructorRefSize);
+ this.WriteReference(writer, row.Value, this.blobRefSize);
+ }
+ }
+ private void SerializeDeclSecurityTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.declSecurityTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.DeclSecurity];
+ for (int i = 0; i < n; i++)
+ {
+ DeclSecurityRow row = this.declSecurityTable[i];
+ writer.Write((short)row.Action);
+ this.WriteReference(writer, row.Parent, this.declSecurityParentRefSize);
+ this.WriteReference(writer, row.PermissionSet, this.blobRefSize);
+ }
+ }
+ private void SerializeEventMapTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.eventMapTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.EventMap];
+ for (int i = 0; i < n; i++)
+ {
+ EventMapRow row = this.eventMapTable[i];
+ this.WriteReference(writer, row.Parent, this.tableRefSize[(int)TableIndices.TypeDef]);
+ this.WriteReference(writer, row.EventList, this.tableRefSize[(int)TableIndices.Event]);
+ }
+ }
+ private void SerializeEventTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.eventTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Event];
+ for (int i = 0; i < n; i++)
+ {
+ EventRow row = this.eventTable[i];
+ writer.Write((short)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.EventType, this.typeDefOrRefOrSpecSize);
+ }
+ }
+ private void SerializeExportedTypeTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.exportedTypeTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ExportedType];
+ for (int i = 0; i < n; i++)
+ {
+ ExportedTypeRow row = this.exportedTypeTable[i];
+ writer.Write((int)row.Flags);
+ writer.Write((int)row.TypeDefId);
+ this.WriteReference(writer, row.TypeName, this.stringRefSize);
+ this.WriteReference(writer, row.TypeNamespace, this.stringRefSize);
+ this.WriteReference(writer, row.Implementation, this.implementationRefSize);
+ }
+ }
+ private void SerializeFieldTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.fieldTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Field];
+ for (int i = 0; i < n; i++)
+ {
+ FieldRow row = this.fieldTable[i];
+ writer.Write((short)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ }
+ }
+ private void SerializeFieldLayoutTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.fieldLayoutTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldLayout];
+ for (int i = 0; i < n; i++)
+ {
+ FieldLayoutRow row = this.fieldLayoutTable[i];
+ writer.Write((int)row.Offset);
+ this.WriteReference(writer, row.Field, this.tableRefSize[(int)TableIndices.Field]);
+ }
+ }
+
+ private void SerializeFieldMarshalTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.fieldMarshalTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldMarshal];
+ for (int i = 0; i < n; i++)
+ {
+ FieldMarshalRow row = this.fieldMarshalTable[i];
+ this.WriteReference(writer, row.Parent, this.fieldMarshalParentRefSize);
+ this.WriteReference(writer, row.NativeType, this.blobRefSize);
+ }
+ }
+ private void SerializeFieldRvaTable(BinaryWriter/*!*/ writer, int mbRVAOffset, Fixup/*!*/ sdataFixup, Fixup/*!*/ tlsFixup)
+ //^ requires this.tableSize != null;
+ //^ requires this.fieldRvaTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.FieldRva];
+ for (int i = 0; i < n; i++)
+ {
+ FieldRvaRow row = this.fieldRvaTable[i];
+ switch (row.TargetSection)
+ {
+ case PESection.SData:
+ case PESection.TLS:
+ Fixup fixup = new Fixup();
+ fixup.fixupLocation = writer.BaseStream.Position;
+ fixup.addressOfNextInstruction = row.RVA;
+ if (row.TargetSection == PESection.SData)
+ {
+ sdataFixup.nextFixUp = fixup;
+ sdataFixup = fixup;
+ }
+ else
+ {
+ sdataFixup.nextFixUp = fixup;
+ sdataFixup = fixup;
+ }
+ writer.Write((int)0);
+ break;
+ case PESection.Text:
+ writer.Write((int)row.RVA + mbRVAOffset);
+ break;
+ }
+ this.WriteReference(writer, row.Field, this.tableRefSize[(int)TableIndices.Field]);
+ }
+ }
+ private void SerializeFileTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.fileTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.File];
+ for (int i = 0; i < n; i++)
+ {
+ FileRow row = this.fileTable[i];
+ writer.Write((int)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.HashValue, this.blobRefSize);
+ }
+ }
+ private void SerializeGenericParamTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.genericParamTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.GenericParam];
+ bool reallyOldGenericsFileFormat = TargetPlatform.MajorVersion == 1 && TargetPlatform.MinorVersion == 0;
+ bool oldGenericsFileFormat = TargetPlatform.MajorVersion == 1 && TargetPlatform.MinorVersion == 1;
+ for (int i = 0; i < n; i++)
+ {
+ GenericParamRow row = this.genericParamTable[i];
+ writer.Write((short)row.Number);
+ writer.Write((short)row.Flags);
+ this.WriteReference(writer, row.Owner, this.typeDefOrMethodDefSize);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ if (oldGenericsFileFormat) this.WriteReference(writer, 0, this.typeDefOrRefOrSpecSize);
+ if (reallyOldGenericsFileFormat) writer.Write((short)0);
+ }
+ }
+ private void SerializeGenericParamConstraintTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.genericParamConstraintTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.GenericParamConstraint];
+ for (int i = 0; i < n; i++)
+ {
+ GenericParamConstraintRow row = this.genericParamConstraintTable[i];
+ this.WriteReference(writer, row.Param, this.tableRefSize[(int)TableIndices.GenericParam]);
+ this.WriteReference(writer, row.Constraint, this.typeDefOrRefOrSpecSize);
+ }
+ }
+ private void SerializeImplMapTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.implMapTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ImplMap];
+ for (int i = 0; i < n; i++)
+ {
+ ImplMapRow row = this.implMapTable[i];
+ writer.Write((short)row.MappingFlags);
+ this.WriteReference(writer, row.MemberForwarded, this.memberForwardedRefSize);
+ this.WriteReference(writer, row.ImportName, this.stringRefSize);
+ this.WriteReference(writer, row.ImportScope, this.tableRefSize[(int)TableIndices.ModuleRef]);
+ }
+ }
+ private void SerializeInterfaceImplTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.interfaceImplTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.InterfaceImpl];
+ for (int i = 0; i < n; i++)
+ {
+ InterfaceImplRow row = this.interfaceImplTable[i];
+ this.WriteReference(writer, row.Class, this.tableRefSize[(int)TableIndices.TypeDef]);
+ this.WriteReference(writer, row.Interface, this.typeDefOrRefOrSpecSize);
+ }
+ }
+ private void SerializeManifestResourceTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.manifestResourceTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ManifestResource];
+ for (int i = 0; i < n; i++)
+ {
+ ManifestResourceRow row = this.manifestResourceTable[i];
+ writer.Write((int)row.Offset);
+ writer.Write((int)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Implementation, this.implementationRefSize);
+ }
+ }
+ private void SerializeMemberRefTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.memberRefTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MemberRef];
+ for (int i = 0; i < n; i++)
+ {
+ MemberRefRow row = this.memberRefTable[i];
+ this.WriteReference(writer, row.Class, this.memberRefParentSize);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ }
+ }
+ private void SerializeMethodTable(BinaryWriter/*!*/ writer, int mbRVAOffset)
+ //^ requires this.tableSize != null;
+ //^ requires this.methodTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Method];
+ int pn = this.paramTable == null ? 1 : this.paramTable.Length + 1;
+ for (int i = n - 1; i >= 0; i--)
+ {
+ MethodRow row = this.methodTable[i];
+ if (row.ParamList != 0) pn = row.ParamList; else this.methodTable[i].ParamList = pn;
+ }
+ for (int i = 0; i < n; i++)
+ {
+ MethodRow row = this.methodTable[i];
+ if (row.RVA < 0)
+ writer.Write((int)0);
+ else
+ writer.Write((int)row.RVA + mbRVAOffset);
+ writer.Write((short)row.ImplFlags);
+ writer.Write((short)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ this.WriteReference(writer, row.ParamList, this.tableRefSize[(int)TableIndices.Param]);
+ }
+ }
+ private void SerializeMethodImplTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.methodImplTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodImpl];
+ for (int i = 0; i < n; i++)
+ {
+ MethodImplRow row = this.methodImplTable[i];
+ this.WriteReference(writer, row.Class, this.tableRefSize[(int)TableIndices.TypeDef]);
+ this.WriteReference(writer, row.MethodBody, this.methodDefOrRefSize);
+ this.WriteReference(writer, row.MethodDeclaration, this.methodDefOrRefSize);
+ }
+ }
+ private void SerializeMethodSemanticsTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.methodSemanticsTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodSemantics];
+ for (int i = 0; i < n; i++)
+ {
+ MethodSemanticsRow row = this.methodSemanticsTable[i];
+ writer.Write((short)row.Semantics);
+ this.WriteReference(writer, row.Method, this.tableRefSize[(int)TableIndices.Method]);
+ this.WriteReference(writer, row.Association, this.hasSemanticRefSize);
+ }
+ }
+ private void SerializeMethodSpecTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.assemblyTable != null;
+ //^ requires this.methodSpecTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.MethodSpec];
+ for (int i = 0; i < n; i++)
+ {
+ MethodSpecRow row = this.methodSpecTable[i];
+ this.WriteReference(writer, row.Method, this.methodDefOrRefSize);
+ this.WriteReference(writer, row.Instantiation, this.blobRefSize);
+ }
+ }
+ private void SerializeModuleTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.moduleTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Module];
+ for (int i = 0; i < n; i++)
+ {
+ ModuleRow row = this.moduleTable[i];
+ writer.Write((short)row.Generation);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Mvid, this.guidRefSize);
+ this.WriteReference(writer, row.EncId, this.guidRefSize);
+ this.WriteReference(writer, row.EncBaseId, this.guidRefSize);
+ }
+ }
+ private void SerializeModuleRefTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.moduleRefTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.ModuleRef];
+ for (int i = 0; i < n; i++)
+ {
+ ModuleRefRow row = this.moduleRefTable[i];
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ }
+ }
+ private void SerializeNestedClassTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.nestedClassTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.NestedClass];
+ for (int i = 0; i < n; i++)
+ {
+ NestedClassRow row = this.nestedClassTable[i];
+ this.WriteReference(writer, row.NestedClass, this.tableRefSize[(int)TableIndices.TypeDef]);
+ this.WriteReference(writer, row.EnclosingClass, this.tableRefSize[(int)TableIndices.TypeDef]);
+ }
+ }
+ private void SerializeParamTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.paramTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Param];
+ for (int i = 0; i < n; i++)
+ {
+ ParamRow row = this.paramTable[i];
+ writer.Write((short)row.Flags);
+ writer.Write((short)row.Sequence);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ }
+ }
+ private void SerializePropertyTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.propertyTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.Property];
+ for (int i = 0; i < n; i++)
+ {
+ PropertyRow row = this.propertyTable[i];
+ writer.Write((short)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ }
+ }
+ private void SerializePropertyMapTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.propertyMapTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.PropertyMap];
+ for (int i = 0; i < n; i++)
+ {
+ PropertyMapRow row = this.propertyMapTable[i];
+ this.WriteReference(writer, row.Parent, this.tableRefSize[(int)TableIndices.TypeDef]);
+ this.WriteReference(writer, row.PropertyList, this.tableRefSize[(int)TableIndices.Property]);
+ }
+ }
+ private void SerializeStandAloneSigTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.assemblyTable != null;
+ //^ requires this.standAloneSigTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.StandAloneSig];
+ for (int i = 0; i < n; i++)
+ {
+ StandAloneSigRow row = this.standAloneSigTable[i];
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ }
+ }
+ private void SerializeTypeDefTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.typeDefTable != null;
+ //^ requires this.tableRefSize != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeDef];
+ int fn = this.fieldTable == null ? 1 : this.fieldTable.Length + 1;
+ int mn = this.methodTable == null ? 1 : this.methodTable.Length + 1;
+ for (int i = n - 1; i >= 0; i--)
+ {
+ TypeDefRow row = this.typeDefTable[i];
+ if (row.FieldList != 0) fn = row.FieldList; else this.typeDefTable[i].FieldList = fn;
+ if (row.MethodList != 0) mn = row.MethodList; else this.typeDefTable[i].MethodList = mn;
+ }
+ for (int i = 0; i < n; i++)
+ {
+ TypeDefRow row = this.typeDefTable[i];
+ writer.Write((int)row.Flags);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Namespace, this.stringRefSize);
+ this.WriteReference(writer, row.Extends, this.typeDefOrRefOrSpecSize);
+ this.WriteReference(writer, row.FieldList, this.tableRefSize[(int)TableIndices.Field]);
+ this.WriteReference(writer, row.MethodList, this.tableRefSize[(int)TableIndices.Method]);
+ }
+ }
+ private void SerializeTypeRefTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.typeRefTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeRef];
+ for (int i = 0; i < n; i++)
+ {
+ TypeRefRow row = this.typeRefTable[i];
+ this.WriteReference(writer, row.ResolutionScope, this.resolutionScopeRefSize);
+ this.WriteReference(writer, row.Name, this.stringRefSize);
+ this.WriteReference(writer, row.Namespace, this.stringRefSize);
+ }
+ }
+ private void SerializeTypeSpecTable(BinaryWriter/*!*/ writer)
+ //^ requires this.tableSize != null;
+ //^ requires this.typeSpecTable != null;
+ {
+ int n = this.tableSize[(int)TableIndices.TypeSpec];
+ for (int i = 0; i < n; i++)
+ {
+ TypeSpecRow row = this.typeSpecTable[i];
+ this.WriteReference(writer, row.Signature, this.blobRefSize);
+ }
+ }
+ private int TablesLength()
+ //^ requires this.BlobHeap != null;
+ //^ requires this.GuidHeap != null;
+ //^ requires this.StringHeap != null;
+ {
+ int[] tableSize = this.tableSize = new int[(int)TableIndices.Count];
+ int[] tableRefSize = this.tableRefSize = new int[(int)TableIndices.Count];
+ int tableCount = 0;
+ long validMask = 0;
+ for (int i = 0; i < (int)TableIndices.Count; i++)
+ {
+ int j = 0;
+ switch ((TableIndices)i)
+ {
+ case TableIndices.Module: if (this.moduleTable != null) j = this.moduleTable.Length; break;
+ case TableIndices.TypeRef: if (this.typeRefTable != null) j = this.typeRefTable.Length; break;
+ case TableIndices.TypeDef: if (this.typeDefTable != null) j = this.typeDefTable.Length; break;
+ case TableIndices.Field: if (this.fieldTable != null) j = this.fieldTable.Length; break;
+ case TableIndices.Method: if (this.methodTable != null) j = this.methodTable.Length; break;
+ case TableIndices.Param: if (this.paramTable != null) j = this.paramTable.Length; break;
+ case TableIndices.InterfaceImpl: if (this.interfaceImplTable != null) j = this.interfaceImplTable.Length; break;
+ case TableIndices.MemberRef: if (this.memberRefTable != null) j = this.memberRefTable.Length; break;
+ case TableIndices.Constant: if (this.constantTable != null) j = this.constantTable.Length; break;
+ case TableIndices.CustomAttribute: if (this.customAttributeTable != null) j = this.customAttributeTable.Length; break;
+ case TableIndices.FieldMarshal: if (this.fieldMarshalTable != null) j = this.fieldMarshalTable.Length; break;
+ case TableIndices.DeclSecurity: if (this.declSecurityTable != null) j = this.declSecurityTable.Length; break;
+ case TableIndices.ClassLayout: if (this.classLayoutTable != null) j = this.classLayoutTable.Length; break;
+ case TableIndices.FieldLayout: if (this.fieldLayoutTable != null) j = this.fieldLayoutTable.Length; break;
+ case TableIndices.StandAloneSig: if (this.standAloneSigTable != null) j = this.standAloneSigTable.Length; break;
+ case TableIndices.EventMap: if (this.eventMapTable != null) j = this.eventMapTable.Length; break;
+ case TableIndices.Event: if (this.eventTable != null) j = this.eventTable.Length; break;
+ case TableIndices.PropertyMap: if (this.propertyMapTable != null) j = this.propertyMapTable.Length; break;
+ case TableIndices.Property: if (this.propertyTable != null) j = this.propertyTable.Length; break;
+ case TableIndices.MethodSemantics: if (this.methodSemanticsTable != null) j = this.methodSemanticsTable.Length; break;
+ case TableIndices.MethodImpl: if (this.methodImplTable != null) j = this.methodImplTable.Length; break;
+ case TableIndices.ModuleRef: if (this.moduleRefTable != null) j = this.moduleRefTable.Length; break;
+ case TableIndices.TypeSpec: if (this.typeSpecTable != null) j = this.typeSpecTable.Length; break;
+ case TableIndices.ImplMap: if (this.implMapTable != null) j = this.implMapTable.Length; break;
+ case TableIndices.FieldRva: if (this.fieldRvaTable != null) j = this.fieldRvaTable.Length; break;
+ case TableIndices.Assembly: if (this.assemblyTable != null) j = this.assemblyTable.Length; break;
+ case TableIndices.AssemblyRef: if (this.assemblyRefTable != null) j = this.assemblyRefTable.Length; break;
+ case TableIndices.File: if (this.fileTable != null) j = this.fileTable.Length; break;
+ case TableIndices.ExportedType: if (this.exportedTypeTable != null) j = this.exportedTypeTable.Length; break;
+ case TableIndices.ManifestResource: if (this.manifestResourceTable != null) j = this.manifestResourceTable.Length; break;
+ case TableIndices.NestedClass: if (this.nestedClassTable != null) j = this.nestedClassTable.Length; break;
+ case TableIndices.GenericParam: if (this.genericParamTable != null) j = this.genericParamTable.Length; break;
+ case TableIndices.MethodSpec: if (this.methodSpecTable != null) j = this.methodSpecTable.Length; break;
+ case TableIndices.GenericParamConstraint: if (this.genericParamConstraintTable != null) j = this.genericParamConstraintTable.Length; break;
+ }
+ tableSize[i] = j;
+ if (j > 0)
+ {
+ tableCount++;
+ validMask |= 1L << i;
+ }
+ }
+ this.validMask = validMask;
+
+ for (int i = 0; i < (int)TableIndices.Count; i++)
+ tableRefSize[i] = tableSize[i] < 0x10000 ? 2 : 4;
+ int blobRefSize = this.blobRefSize = this.BlobHeap.Length < 0x10000 ? 2 : 4;
+ int constantParentRefSize = this.constantParentRefSize =
+ tableSize[(int)TableIndices.Param] < 0x4000 &&
+ tableSize[(int)TableIndices.Field] < 0x4000 &&
+ tableSize[(int)TableIndices.Property] < 0x4000 ? 2 : 4;
+ int customAttributeParentRefSize = this.customAttributeParentRefSize =
+ tableSize[(int)TableIndices.Method] < 0x0800 &&
+ tableSize[(int)TableIndices.Field] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeDef] < 0x0800 &&
+ tableSize[(int)TableIndices.Param] < 0x0800 &&
+ tableSize[(int)TableIndices.InterfaceImpl] < 0x0800 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x0800 &&
+ tableSize[(int)TableIndices.Module] < 0x0800 &&
+ tableSize[(int)TableIndices.DeclSecurity] < 0x0800 &&
+ tableSize[(int)TableIndices.Property] < 0x0800 &&
+ tableSize[(int)TableIndices.Event] < 0x0800 &&
+ tableSize[(int)TableIndices.StandAloneSig] < 0x0800 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x0800 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x0800 &&
+ tableSize[(int)TableIndices.Assembly] < 0x0800 &&
+ tableSize[(int)TableIndices.File] < 0x0800 &&
+ tableSize[(int)TableIndices.ExportedType] < 0x0800 &&
+ tableSize[(int)TableIndices.ManifestResource] < 0x0800 &&
+ tableSize[(int)TableIndices.GenericParam] < 0x0800 &&
+ tableSize[(int)TableIndices.MethodSpec] < 0x0800 &&
+ tableSize[(int)TableIndices.GenericParamConstraint] < 0x0800 ? 2 : 4;
+ int customAttributeConstructorRefSize = this.customAttributeConstructorRefSize =
+ tableSize[(int)TableIndices.Method] < 0x2000 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x2000 ? 2 : 4;
+ int declSecurityParentRefSize = this.declSecurityParentRefSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x4000 &&
+ tableSize[(int)TableIndices.Method] < 0x4000 &&
+ tableSize[(int)TableIndices.Assembly] < 0x4000 ? 2 : 4;
+ int fieldMarshalParentRefSize = this.fieldMarshalParentRefSize =
+ tableSize[(int)TableIndices.Field] < 0x8000 &&
+ tableSize[(int)TableIndices.Param] < 0x8000 ? 2 : 4;
+ int guidRefSize = this.guidRefSize = this.GuidHeap.Length < 0x10000 ? 2 : 4;
+ int hasSemanticRefSize = this.hasSemanticRefSize =
+ tableSize[(int)TableIndices.Event] < 0x8000 &&
+ tableSize[(int)TableIndices.Property] < 0x8000 ? 2 : 4;
+ int implementationRefSize = this.implementationRefSize =
+ tableSize[(int)TableIndices.File] < 0x4000 &&
+ tableSize[(int)TableIndices.AssemblyRef] < 0x4000 &&
+ tableSize[(int)TableIndices.ExportedType] < 0x4000 ? 2 : 4;
+ int methodDefOrRefSize = this.methodDefOrRefSize =
+ tableSize[(int)TableIndices.Method] < 0x8000 &&
+ tableSize[(int)TableIndices.MemberRef] < 0x8000 ? 2 : 4;
+ int memberRefParentSize = this.memberRefParentSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x2000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x2000 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x2000 &&
+ tableSize[(int)TableIndices.Method] < 0x2000 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x2000 ? 2 : 4;
+ int memberForwardedRefSize = this.memberForwardedRefSize =
+ tableSize[(int)TableIndices.Field] < 0x8000 &&
+ tableSize[(int)TableIndices.Method] < 0x8000 ? 2 : 4;
+ int typeDefOrMethodDefSize = this.typeDefOrMethodDefSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x8000 &&
+ tableSize[(int)TableIndices.Method] < 0x8000 ? 2 : 4;
+ int typeDefOrRefOrSpecSize = this.typeDefOrRefOrSpecSize =
+ tableSize[(int)TableIndices.TypeDef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeSpec] < 0x4000 ? 2 : 4;
+ int resolutionScopeRefSize = this.resolutionScopeRefSize =
+ tableSize[(int)TableIndices.Module] < 0x4000 &&
+ tableSize[(int)TableIndices.ModuleRef] < 0x4000 &&
+ tableSize[(int)TableIndices.AssemblyRef] < 0x4000 &&
+ tableSize[(int)TableIndices.TypeRef] < 0x4000 ? 2 : 4;
+ int stringRefSize = this.stringRefSize = this.StringHeap.Length < 0x10000 ? 2 : 4;
+
+ int length = 0;
+ for (int i = 0; i < (int)TableIndices.Count; i++)
+ {
+ int m = tableSize[i];
+ if (m == 0) continue;
+ switch ((TableIndices)i)
+ {
+ case TableIndices.Module: length += m * (2 + stringRefSize + 3 * guidRefSize); break;
+ case TableIndices.TypeRef: length += m * (resolutionScopeRefSize + 2 * stringRefSize); break;
+ case TableIndices.TypeDef: length += m * (4 + 2 * stringRefSize + typeDefOrRefOrSpecSize + tableRefSize[(int)TableIndices.Field] + tableRefSize[(int)TableIndices.Method]); break;
+ case TableIndices.Field: length += m * (2 + stringRefSize + blobRefSize); break;
+ case TableIndices.Method: length += m * (8 + stringRefSize + blobRefSize + tableRefSize[(int)TableIndices.Param]); break;
+ case TableIndices.Param: length += m * (4 + stringRefSize); break;
+ case TableIndices.InterfaceImpl: length += m * (tableRefSize[(int)TableIndices.TypeDef] + typeDefOrRefOrSpecSize); break;
+ case TableIndices.MemberRef: length += m * (memberRefParentSize + stringRefSize + blobRefSize); break;
+ case TableIndices.Constant: length += m * (2 + constantParentRefSize + blobRefSize); break;
+ case TableIndices.CustomAttribute: length += m * (customAttributeParentRefSize + customAttributeConstructorRefSize + blobRefSize); break;
+ case TableIndices.FieldMarshal: length += m * (fieldMarshalParentRefSize + blobRefSize); break;
+ case TableIndices.DeclSecurity: length += m * (2 + declSecurityParentRefSize + blobRefSize); break;
+ case TableIndices.ClassLayout: length += m * (6 + tableRefSize[(int)TableIndices.TypeDef]); break;
+ case TableIndices.FieldLayout: length += m * (4 + tableRefSize[(int)TableIndices.Field]); break;
+ case TableIndices.StandAloneSig: length += m * (blobRefSize); break;
+ case TableIndices.EventMap: length += m * (tableRefSize[(int)TableIndices.TypeDef] + tableRefSize[(int)TableIndices.Event]); break;
+ case TableIndices.Event: length += m * (2 + stringRefSize + typeDefOrRefOrSpecSize); break;
+ case TableIndices.PropertyMap: length += m * (tableRefSize[(int)TableIndices.TypeDef] + tableRefSize[(int)TableIndices.Property]); break;
+ case TableIndices.Property: length += m * (2 + stringRefSize + blobRefSize); break;
+ case TableIndices.MethodSemantics: length += m * (2 + tableRefSize[(int)TableIndices.Method] + hasSemanticRefSize); break;
+ case TableIndices.MethodImpl: length += m * (tableRefSize[(int)TableIndices.TypeDef] + 2 * methodDefOrRefSize); break;
+ case TableIndices.ModuleRef: length += m * (stringRefSize); break;
+ case TableIndices.TypeSpec: length += m * (blobRefSize); break;
+ case TableIndices.ImplMap: length += m * (2 + memberForwardedRefSize + stringRefSize + tableRefSize[(int)TableIndices.ModuleRef]); break;
+ case TableIndices.FieldRva: length += m * (4 + tableRefSize[(int)TableIndices.Field]); break;
+ case TableIndices.EncLog: throw new InvalidMetadataException(ExceptionStrings.ENCLogTableEncountered);
+ case TableIndices.EncMap: throw new InvalidMetadataException(ExceptionStrings.ENCMapTableEncountered);
+ case TableIndices.Assembly: length += m * (16 + blobRefSize + 2 * stringRefSize); break;
+ case TableIndices.AssemblyRef: length += m * (12 + 2 * blobRefSize + 2 * stringRefSize); break;
+ case TableIndices.File: length += m * (4 + stringRefSize + blobRefSize); break;
+ case TableIndices.ExportedType: length += m * (8 + 2 * stringRefSize + implementationRefSize); break;
+ case TableIndices.ManifestResource: length += m * (8 + stringRefSize + implementationRefSize); break;
+ case TableIndices.NestedClass: length += m * (2 * tableRefSize[(int)TableIndices.TypeDef]); break;
+ case TableIndices.GenericParam:
+ if (TargetPlatform.MajorVersion == 1 && TargetPlatform.MinorVersion == 0)
+ length += m * (6 + typeDefOrMethodDefSize + stringRefSize + typeDefOrRefOrSpecSize);
+ else if (TargetPlatform.MajorVersion == 1 && TargetPlatform.MinorVersion == 1)
+ length += m * (4 + typeDefOrMethodDefSize + stringRefSize + typeDefOrRefOrSpecSize);
+ else
+ length += m * (4 + typeDefOrMethodDefSize + stringRefSize);
+ break;
+ case TableIndices.MethodSpec: length += m * (methodDefOrRefSize + blobRefSize); break;
+ case TableIndices.GenericParamConstraint: length += m * (tableRefSize[(int)TableIndices.GenericParam] + typeDefOrRefOrSpecSize); break;
+ }
+ }
+ length += 24 + (tableCount * 4);
+ return length;
+ }
+
+ private NTHeader/*!*/ ntHeader = new NTHeader();
+ private CLIHeader/*!*/ cliHeader = new CLIHeader();
+ private SectionHeader[] sectionHeaders;
+
+ internal void WritePE(BinaryWriter/*!*/ writer)
+ //^ requires this.SdataHeap != null;
+ //^ requires this.TlsHeap != null;
+ {
+ this.cliHeader.entryPointToken = this.entryPointToken;
+ switch (this.moduleKind)
+ {
+ case ModuleKindFlags.ConsoleApplication:
+ this.ntHeader.subsystem = 3;
+ break;
+ case ModuleKindFlags.DynamicallyLinkedLibrary:
+ this.ntHeader.characteristics |= 0x2000;
+ this.ntHeader.subsystem = 3;
+ break;
+ case ModuleKindFlags.WindowsApplication:
+ this.ntHeader.subsystem = 2;
+ break;
+ }
+ int numSectionHeaders = 2;
+ if (this.SdataHeap.Length > 0) numSectionHeaders++;
+ if (this.TlsHeap.Length > 0) numSectionHeaders++;
+ if (this.Win32Resources != null && this.Win32Resources.Count > 0) numSectionHeaders++;
+ this.sectionHeaders = new SectionHeader[numSectionHeaders];
+ this.ntHeader.numberOfSections = (ushort)numSectionHeaders;
+ this.ntHeader.timeDateStamp = (int)((DateTime.Now.ToUniversalTime() - NineteenSeventy).TotalSeconds);
+
+ //Write out .text section for meta data tables, method bodies, address tables and entry point stub
+ Fixup sdataFixup = new Fixup();
+ Fixup tlsFixup = new Fixup();
+ SectionHeader textSection = new SectionHeader();
+ textSection.name = ".text";
+ textSection.virtualAddress = 8192;
+ int sizeOfPeHeaders = 376 + 40 * numSectionHeaders;
+ textSection.pointerToRawData = ((int)Math.Ceiling(sizeOfPeHeaders / (double)this.fileAlignment)) * this.fileAlignment;
+ textSection.characteristics = 0x60000020;
+ writer.BaseStream.Position = textSection.pointerToRawData + 72; //Leave 72 bytes for CLI header
+ this.SerializeMetadata(writer, textSection.virtualAddress, sdataFixup, tlsFixup);
+ int RVAofEntryPointJumpTarget = this.WriteImportTableAndEntryPointStub(writer, ref textSection);
+#if !ROTOR
+ if (this.symWriter != null) this.WriteReferenceToPDBFile(writer, textSection.virtualAddress, textSection.pointerToRawData);
+#endif
+ int len = textSection.virtualSize = ((int)writer.BaseStream.Position) - textSection.pointerToRawData;
+ textSection.sizeOfRawData = ((int)Math.Ceiling(len / (double)this.fileAlignment)) * this.fileAlignment;
+ this.sectionHeaders[0] = textSection;
+ writer.BaseStream.Position = textSection.pointerToRawData;
+ this.ntHeader.cliHeaderTable.virtualAddress = textSection.virtualAddress;
+ this.ntHeader.cliHeaderTable.size = 72;
+ WriteCLIHeader(writer); //Write CLI header last so that forward pointers can be filled in first
+
+ int sectionHeaderIndex = 1;
+ SectionHeader previousSection = textSection;
+ int n = this.ntHeader.sectionAlignment;
+ int m = this.fileAlignment;
+
+ if (this.SdataHeap.Length > 0)
+ {
+ SectionHeader sdataSection = new SectionHeader();
+ sdataSection.name = ".sdata";
+ int vaddr = sdataSection.virtualAddress = previousSection.virtualAddress + n * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)n);
+ sdataSection.virtualSize = this.SdataHeap.Length;
+ sdataSection.pointerToRawData = previousSection.pointerToRawData + m * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)m);
+ sdataSection.characteristics = unchecked((int)0xC0000040);
+ writer.BaseStream.Position = sdataSection.pointerToRawData;
+ this.SdataHeap.WriteTo(writer.BaseStream);
+ len = sdataSection.virtualSize = ((int)writer.BaseStream.Position) - sdataSection.pointerToRawData;
+ writer.BaseStream.Position += m - (len % this.fileAlignment) - 1;
+ writer.Write((byte)0);
+ sdataSection.sizeOfRawData = ((int)Math.Ceiling(len / (double)this.fileAlignment)) * this.fileAlignment;
+ sdataFixup = sdataFixup.nextFixUp; //Skip over dummy header
+ while (sdataFixup != null)
+ {
+ writer.BaseStream.Position = sdataFixup.fixupLocation;
+ writer.Write((int)(vaddr + sdataFixup.addressOfNextInstruction));
+ sdataFixup = sdataFixup.nextFixUp;
+ }
+ this.sectionHeaders[sectionHeaderIndex++] = sdataSection;
+ previousSection = sdataSection;
+ }
+
+ if (this.TlsHeap.Length > 0)
+ {
+ SectionHeader tlsSection = new SectionHeader();
+ tlsSection.name = ".tls";
+ int vaddr = tlsSection.virtualAddress = previousSection.virtualAddress + n * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)n);
+ tlsSection.virtualSize = this.SdataHeap.Length;
+ tlsSection.pointerToRawData = previousSection.pointerToRawData + m * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)m);
+ tlsSection.characteristics = unchecked((int)0xC0000040);
+ writer.BaseStream.Position = tlsSection.pointerToRawData;
+ this.TlsHeap.WriteTo(writer.BaseStream);
+ len = tlsSection.virtualSize = ((int)writer.BaseStream.Position) - tlsSection.pointerToRawData;
+ writer.BaseStream.Position += m - (len % this.fileAlignment) - 1;
+ writer.Write((byte)0);
+ tlsSection.sizeOfRawData = ((int)Math.Ceiling(len / (double)this.fileAlignment)) * this.fileAlignment;
+ tlsFixup = tlsFixup.nextFixUp; //Skip over dummy header
+ while (tlsFixup != null)
+ {
+ writer.BaseStream.Position = tlsFixup.fixupLocation;
+ writer.Write((int)(vaddr + tlsFixup.addressOfNextInstruction));
+ tlsFixup = tlsFixup.nextFixUp;
+ }
+ this.sectionHeaders[sectionHeaderIndex++] = tlsSection;
+ previousSection = tlsSection;
+ }
+
+ if (this.Win32Resources != null && this.Win32Resources.Count > 0)
+ {
+ SectionHeader rsrcSection = new SectionHeader();
+ rsrcSection.name = ".rsrc";
+ rsrcSection.virtualAddress = previousSection.virtualAddress + n * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)n);
+ rsrcSection.pointerToRawData = previousSection.pointerToRawData + m * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)m);
+ rsrcSection.characteristics = 0x40000040;
+ writer.BaseStream.Position = rsrcSection.pointerToRawData;
+ this.WriteWin32Resources(writer, rsrcSection.virtualAddress);
+ len = rsrcSection.virtualSize = ((int)writer.BaseStream.Position) - rsrcSection.pointerToRawData;
+ writer.BaseStream.Position += m - (len % this.fileAlignment) - 1;
+ writer.Write((byte)0);
+ rsrcSection.sizeOfRawData = ((int)Math.Ceiling(len / (double)this.fileAlignment)) * this.fileAlignment;
+ this.sectionHeaders[sectionHeaderIndex++] = rsrcSection;
+ this.ntHeader.resourceTable.virtualAddress = rsrcSection.virtualAddress;
+ this.ntHeader.resourceTable.size = rsrcSection.virtualSize;
+ this.ntHeader.sizeOfInitializedData += rsrcSection.sizeOfRawData;
+ previousSection = rsrcSection;
+ }
+
+ //Write out .reloc section for entry point stub relocation table
+ SectionHeader relocSection = new SectionHeader();
+ relocSection.name = ".reloc";
+ relocSection.virtualAddress = previousSection.virtualAddress + n * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)n);
+ relocSection.virtualSize = 12;
+ relocSection.pointerToRawData = previousSection.pointerToRawData + m * (int)Math.Ceiling(previousSection.sizeOfRawData / (double)m);
+ relocSection.sizeOfRawData = m;
+ relocSection.characteristics = 0x42000040;
+ writer.BaseStream.Position = relocSection.pointerToRawData;
+ writer.Write((int)((RVAofEntryPointJumpTarget / 4096) * 4096)); //Page RVA
+ writer.Write((int)12);
+ int offsetWithinPage = RVAofEntryPointJumpTarget % 4096;
+ short s = (short)(3 << 12 | offsetWithinPage);
+ writer.Write(s);
+ writer.Write((short)0); //next chunk's RVA
+ writer.BaseStream.Position += m - 13;
+ writer.Write((byte)0);
+ this.sectionHeaders[sectionHeaderIndex] = relocSection;
+ this.ntHeader.baseRelocationTable.virtualAddress = relocSection.virtualAddress;
+ this.ntHeader.baseRelocationTable.size = relocSection.virtualSize;
+ this.ntHeader.sizeOfInitializedData += relocSection.sizeOfRawData;
+
+ //Write PE headers. Do this last because forward pointers are filled in by preceding code
+ writer.BaseStream.Position = 0;
+ writer.Write(dosHeader);
+ WriteNTHeader(writer);
+ WriteSectionHeaders(writer);
+ }
+ private class Directory
+ {
+ internal string Name;
+ internal int ID;
+ internal int NumberOfNamedEntries;
+ internal int NumberOfIdEntries;
+ internal ArrayList/*!*/ Entries;
+ internal Directory(string Name, int ID)
+ {
+ this.Name = Name;
+ this.ID = ID;
+ this.Entries = new ArrayList();
+ //^ base();
+ }
+ }
+ private void WriteWin32Resources(BinaryWriter/*!*/ writer, int virtualAddressBase)
+ //^ requires this.Win32Resources != null;
+ {
+ Win32ResourceList rsrcs = this.Win32Resources;
+ BinaryWriter dataHeap = new BinaryWriter(new MemoryStream(), System.Text.Encoding.Unicode);
+ //Construct a tree of array lists to represent the directory and make it easier to compute offsets
+ Directory TypeDirectory = new Directory("", 0);
+ Directory NameDirectory = null;
+ Directory LanguageDirectory = null;
+ int lastTypeID = int.MinValue;
+ string lastTypeName = null;
+ int lastID = int.MinValue;
+ string lastName = null;
+ int sizeOfDirectoryTree = 16;
+ for (int i = 0, n = rsrcs.Count; i < n; i++)
+ {
+ Win32Resource r = rsrcs[i];
+ bool typeDifferent = (r.TypeId < 0 && r.TypeName != lastTypeName) || r.TypeId > lastTypeID;
+ if (typeDifferent)
+ {
+ lastTypeID = r.TypeId;
+ lastTypeName = r.TypeName;
+ if (lastTypeID < 0) TypeDirectory.NumberOfNamedEntries++; else TypeDirectory.NumberOfIdEntries++;
+ sizeOfDirectoryTree += 24;
+ TypeDirectory.Entries.Add(NameDirectory = new Directory(lastTypeName, lastTypeID));
+ }
+ //^ assume NameDirectory != null;
+ if (typeDifferent || (r.Id < 0 && r.Name != lastName) || r.Id > lastID)
+ {
+ lastID = r.Id;
+ lastName = r.Name;
+ if (lastID < 0) NameDirectory.NumberOfNamedEntries++; else NameDirectory.NumberOfIdEntries++;
+ sizeOfDirectoryTree += 24;
+ NameDirectory.Entries.Add(LanguageDirectory = new Directory(lastName, lastID));
+ }
+ //^ assume LanguageDirectory != null;
+ LanguageDirectory.NumberOfIdEntries++;
+ sizeOfDirectoryTree += 8;
+ LanguageDirectory.Entries.Add(r);
+ continue;
+ }
+ this.WriteDirectory(TypeDirectory, writer, 0, 0, sizeOfDirectoryTree, virtualAddressBase, dataHeap);
+ dataHeap.BaseStream.WriteTo(writer.BaseStream);
+ }
+ private void WriteDirectory(Directory/*!*/ directory, BinaryWriter/*!*/ writer, int offset, int level, int sizeOfDirectoryTree,
+ int virtualAddressBase, BinaryWriter/*!*/ dataHeap)
+ {
+ writer.Write((int)0); //Characteristics
+ writer.Write((int)0); //Timestamp
+ writer.Write((int)0); //Version
+ writer.Write((short)directory.NumberOfNamedEntries);
+ writer.Write((short)directory.NumberOfIdEntries);
+ int n = directory.Entries.Count;
+ int k = offset + 16 + n * 8;
+ for (int i = 0; i < n; i++)
+ {
+ int id = int.MinValue;
+ string name = null;
+ int nOff = dataHeap.BaseStream.Position + sizeOfDirectoryTree;
+ int dOff = k;
+ Directory subDir = directory.Entries[i] as Directory;
+ if (subDir != null)
+ {
+ id = subDir.ID;
+ name = subDir.Name;
+ if (level == 0)
+ k += this.SizeOfDirectory(subDir);
+ else
+ k += 16 + 8 * subDir.Entries.Count;
+ }
+ else
+ {
+ Win32Resource r = (Win32Resource)directory.Entries[i];
+ id = level == 0 ? r.TypeId : level == 1 ? r.Id : r.LanguageId;
+ name = level == 0 ? r.TypeName : level == 1 ? r.Name : null;
+ dataHeap.Write((int)(virtualAddressBase + sizeOfDirectoryTree + 16 + dataHeap.BaseStream.Position));
+ dataHeap.Write((int)r.Data.Length);
+ dataHeap.Write((int)r.CodePage);
+ dataHeap.Write((int)0);
+ dataHeap.Write(r.Data);
+ }
+ if (id >= 0)
+ writer.Write(id);
+ else
+ {
+ if (name == null) name = "";
+ writer.Write(((uint)nOff) | 0x80000000);
+ dataHeap.Write((ushort)name.Length);
+ dataHeap.Write(name.ToCharArray()); //REVIEW: what happens if the name contains chars that do not fit into a single utf8 code point?
+ }
+ if (subDir != null)
+ writer.Write(((uint)dOff) | 0x80000000);
+ else
+ writer.Write(nOff);
+ }
+ k = offset + 16 + n * 8;
+ for (int i = 0; i < n; i++)
+ {
+ Directory subDir = directory.Entries[i] as Directory;
+ if (subDir != null)
+ {
+ this.WriteDirectory(subDir, writer, k, level + 1, sizeOfDirectoryTree, virtualAddressBase, dataHeap);
+ if (level == 0)
+ k += this.SizeOfDirectory(subDir);
+ else
+ k += 16 + 8 * subDir.Entries.Count;
+ }
+ }
+ }
+ private int SizeOfDirectory(Directory/*!*/ directory)
+ {
+ int n = directory.Entries.Count;
+ int size = 16 + 8 * n;
+ for (int i = 0; i < n; i++)
+ {
+ Directory subDir = directory.Entries[i] as Directory;
+ if (subDir != null)
+ size += 16 + 8 * subDir.Entries.Count;
+ }
+ return size;
+ }
+ private static readonly byte[] dosHeader = new byte[]{
+ 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+ 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
+ 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
+ 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
+ 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
+ 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e,
+ 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
+ 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ static readonly DateTime NineteenSeventy = new DateTime(1970, 1, 1).ToUniversalTime();
+ private void WriteNTHeader(BinaryWriter/*!*/ writer)
+ //^ requires this.sectionHeaders != null;
+ {
+ NTHeader ntHeader = this.ntHeader;
+ writer.Write(ntHeader.signature);
+ if ((this.peKind & PEKindFlags.Requires64bits) == 0)
+ {
+ ntHeader.magic = 0x10B; //PE32
+ ntHeader.machine = 0x014c; //I386
+ }
+ else
+ {
+ ntHeader.characteristics &= 0xFEFF; //Not 32-bit
+ ntHeader.characteristics |= 0x0020; //Can handle >2gb addresses
+ ntHeader.magic = 0x20B; //PE32+
+ if ((this.peKind & PEKindFlags.AMD) != 0)
+ ntHeader.machine = 0x8664; //AMD64
+ else
+ ntHeader.machine = 0x0200; //IA64
+ ntHeader.sizeOfOptionalHeader += 16;
+ }
+ writer.Write(ntHeader.machine);
+ writer.Write(ntHeader.numberOfSections);
+ writer.Write(ntHeader.timeDateStamp);
+ writer.Write(ntHeader.pointerToSymbolTable);
+ writer.Write(ntHeader.numberOfSymbols);
+ writer.Write(ntHeader.sizeOfOptionalHeader);
+ writer.Write(ntHeader.characteristics);
+ writer.Write(ntHeader.magic);
+ writer.Write((byte)TargetPlatform.LinkerMajorVersion);
+ writer.Write((byte)TargetPlatform.LinkerMinorVersion);
+ writer.Write(this.sectionHeaders[0].sizeOfRawData); //sizeOfCode
+ writer.Write(ntHeader.sizeOfInitializedData);
+ writer.Write(ntHeader.sizeOfUninitializedData);
+ writer.Write(ntHeader.addressOfEntryPoint);
+ writer.Write(this.sectionHeaders[0].virtualAddress); //baseOfCode
+ if (ntHeader.magic == 0x10B)
+ {
+ if (this.sectionHeaders.Length > 1)
+ writer.Write(this.sectionHeaders[1].virtualAddress); //baseOfData
+ else
+ writer.Write((int)0);
+ writer.Write((int)ntHeader.imageBase);
+ }
+ else
+ {
+ writer.Write(ntHeader.imageBase);
+ }
+ writer.Write(ntHeader.sectionAlignment);
+ writer.Write(this.fileAlignment);
+ writer.Write(ntHeader.majorOperatingSystemVersion);
+ writer.Write(ntHeader.minorOperatingSystemVersion);
+ writer.Write(ntHeader.majorImageVersion);
+ writer.Write(ntHeader.minorImageVersion);
+ writer.Write(ntHeader.majorSubsystemVersion);
+ writer.Write(ntHeader.minorSubsystemVersion);
+ writer.Write(ntHeader.win32VersionValue);
+ int sectionPages = (int)(Math.Ceiling(this.sectionHeaders[this.sectionHeaders.Length - 1].virtualSize /
+ (double)ntHeader.sectionAlignment) * ntHeader.sectionAlignment);
+ writer.Write(this.sectionHeaders[this.sectionHeaders.Length - 1].virtualAddress + sectionPages); //sizeOfImage
+ writer.Write(this.sectionHeaders[0].pointerToRawData); //sizeOfHeaders
+ writer.Write(ntHeader.checkSum);
+ writer.Write(ntHeader.subsystem);
+ writer.Write(ntHeader.dllCharacteristics);
+ if (ntHeader.magic == 0x10B)
+ {
+ writer.Write((int)ntHeader.sizeOfStackReserve);
+ writer.Write((int)ntHeader.sizeOfStackCommit);
+ writer.Write((int)ntHeader.sizeOfHeapReserve);
+ writer.Write((int)ntHeader.sizeOfHeapCommit);
+ }
+ else
+ {
+ writer.Write(ntHeader.sizeOfStackReserve);
+ writer.Write(ntHeader.sizeOfStackCommit);
+ writer.Write(ntHeader.sizeOfHeapReserve);
+ writer.Write(ntHeader.sizeOfHeapCommit);
+ }
+ writer.Write(ntHeader.loaderFlags);
+ writer.Write(ntHeader.numberOfDataDirectories);
+ writer.Write(ntHeader.exportTable.virtualAddress);
+ writer.Write(ntHeader.exportTable.size);
+ writer.Write(ntHeader.importTable.virtualAddress);
+ writer.Write(ntHeader.importTable.size);
+ writer.Write(ntHeader.resourceTable.virtualAddress);
+ writer.Write(ntHeader.resourceTable.size);
+ writer.Write(ntHeader.exceptionTable.virtualAddress);
+ writer.Write(ntHeader.exceptionTable.size);
+ writer.Write(ntHeader.certificateTable.virtualAddress);
+ writer.Write(ntHeader.certificateTable.size);
+ writer.Write(ntHeader.baseRelocationTable.virtualAddress);
+ writer.Write(ntHeader.baseRelocationTable.size);
+ writer.Write(ntHeader.debugTable.virtualAddress);
+ writer.Write(ntHeader.debugTable.size);
+ writer.Write(ntHeader.copyrightTable.virtualAddress);
+ writer.Write(ntHeader.copyrightTable.size);
+ writer.Write(ntHeader.globalPointerTable.virtualAddress);
+ writer.Write(ntHeader.globalPointerTable.size);
+ writer.Write(ntHeader.threadLocalStorageTable.virtualAddress);
+ writer.Write(ntHeader.threadLocalStorageTable.size);
+ writer.Write(ntHeader.loadConfigTable.virtualAddress);
+ writer.Write(ntHeader.loadConfigTable.size);
+ writer.Write(ntHeader.boundImportTable.virtualAddress);
+ writer.Write(ntHeader.boundImportTable.size);
+ writer.Write(ntHeader.importAddressTable.virtualAddress);
+ writer.Write(ntHeader.importAddressTable.size);
+ writer.Write(ntHeader.delayImportTable.virtualAddress);
+ writer.Write(ntHeader.delayImportTable.size);
+ writer.Write(ntHeader.cliHeaderTable.virtualAddress);
+ writer.Write(ntHeader.cliHeaderTable.size);
+ writer.Write((long)0);
+ }
+ private void WriteSectionHeaders(BinaryWriter/*!*/ writer)
+ //^ requires this.sectionHeaders != null;
+ {
+ SectionHeader[] sectionHeaders = this.sectionHeaders;
+ for (int i = 0, n = this.sectionHeaders.Length; i < n; i++)
+ {
+ SectionHeader hdr = sectionHeaders[i];
+ //^ assume hdr.name != null;
+ for (int j = 0, m = hdr.name.Length; j < 8; j++)
+ if (j < m) writer.Write(hdr.name[j]); else writer.Write((byte)0);
+ writer.Write(hdr.virtualSize);
+ writer.Write(hdr.virtualAddress);
+ writer.Write(hdr.sizeOfRawData);
+ writer.Write(hdr.pointerToRawData);
+ writer.Write(hdr.pointerToRelocations);
+ writer.Write(hdr.pointerToLinenumbers);
+ writer.Write(hdr.numberOfRelocations);
+ writer.Write(hdr.numberOfLinenumbers);
+ writer.Write(hdr.characteristics);
+ }
+ }
+ private void WriteCLIHeader(BinaryWriter/*!*/ writer)
+ {
+ CLIHeader hdr = this.cliHeader;
+ writer.Write(hdr.cb);
+ writer.Write((ushort)2);
+ if (this.UseGenerics)
+ writer.Write((ushort)5); //Violates the ECMA standard (25.3.3 of Partition II), but apparently necessary
+ else
+ writer.Write((ushort)0);
+ writer.Write(hdr.metaData.virtualAddress);
+ writer.Write(hdr.metaData.size);
+ if ((this.peKind & PEKindFlags.Requires32bits) != 0) hdr.flags |= 2;
+ if ((this.peKind & PEKindFlags.ILonly) != 0) hdr.flags |= 1;
+ if (this.TrackDebugData) hdr.flags |= 0x10000;
+ writer.Write(hdr.flags);
+ writer.Write(hdr.entryPointToken);
+ writer.Write(hdr.resources.virtualAddress);
+ writer.Write(hdr.resources.size);
+ writer.Write(hdr.strongNameSignature.virtualAddress);
+ writer.Write(hdr.strongNameSignature.size);
+ writer.Write(hdr.codeManagerTable.virtualAddress);
+ writer.Write(hdr.codeManagerTable.size);
+ writer.Write(hdr.vtableFixups.virtualAddress);
+ writer.Write(hdr.vtableFixups.size);
+ }
+ private int WriteImportTableAndEntryPointStub(BinaryWriter/*!*/ writer, ref SectionHeader textSection)
+ {
+ bool use32bitAddresses = (this.peKind & PEKindFlags.Requires64bits) == 0;
+ int pos = (int)writer.BaseStream.Position;
+ while (pos % 4 != 0) { pos++; writer.Write((byte)0); }
+ int ITrva = textSection.virtualAddress + pos - textSection.pointerToRawData;
+ int ITLrva = ITrva + 40;
+ int rvasize = 12; // size of relocation sections
+ int hintRva = ITLrva + (use32bitAddresses ? 8 : 16); //position of name of entry point in runtime dll
+ int nameRva = hintRva + 14; // position of name of runtime dll
+ int ITArva = nameRva + 14 + // size of name of runtime dll
+ 4 + // size of entry point code 0000ff25
+ rvasize; // size of relocation fixup
+
+ this.ntHeader.addressOfEntryPoint = ITArva - rvasize - 2;
+ this.ntHeader.importTable.virtualAddress = ITrva;
+ this.ntHeader.importTable.size = this.ntHeader.addressOfEntryPoint - ITrva - 2;
+ this.ntHeader.importAddressTable.virtualAddress = ITArva;
+ this.ntHeader.importAddressTable.size = 8;
+ //Import table
+ writer.Write((int)ITLrva);
+ writer.Write((int)0);
+ writer.Write((int)0);
+ writer.Write((int)nameRva);
+ writer.Write((int)ITArva);
+ writer.BaseStream.Position += 20;
+ //Import Lookup table
+ if (use32bitAddresses)
+ {
+ writer.Write((int)hintRva);
+ writer.Write((int)0);
+ }
+ else
+ {
+ writer.Write((long)hintRva);
+ writer.Write((long)0);
+ }
+ //Hint table
+ writer.Write((short)0); //Hint
+ string entryPointName = this.moduleKind == ModuleKindFlags.DynamicallyLinkedLibrary ? "_CorDllMain" : "_CorExeMain";
+ foreach (char ch in entryPointName.ToCharArray()) writer.Write((byte)ch);
+ writer.Write((byte)0);
+ //name of CLR runtime dll
+ foreach (char ch in "mscoree.dll".ToCharArray()) writer.Write((byte)ch);
+ writer.Write((byte)0);
+ writer.Write((short)0);
+ //entry point code, consisting of a jump indirect to _CorXXXMain
+ writer.Write((short)0); //padding so that address to replace is on a word boundary
+ writer.Write((byte)0xff);
+ writer.Write((byte)0x25);
+ writer.Write((int)ITArva + (int)this.ntHeader.imageBase); //REVIEW: is this OK for 64 bit?
+ writer.Write((int)0); // relocation fixup must be 12 bytes.
+ writer.Write((int)0);
+ //Import Address Table
+ if (use32bitAddresses)
+ {
+ writer.Write((int)hintRva);
+ writer.Write((int)0);
+ }
+ else
+ {
+ writer.Write((long)hintRva);
+ writer.Write((long)0);
+ }
+ //Return RVA of the target address of the indirect jump at the entry point
+ return ITArva - rvasize;
+ }
+ private void WriteReference(BinaryWriter/*!*/ writer, int index, int refSize)
+ {
+ if (refSize == 2) writer.Write((short)index); else writer.Write(index);
+ }
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/Nodes.cs b/tools/Sandcastle/Source/CCI/Nodes.cs
new file mode 100644
index 0000000..dd251b3
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Nodes.cs
@@ -0,0 +1,21996 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Collections.Specialized;
+#if FxCop
+using AssemblyReferenceList = Microsoft.Cci.AssemblyReferenceCollection;
+using AttributeList = Microsoft.Cci.AttributeNodeCollection;
+using BlockList = Microsoft.Cci.BlockCollection;
+using ExpressionList = Microsoft.Cci.ExpressionCollection;
+using InstructionList = Microsoft.Cci.InstructionCollection;
+using Int32List = System.Collections.Generic.List<int>;
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using MemberList = Microsoft.Cci.MemberCollection;
+using MethodList = Microsoft.Cci.MethodCollection;
+using ModuleReferenceList = Microsoft.Cci.ModuleReferenceCollection;
+using NamespaceList = Microsoft.Cci.NamespaceCollection;
+using ParameterList = Microsoft.Cci.ParameterCollection;
+using ResourceList = Microsoft.Cci.ResourceCollection;
+using SecurityAttributeList = Microsoft.Cci.SecurityAttributeCollection;
+using StatementList = Microsoft.Cci.StatementCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Win32ResourceList = Microsoft.Cci.Win32ResourceCollection;
+using Module = Microsoft.Cci.ModuleNode;
+using Class = Microsoft.Cci.ClassNode;
+using Interface = Microsoft.Cci.InterfaceNode;
+using Property = Microsoft.Cci.PropertyNode;
+using Event = Microsoft.Cci.EventNode;
+using Return = Microsoft.Cci.ReturnNode;
+using Throw = Microsoft.Cci.ThrowNode;
+#endif
+#if UseSingularityPDB
+using Microsoft.Singularity.PdbInfo;
+#endif
+#if CCINamespace
+using Cci = Microsoft.Cci;
+using Microsoft.Cci.Metadata;
+using Metadata = Microsoft.Cci.Metadata;
+#else
+using Cci = System.Compiler;
+using System.Compiler.Metadata;
+using Metadata = System.Compiler.Metadata;
+#endif
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+#if !NoXml
+using System.Xml;
+#endif
+
+using BindingFlags = System.Reflection.BindingFlags;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !FxCop
+ /// <summary>
+ /// This interface can be used to link an arbitrary source text provider into an IR tree via a DocumentText instance.
+ /// </summary>
+ public interface ISourceText
+ {
+ /// <summary>
+ /// The number of characters in the source text.
+ /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
+ /// </summary>
+ int Length { get; }
+ /// <summary>
+ /// Retrieves a substring from this instance. The substring starts with the character at the specified index and has a specified length.
+ /// </summary>
+ string Substring(int startIndex, int length);
+ /// <summary>
+ /// Retrieves the character at the given position. The first character is at position zero.
+ /// </summary>
+ char this[int position] { get; }
+ /// <summary>
+ /// Indicates that the text has been fully scanned and futher references to the text are expected to be infrequent.
+ /// The underlying object can now choose to clear cached information if it comes under resource pressure.
+ /// </summary>
+ void MakeCollectible();
+ }
+ public unsafe interface ISourceTextBuffer : ISourceText
+ {
+ /// <summary>
+ /// Returns null unless the implementer is based on an ASCII buffer that stays alive as long at the implementer itself.
+ /// An implementer that returns a non-null value is merely a wrapper to keep the buffer alive. No further methods will
+ /// be called on the interface in this case.
+ /// </summary>
+ byte* Buffer { get; }
+ }
+#endif
+#if !MinimalReader
+ /// <summary>
+ /// Use this after a source text has already been scanned and parsed. This allows the source text to get released
+ /// if there is memory pressure, while still allowing portions of it to be retrieved on demand. This is useful when
+ /// a large number of source files are read in, but only infrequent references are made to them.
+ /// </summary>
+ public sealed class CollectibleSourceText : ISourceText
+ {
+ private string/*!*/ filePath;
+ private WeakReference/*!*/ fileContent;
+ private int length;
+
+ public CollectibleSourceText(string/*!*/ filePath, int length)
+ {
+ this.filePath = filePath;
+ this.fileContent = new WeakReference(null);
+ this.length = length;
+ //^ base();
+ }
+ public CollectibleSourceText(string/*!*/ filePath, string fileContent)
+ {
+ this.filePath = filePath;
+ this.fileContent = new WeakReference(fileContent);
+ this.length = fileContent == null ? 0 : fileContent.Length;
+ //^ base();
+ }
+ private string/*!*/ ReadFile()
+ {
+ string content = string.Empty;
+ try
+ {
+ StreamReader sr = new StreamReader(filePath);
+ content = sr.ReadToEnd();
+ this.length = content.Length;
+ sr.Close();
+ }
+ catch { }
+ return content;
+ }
+ public string/*!*/ GetSourceText()
+ {
+ string source = (string)this.fileContent.Target;
+ if (source != null) return source;
+ source = this.ReadFile();
+ this.fileContent.Target = source;
+ return source;
+ }
+
+ int ISourceText.Length { get { return this.length; } }
+ string ISourceText.Substring(int startIndex, int length)
+ {
+ return this.GetSourceText().Substring(startIndex, length);
+ }
+ char ISourceText.this[int index]
+ {
+ get
+ {
+ return this.GetSourceText()[index];
+ }
+ }
+ void ISourceText.MakeCollectible()
+ {
+ this.fileContent.Target = null;
+ }
+ }
+ /// <summary>
+ /// This class is used to wrap the string contents of a source file with an ISourceText interface. It is used while compiling
+ /// a project the first time in order to obtain a symbol table. After that the StringSourceText instance is typically replaced with
+ /// a CollectibleSourceText instance, so that the actual source text string can be collected. When a file is edited,
+ /// and the editor does not provide its own ISourceText wrapper for its edit buffer, this class can be used to wrap a copy of the edit buffer.
+ /// </summary>
+ public sealed class StringSourceText : ISourceText
+ {
+ /// <summary>
+ /// The wrapped string used to implement ISourceText. Use this value when unwrapping.
+ /// </summary>
+ public readonly string/*!*/ SourceText;
+ /// <summary>
+ /// True when the wrapped string is the contents of a file. Typically used to check if it safe to replace this
+ /// StringSourceText instance with a CollectibleSourceText instance.
+ /// </summary>
+ public bool IsSameAsFileContents;
+
+ public StringSourceText(string/*!*/ sourceText, bool isSameAsFileContents)
+ {
+ this.SourceText = sourceText;
+ this.IsSameAsFileContents = isSameAsFileContents;
+ //^ base();
+ }
+ int ISourceText.Length { get { return this.SourceText.Length; } }
+ string ISourceText.Substring(int startIndex, int length)
+ {
+ return this.SourceText.Substring(startIndex, length);
+ }
+ char ISourceText.this[int index]
+ {
+ get
+ {
+ return this.SourceText[index];
+ }
+ }
+ void ISourceText.MakeCollectible()
+ {
+ }
+ }
+#endif
+#if !FxCop
+ /// <summary>
+ /// This class provides a uniform interface to program sources provided in the form of Unicode strings,
+ /// unsafe pointers to ascii buffers (as obtained from a memory mapped file, for instance) as well as
+ /// arbitrary source text providers that implement the ISourceText interface.
+ /// </summary>
+ public sealed unsafe class DocumentText
+ {
+ /// <summary>
+ /// If this is not null it is used to obtain 8-bit ASCII characters.
+ /// </summary>
+ public byte* AsciiStringPtr;
+ /// <summary>
+ /// If this is not null it represents a Unicode string encoded as UTF16.
+ /// </summary>
+ public string Source;
+ /// <summary>
+ /// If this is not null the object implement ISourceText provides some way to get at individual characters and substrings.
+ /// </summary>
+ public ISourceText TextProvider;
+ /// <summary>
+ /// The number of characters in the source document.
+ /// A "character" corresponds to a System.Char which is actually a Unicode UTF16 code point to be precise.
+ /// </summary>
+ public int Length;
+ public DocumentText(string source)
+ {
+ if (source == null) { Debug.Assert(false); return; }
+ this.Source = source;
+ this.Length = source.Length;
+ }
+ public DocumentText(ISourceText textProvider)
+ {
+ if (textProvider == null) { Debug.Assert(false); return; }
+ this.TextProvider = textProvider;
+ this.Length = textProvider.Length;
+ }
+ public unsafe DocumentText(ISourceTextBuffer textProvider)
+ {
+ if (textProvider == null) { Debug.Assert(false); return; }
+ this.TextProvider = textProvider;
+ this.AsciiStringPtr = textProvider.Buffer;
+ this.Length = textProvider.Length;
+ }
+ /// <summary>
+ /// Compare this.Substring(offset, length) for equality with str.
+ /// Call this only if str.Length is known to be equal to length.
+ /// </summary>
+ public bool Equals(string str, int position, int length)
+ { //TODO: (int position, int length, string str)
+ if (str == null) { Debug.Assert(false); return false; }
+ if (str.Length != length) { Debug.Assert(false); return false; }
+ if (position < 0 || position + length > this.Length) { Debug.Assert(false); return false; }
+ unsafe
+ {
+ byte* p = this.AsciiStringPtr;
+ if (p != null)
+ {
+ for (int i = position, j = 0; j < length; i++, j++)
+ if (((char)*(p + i)) != str[j]) return false;
+ return true;
+ }
+ }
+ string source = this.Source;
+ if (source != null)
+ {
+ for (int i = position, j = 0; j < length; i++, j++)
+ if (source[i] != str[j]) return false;
+ return true;
+ }
+ ISourceText myProvider = this.TextProvider;
+ if (myProvider == null) { Debug.Assert(false); return false; }
+ for (int i = position, j = 0; j < length; i++, j++)
+ if (myProvider[i] != str[j]) return false;
+ return true;
+ }
+ /// <summary>
+ /// Compares the substring of the specificied length starting at offset, with the substring in DocumentText starting at textOffset.
+ /// </summary>
+ /// <param name="offset">The index of the first character of the substring of this DocumentText.</param>
+ /// <param name="text">The Document text with the substring being compared to.</param>
+ /// <param name="textOffset">The index of the first character of the substring of the DocumentText being compared to.</param>
+ /// <param name="length">The number of characters in the substring being compared.</param>
+ /// <returns></returns>
+ public bool Equals(int offset, DocumentText text, int textOffset, int length)
+ { //TODO: (int position, int length, DocumentText text, int textPosition)
+ if (offset < 0 || length < 0 || offset + length > this.Length) { Debug.Assert(false); return false; }
+ if (textOffset < 0 || text == null || textOffset + length > text.Length) { Debug.Assert(false); return false; }
+ unsafe
+ {
+ byte* p = this.AsciiStringPtr;
+ if (p != null)
+ {
+ unsafe
+ {
+ byte* q = text.AsciiStringPtr;
+ if (q != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (*(p + i) != *(q + j)) return false;
+ return true;
+ }
+ }
+ string textSource = text.Source;
+ if (textSource != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (((char)*(p + i)) != textSource[j]) return false;
+ return true;
+ }
+ ISourceText textProvider = text.TextProvider;
+ if (textProvider == null) { Debug.Assert(false); return false; }
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (((char)*(p + i)) != textProvider[j]) return false;
+ return true;
+ }
+ }
+ string source = this.Source;
+ if (source != null)
+ {
+ unsafe
+ {
+ byte* q = text.AsciiStringPtr;
+ if (q != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (source[i] != (char)*(q + j)) return false;
+ return true;
+ }
+ }
+ string textSource = text.Source;
+ if (textSource != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (source[i] != textSource[j]) return false;
+ return true;
+ }
+ ISourceText textProvider = text.TextProvider;
+ if (textProvider == null) { Debug.Assert(false); return false; }
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (source[i] != textProvider[j]) return false;
+ return true;
+ }
+ {
+ ISourceText myProvider = this.TextProvider;
+ if (myProvider == null) { Debug.Assert(false); return false; }
+ unsafe
+ {
+ byte* q = text.AsciiStringPtr;
+ if (q != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (myProvider[i] != (char)*(q + j)) return false;
+ return true;
+ }
+ }
+ string textSource = text.Source;
+ if (textSource != null)
+ {
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (myProvider[i] != textSource[j]) return false;
+ return true;
+ }
+ ISourceText textProvider = text.TextProvider;
+ if (textProvider == null) { Debug.Assert(false); return false; }
+ for (int i = offset, j = textOffset, n = offset + length; i < n; i++, j++)
+ if (myProvider[i] != textProvider[j]) return false;
+ return true;
+ }
+ }
+ /// <summary>
+ /// Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.
+ /// </summary>
+ public string/*!*/ Substring(int position, int length)
+ {
+ if (position < 0 || length < 0 || position + length > this.Length + 1) { Debug.Assert(false); return ""; }
+ if (position + length > this.Length) length = this.Length - position; //Allow virtual EOF character to be included in length
+ if (this.AsciiStringPtr != null)
+ {
+ unsafe
+ {
+ return new String((sbyte*)this.AsciiStringPtr, position, length, System.Text.Encoding.ASCII);
+ }
+ }
+ else if (this.Source != null)
+ return this.Source.Substring(position, length);
+ else if (this.TextProvider != null)
+ return this.TextProvider.Substring(position, length);
+ else
+ {
+ Debug.Assert(false);
+ return "";
+ }
+ }
+ /// <summary>
+ /// Retrieves the character at the given position. The first character is at position zero.
+ /// </summary>
+ public char this[int position]
+ {
+ get
+ {
+ if (position < 0 || position >= this.Length) { Debug.Assert(false); return (char)0; }
+ if (this.AsciiStringPtr != null)
+ {
+ unsafe
+ {
+ unchecked
+ {
+ return (char)*(this.AsciiStringPtr + position);
+ }
+ }
+ }
+ else if (this.Source != null)
+ return this.Source[position];
+ else if (this.TextProvider != null)
+ return this.TextProvider[position];
+ else
+ {
+ Debug.Assert(false);
+ return (char)0;
+ }
+ }
+ }
+ }
+ /// <summary>
+ /// A source document from which an Abstract Syntax Tree has been derived.
+ /// </summary>
+ public class Document
+ {
+ /// <summary>
+ /// A Guid that identifies the kind of document to applications such as a debugger. Typically System.Diagnostics.SymbolStore.SymDocumentType.Text.
+ /// </summary>
+ public System.Guid DocumentType;
+ /// <summary>
+ /// A Guid that identifies the programming language used in the source document. Typically used by a debugger to locate language specific logic.
+ /// </summary>
+ public System.Guid Language;
+ /// <summary>
+ /// A Guid that identifies the compiler vendor programming language used in the source document. Typically used by a debugger to locate vendor specific logic.
+ /// </summary>
+ public System.Guid LanguageVendor;
+ /// <summary>
+ /// The line number corresponding to the first character in Text. Typically 1 but can be changed by C# preprocessor directives.
+ /// </summary>
+ public int LineNumber;
+ /// <summary>
+ /// Indicates that the document contains machine generated source code that should not show up in tools such as debuggers.
+ /// Can be set by C# preprocessor directives.
+ /// </summary>
+ public bool Hidden;
+ /// <summary>
+ /// The name of the document. Typically a file name. Can be a full or relative file path, or a URI or some other kind of identifier.
+ /// </summary>
+ public string/*!*/ Name;
+ /// <summary>
+ /// Contains the source text.
+ /// </summary>
+ public DocumentText Text;
+ public Document()
+ {
+ this.Name = "";
+ //^ base();
+ }
+ public Document(string/*!*/ name, int lineNumber, string text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
+ : this(name, lineNumber, new DocumentText(text), documentType, language, languageVendor)
+ {
+ }
+ public Document(string/*!*/ name, int lineNumber, DocumentText text, System.Guid documentType, System.Guid language, System.Guid languageVendor)
+ {
+ this.DocumentType = documentType;
+ this.Language = language;
+ this.LanguageVendor = languageVendor;
+ this.LineNumber = lineNumber;
+ this.Name = name;
+ this.Text = text;
+ //^ base();
+ }
+
+ /// <summary>
+ /// Maps the given zero based character position to the number of the source line containing the same character.
+ /// Line number counting starts from the value of LineNumber.
+ /// </summary>
+ public virtual int GetLine(int position)
+ {
+ int line = 0; int column = 0;
+ this.GetPosition(position, out line, out column);
+ return line + this.LineNumber;
+ }
+ /// <summary>
+ /// Maps the given zero based character position in the entire text to the position of the same character in a source line.
+ /// Counting within the source line starts at 1.
+ /// </summary>
+ public virtual int GetColumn(int position)
+ {
+ int line = 0; int column = 0;
+ this.GetPosition(position, out line, out column);
+ return column + 1;
+ }
+
+ /// <summary>
+ /// Given a startLine, startColum, endLine and endColumn, this returns the corresponding startPos and endPos. In other words it
+ /// converts a range expression in line and columns to a range expressed as a start and end character position.
+ /// </summary>
+ /// <param name="startLine">The number of the line containing the first character. The number of the first line equals this.LineNumber.</param>
+ /// <param name="startColumn">The position of the first character relative to the start of the line. Counting from 1.</param>
+ /// <param name="endLine">The number of the line contain the character that immediate follows the last character of the range.</param>
+ /// <param name="endColumn">The position, in the last line, of the character that immediately follows the last character of the range.</param>
+ /// <param name="startPos">The position in the entire text of the first character of the range, counting from 0.</param>
+ /// <param name="endPos">The position in the entire text of the character following the last character of the range.</param>
+ public virtual void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startPos, out int endPos)
+ {
+ lock (this)
+ {
+ if (this.lineOffsets == null) this.ComputeLineOffsets();
+ //^ assert this.lineOffsets != null;
+ startPos = this.lineOffsets[startLine - this.LineNumber] + startColumn - 1;
+ endPos = this.lineOffsets[endLine - this.LineNumber] + endColumn - 1;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves a substring from the text of this Document. The substring starts at a specified character position and has a specified length.
+ /// </summary>
+ public virtual string Substring(int position, int length)
+ {
+ if (this.Text == null) return null;
+ return this.Text.Substring(position, length);
+ }
+
+ /// <summary>
+ /// Counts the number of end of line marker sequences in the given text.
+ /// </summary>
+ protected int GetLineCount(string/*!*/ text)
+ {
+ int n = text == null ? 0 : text.Length;
+ int count = 0;
+ for (int i = 0; i < n; i++)
+ {
+ switch (text[i])
+ {
+ case '\r':
+ if (i + 1 < n && text[i + 1] == '\n')
+ i++;
+ count++;
+ break;
+ case '\n':
+ case (char)0x2028:
+ case (char)0x2029:
+ count++;
+ break;
+ }
+ }
+ return count;
+ }
+ /// <summary>An array of offsets, with offset at index i corresponding to the position of the first character of line i, (counting lines from 0).</summary>
+ private int[] lineOffsets;
+ /// <summary>The number of lines in Text.</summary>
+ private int lines;
+
+ /// <summary>
+ /// Returns the index in this.lineOffsets array such that this.lineOffsets[index] is less than or equal to offset
+ /// and offset is less than lineOffsets[index+1]
+ /// </summary>
+ private int Search(int offset)
+ {
+ tryAgain:
+ int[] lineOffsets = this.lineOffsets;
+ int lines = this.lines;
+ if (lineOffsets == null) { Debug.Assert(false); return -1; }
+ if (offset < 0) { Debug.Assert(false); return -1; }
+ int mid = 0;
+ int low = 0;
+ int high = lines - 1;
+ while (low < high)
+ {
+ mid = (low + high) / 2;
+ if (lineOffsets[mid] <= offset)
+ {
+ if (offset < lineOffsets[mid + 1])
+ return mid;
+ else
+ low = mid + 1;
+ }
+ else
+ high = mid;
+ }
+ Debug.Assert(lines == this.lines);
+ Debug.Assert(lineOffsets[low] <= offset);
+ Debug.Assert(offset < lineOffsets[low + 1]);
+ if (lineOffsets != this.lineOffsets) goto tryAgain;
+ return low;
+ }
+
+ /// <summary>
+ /// Maps the given zero based character position in the entire text to a (line, column) pair corresponding to the same position.
+ /// Counting within the source line starts at 0. Counting source lines start at 0.
+ /// </summary>
+ private void GetPosition(int offset, out int line, out int column)
+ {
+ line = 0; column = 0;
+ if (offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
+ lock (this)
+ {
+ if (this.lineOffsets == null) this.ComputeLineOffsets();
+ if (this.lineOffsets == null) { Debug.Assert(false); return; }
+ int[] lineOffsets = this.lineOffsets;
+ int index = this.Search(offset);
+ Debug.Assert(lineOffsets == this.lineOffsets);
+ if (index < 0 || index >= this.lineOffsets.Length) { Debug.Assert(false); return; }
+ Debug.Assert(this.lineOffsets[index] <= offset && offset < this.lineOffsets[index + 1]);
+ line = index;
+ column = offset - this.lineOffsets[index];
+ }
+ }
+ /// <summary>
+ /// Adds the given offset to the this.lineOffsets table as the offset corresponding to the start of line this.lines+1.
+ /// </summary>
+ private void AddOffset(int offset)
+ {
+ if (this.lineOffsets == null || this.lines < 0) { Debug.Assert(false); return; }
+ if (this.lines >= this.lineOffsets.Length)
+ {
+ int n = this.lineOffsets.Length;
+ if (n <= 0) n = 16;
+ int[] newLineOffsets = new int[n * 2];
+ Array.Copy(this.lineOffsets, newLineOffsets, this.lineOffsets.Length);
+ this.lineOffsets = newLineOffsets;
+ }
+ this.lineOffsets[this.lines++] = offset;
+ }
+ public virtual void InsertOrDeleteLines(int offset, int lineCount)
+ {
+ if (lineCount == 0) return;
+ if (offset < 0 || this.Text == null || offset > this.Text.Length) { Debug.Assert(false); return; }
+ lock (this)
+ {
+ if (this.lineOffsets == null)
+ if (this.lineOffsets == null) this.ComputeLineOffsets();
+ if (lineCount < 0)
+ this.DeleteLines(offset, -lineCount);
+ else
+ this.InsertLines(offset, lineCount);
+ }
+ }
+ private void DeleteLines(int offset, int lineCount)
+ //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
+ {
+ Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
+ int index = this.Search(offset);
+ if (index < 0 || index >= this.lines) { Debug.Assert(false); return; }
+ for (int i = index + 1; i + lineCount < this.lines; i++)
+ {
+ this.lineOffsets[i] = this.lineOffsets[i + lineCount];
+ }
+ this.lines -= lineCount;
+ if (this.lines <= index) { Debug.Assert(false); this.lines = index + 1; }
+ }
+ private void InsertLines(int offset, int lineCount)
+ //^ requires offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null;
+ {
+ Debug.Assert(offset >= 0 && this.Text != null && offset < this.Text.Length && lineCount > 0 && this.lineOffsets != null);
+ int index = this.Search(offset);
+ if (index < 0 || index >= this.lines) { Debug.Assert(false); return; }
+ int n = this.lineOffsets[this.lines - 1];
+ for (int i = 0; i < lineCount; i++) this.AddOffset(++n);
+ for (int i = lineCount; i > 0; i--)
+ {
+ this.lineOffsets[index + i + 1] = this.lineOffsets[index + 1];
+ }
+ }
+ /// <summary>
+ /// Populates this.lineOffsets with an array of offsets, with offset at index i corresponding to the position of the first
+ /// character of line i, (counting lines from 0).
+ /// </summary>
+ private void ComputeLineOffsets()
+ //ensures this.lineOffsets != null;
+ {
+ if (this.Text == null) { Debug.Assert(false); return; }
+ int n = this.Text.Length;
+ this.lineOffsets = new int[n / 10 + 1];
+ this.lines = 0;
+ this.AddOffset(0);
+ for (int i = 0; i < n; i++)
+ {
+ switch (this.Text[i])
+ {
+ case '\r':
+ if (i + 1 < n && this.Text[i + 1] == '\n')
+ i++;
+ this.AddOffset(i + 1);
+ break;
+ case '\n':
+ case (char)0x2028:
+ case (char)0x2029:
+ this.AddOffset(i + 1);
+ break;
+ }
+ }
+ this.AddOffset(n + 1);
+ this.AddOffset(n + 2);
+ }
+
+ /// <summary> Add one to this every time a Document instance gets a unique key.</summary>
+ private static int uniqueKeyCounter;
+ private int uniqueKey;
+ /// <summary>
+ /// An integer that uniquely distinguishes this document instance from every other document instance.
+ /// This provides an efficient equality test to facilitate hashing.
+ /// </summary>
+ public int UniqueKey
+ {
+ get
+ {
+ if (this.uniqueKey == 0)
+ {
+ TryAgain:
+ int c = Document.uniqueKeyCounter;
+ int cp1 = c == int.MaxValue ? 1 : c + 1;
+ if (System.Threading.Interlocked.CompareExchange(ref Document.uniqueKeyCounter, cp1, c) != c) goto TryAgain;
+ this.uniqueKey = cp1;
+ }
+ return this.uniqueKey;
+ }
+ }
+ }
+#endif
+#if !MinimalReader
+ /// <summary>
+ /// For creating source contexts that have just a filename, start line and column and end line and column.
+ /// If a SourceContext has a DocumentWithPrecomputedLineNumbers as its Document, then it should have 0 as its StartPos
+ /// and 1 as its EndPos because those are used here to decide what to return.
+ /// </summary>
+ public class DocumentWithPrecomputedLineNumbers : Document
+ {
+ private int startLine, startCol, endLine, endCol;
+ public DocumentWithPrecomputedLineNumbers(string/*!*/ filename, int startLine, int startCol, int endLine, int endCol)
+ {
+ this.Name = filename;
+ this.startLine = startLine;
+ this.startCol = startCol;
+ this.endLine = endLine;
+ this.endCol = endCol;
+ }
+ public override int GetColumn(int offset) { return offset == 0 ? this.startCol : this.endCol; }
+ public override int GetLine(int offset) { return offset == 0 ? this.startLine : this.endLine; }
+ }
+#endif
+#if UseSingularityPDB
+ internal class PdbDocument : Document {
+ internal PdbDocument(PdbLines lines) {
+ this.Name = lines.file.name;
+ this.lines = lines;
+ }
+ PdbLines lines;
+ public override int GetColumn(int position) {
+ PdbLine line = this.lines.lines[position/2];
+ if (position%2 == 0)
+ return line.colBegin;
+ else
+ return line.colEnd;
+ }
+ public override int GetLine(int position) {
+ PdbLine line = this.lines.lines[position/2];
+ return (int)line.line;
+ }
+ }
+#elif !ROTOR
+ internal class UnmanagedDocument : Document
+ {
+ internal UnmanagedDocument(IntPtr ptrToISymUnmanagedDocument)
+ {
+ //^ base();
+ ISymUnmanagedDocument idoc =
+ (ISymUnmanagedDocument)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(ptrToISymUnmanagedDocument, typeof(ISymUnmanagedDocument));
+ if (idoc != null)
+ {
+ try
+ {
+#if !FxCop
+ idoc.GetDocumentType(out this.DocumentType);
+ idoc.GetLanguage(out this.Language);
+ idoc.GetLanguageVendor(out this.LanguageVendor);
+#endif
+ uint capacity = 1024;
+ uint len = 0;
+ char[] buffer = new char[capacity];
+ while (capacity >= 1024)
+ {
+ idoc.GetURL(capacity, out len, buffer);
+ if (len < capacity) break;
+ capacity += 1024;
+ buffer = new char[capacity];
+ }
+ if (len > 0)
+ this.Name = new String(buffer, 0, (int)len - 1);
+ }
+ finally
+ {
+ System.Runtime.InteropServices.Marshal.ReleaseComObject(idoc);
+ }
+ }
+#if !FxCop
+ this.LineNumber = -1;
+ this.Text = null;
+#endif
+ }
+
+ private Int32List/*!*/ lineList = new Int32List();
+ private Int32List/*!*/ columnList = new Int32List();
+#if !FxCop
+ public override int GetLine(int offset)
+ {
+ return this.lineList[offset];
+ }
+ public override int GetColumn(int offset)
+ {
+ return this.columnList[offset];
+ }
+ public override void GetOffsets(int startLine, int startColumn, int endLine, int endColumn, out int startCol, out int endCol)
+ {
+ int i = UnmanagedDocument.BinarySearch(this.lineList, startLine);
+ Int32List columnList = this.columnList;
+ startCol = 0;
+ for (int j = i, n = columnList.Count; j < n; j++)
+ {
+ if (columnList[j] >= startColumn) { startCol = j; break; }
+ }
+ endCol = 0;
+ i = UnmanagedDocument.BinarySearch(this.lineList, endLine);
+ for (int j = i, n = columnList.Count; j < n; j++)
+ {
+ if (columnList[j] >= endColumn) { endCol = j; break; }
+ }
+ }
+ private static int BinarySearch(Int32List/*!*/ list, int value)
+ {
+ int mid = 0;
+ int low = 0;
+ int high = list.Count - 1;
+ while (low < high)
+ {
+ mid = low + (high - low) / 2;
+ if (list[mid] <= value)
+ {
+ if (list[mid + 1] > value)
+ return mid;
+ else
+ low = mid + 1;
+ }
+ else
+ high = mid;
+ }
+ return low;
+ }
+ public override void InsertOrDeleteLines(int offset, int lineCount)
+ {
+ Debug.Assert(false); //Caller should not be modifying an umanaged document
+ }
+#endif
+ internal int GetOffset(uint line, uint column)
+ {
+ this.lineList.Add((int)line);
+ this.columnList.Add((int)column);
+ return this.lineList.Count - 1;
+ }
+ }
+#endif // !ROTOR
+#if FxCop
+ class Document{
+ internal string Name;
+ }
+ public struct SourceContext{
+ private string name;
+ private int startLine;
+ private int endLine;
+ private int startColumn;
+ private int endColumn;
+ internal SourceContext(string name, uint startLine, uint endLine, uint startColumn, uint endColumn){
+ this.name = name;
+ checked {
+ this.startLine = (int)startLine;
+ this.endLine = (int)endLine;
+ this.startColumn = (int)startColumn;
+ this.endColumn = (int)endColumn;
+ }
+ }
+ public string FileName{
+ get{return this.name;}
+ }
+ public int StartLine{
+ get{return this.startLine;}
+ }
+ public int EndLine{
+ get{return this.endLine;}
+ }
+ public int StartColumn{
+ get{return this.startColumn;}
+ }
+ public int EndColumn{
+ get{return this.endColumn;}
+ }
+ }
+#else
+ /// <summary>
+ /// Records a location within a source document that corresponds to an Abstract Syntax Tree node.
+ /// </summary>
+ public struct SourceContext
+ {
+ /// <summary>The source document within which the AST node is located. Null if the node is not derived from a source document.</summary>
+ public Document Document;
+ /// <summary>
+ /// The zero based index of the first character beyond the last character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int EndPos;
+ /// <summary>
+ /// The zero based index of the first character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int StartPos;
+ public SourceContext(Document document)
+ : this(document, 0, document == null ? 0 : (document.Text == null ? 0 : document.Text.Length))
+ {
+ }
+ public SourceContext(Document document, int startPos, int endPos)
+ {
+ this.Document = document;
+ this.StartPos = startPos;
+ this.EndPos = endPos;
+ }
+ public SourceContext(Document/*!*/ document,
+ int startLine, int startColumn, int endLine, int endColumn)
+ {
+ this.Document = document;
+ this.Document.GetOffsets(startLine, startColumn, endLine, endColumn, out this.StartPos, out this.EndPos);
+ }
+ /// <summary>
+ /// The number (counting from Document.LineNumber) of the line containing the first character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int StartLine
+ {
+ get
+ {
+ if (this.Document == null) return 0;
+ return this.Document.GetLine(this.StartPos);
+ }
+ }
+ /// <summary>
+ /// The number (counting from one) of the line column containing the first character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int StartColumn
+ {
+ get
+ {
+ if (this.Document == null) return 0;
+ return this.Document.GetColumn(this.StartPos);
+ }
+ }
+ /// <summary>
+ /// The number (counting from Document.LineNumber) of the line containing the first character beyond the last character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int EndLine
+ {
+ get
+ {
+#if UseSingularityPDB
+ if (this.Document == null || (this.Document.Text == null && !(this.Document is PdbDocument))) return 0;
+#elif !ROTOR
+ if (this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument))) return 0;
+#else
+ if (this.Document == null || this.Document.Text == null) return 0;
+#endif
+ if (this.Document.Text != null && this.EndPos >= this.Document.Text.Length) this.EndPos = this.Document.Text.Length;
+ return this.Document.GetLine(this.EndPos);
+ }
+ }
+ /// <summary>
+ /// The number (counting from one) of the line column containing first character beyond the last character in the source document that corresponds to the AST node.
+ /// </summary>
+ public int EndColumn
+ {
+ get
+ {
+#if UseSingularityPDB
+ if (this.Document == null || (this.Document.Text == null && !(this.Document is PdbDocument))) return 0;
+#elif !ROTOR
+ if (this.Document == null || (this.Document.Text == null && !(this.Document is UnmanagedDocument))) return 0;
+#else
+ if (this.Document == null || this.Document.Text == null) return 0;
+#endif
+ if (this.Document.Text != null && this.EndPos >= this.Document.Text.Length) this.EndPos = this.Document.Text.Length;
+ return this.Document.GetColumn(this.EndPos);
+ }
+ }
+ /// <summary>
+ /// Returns true if the line and column is greater than or equal the position of the first character
+ /// and less than or equal to the position of the last character
+ /// of the source document that corresponds to the AST node.
+ /// </summary>
+ /// <param name="line">A line number(counting from Document.LineNumber)</param>
+ /// <param name="column">A column number (counting from one)</param>
+ /// <returns></returns>
+ public bool Encloses(int line, int column)
+ {
+ if (line < this.StartLine || line > this.EndLine) return false;
+ if (line == this.StartLine) return column >= this.StartColumn && (column <= this.EndColumn || line < this.EndLine);
+ if (line == this.EndLine) return column <= this.EndColumn;
+ return true;
+ }
+ public bool Encloses(SourceContext sourceContext)
+ {
+ return this.StartPos <= sourceContext.StartPos && this.EndPos >= sourceContext.EndPos && this.EndPos > sourceContext.StartPos;
+ }
+ /// <summary>
+ /// The substring of the source document that corresponds to the AST node.
+ /// </summary>
+ public string SourceText
+ {
+ get
+ {
+ if (this.Document == null) return null;
+ return this.Document.Substring(this.StartPos, this.EndPos - this.StartPos);
+ }
+ }
+ }
+#endif
+#if !MinimalReader
+ public struct SourceChange
+ {
+ public SourceContext SourceContext;
+ public string ChangedText;
+ }
+ /// <summary>
+ /// Allows a compilation to output progress messages and to query if cancellation was requested.
+ /// </summary>
+ public class CompilerSite
+ {
+ public virtual void OutputMessage(string message)
+ {
+ }
+ public virtual bool ShouldCancel
+ {
+ get
+ {
+ return false;
+ }
+ }
+ }
+#endif
+#if !NoWriter
+ public enum PlatformType { notSpecified, v1, v11, v2, cli1 }
+ public class CompilerOptions : System.CodeDom.Compiler.CompilerParameters
+ {
+ public StringCollection AliasesForReferencedAssemblies;
+ public ModuleKindFlags ModuleKind = ModuleKindFlags.ConsoleApplication;
+ public bool EmitManifest = true;
+ public StringList DefinedPreProcessorSymbols;
+ public string XMLDocFileName;
+ public string RecursiveWildcard;
+ public StringList ReferencedModules;
+ public string Win32Icon;
+#if !WHIDBEY
+ private StringCollection embeddedResources = new StringCollection();
+ public StringCollection EmbeddedResources{
+ get{return this.embeddedResources;}
+ }
+ private StringCollection linkedResources = new StringCollection();
+ public StringCollection LinkedResources{
+ get{return this.linkedResources;}
+ }
+#endif
+#if VS7
+ private System.Security.Policy.Evidence evidence;
+ public System.Security.Policy.Evidence Evidence{
+ get{return this.evidence;}
+ set{this.evidence = value;}
+ }
+#endif
+ public bool PDBOnly;
+ public bool Optimize;
+ public bool IncrementalCompile;
+ public Int32List SuppressedWarnings;
+ public bool CheckedArithmetic;
+ public bool AllowUnsafeCode;
+ public bool DisplayCommandLineHelp;
+ public bool SuppressLogo;
+ public long BaseAddress; //TODO: default value
+ public string BugReportFileName;
+ public object CodePage; //must be an int if not null
+ public bool EncodeOutputInUTF8;
+ public bool FullyQualifyPaths;
+ public int FileAlignment;
+ public bool NoStandardLibrary;
+ public StringList AdditionalSearchPaths;
+ public bool HeuristicReferenceResolution;
+ public string RootNamespace;
+ public bool CompileAndExecute;
+ public object UserLocaleId; //must be an int if not null
+ public string StandardLibraryLocation;
+ public PlatformType TargetPlatform; //TODO: rename this to TargetRuntime
+#if !MinimalReader
+ public ProcessorType TargetProcessor;
+#endif
+ public string TargetPlatformLocation;
+ public string AssemblyKeyFile;
+ public string AssemblyKeyName;
+ public bool DelaySign;
+ public TargetInformation TargetInformation;
+ public Int32List SpecificWarningsToTreatAsErrors;
+ public Int32List SpecificWarningsNotToTreatAsErrors;
+ public string OutputPath;
+ public string ExplicitOutputExtension;
+ public AppDomain TargetAppDomain;
+ public bool MayLockFiles;
+ public string ShadowedAssembly;
+ public bool UseStandardConfigFile;
+#if !MinimalReader
+ public CompilerSite Site;
+#endif
+#if ExtendedRuntime
+ /// <summary>
+ /// True if the source code for the assembly specify only contracts.
+ /// </summary>
+ public bool IsContractAssembly;
+ /// <summary>
+ /// Do not emit run-time checks for requires clauses of non-externally-accessible methods, assert statements, loop invariants, and ensures clauses.
+ /// </summary>
+ public bool DisableInternalChecks;
+ /// <summary>
+ /// Do not emit run-time checks for assume statements.
+ /// </summary>
+ public bool DisableAssumeChecks;
+ /// <summary>
+ /// Do not emit run-time checks for requires clauses of externally accessible methods.
+ /// </summary>
+ public bool DisableDefensiveChecks;
+ /// <summary>
+ /// Disable the guarded classes feature, which integrates run-time enforcement of object invariants, ownership, and safe concurrency.
+ /// </summary>
+ public bool DisableGuardedClassesChecks;
+ public bool DisableInternalContractsMetadata;
+ public bool DisablePublicContractsMetadata;
+ /// <summary>
+ /// Disable the runtime test against null on non-null typed parameters on public methods
+ /// </summary>
+ public bool DisableNullParameterValidation;
+ public virtual bool LoadDebugSymbolsForReferencedAssemblies {
+ get { return false; }
+ }
+
+ /// <summary>
+ /// If set, the compiler will only parse and then emit an xml file with detailed source contexts
+ /// about what is parsed.
+ /// </summary>
+ public bool EmitSourceContextsOnly = false;
+
+#endif
+ public CompilerOptions()
+ {
+ }
+ public CompilerOptions(CompilerOptions source)
+ {
+ if (source == null) { Debug.Assert(false); return; }
+ this.AdditionalSearchPaths = source.AdditionalSearchPaths; //REVIEW: clone the list?
+ this.AliasesForReferencedAssemblies = source.AliasesForReferencedAssemblies;
+ this.AllowUnsafeCode = source.AllowUnsafeCode;
+ this.AssemblyKeyFile = source.AssemblyKeyFile;
+ this.AssemblyKeyName = source.AssemblyKeyName;
+ this.BaseAddress = source.BaseAddress;
+ this.BugReportFileName = source.BugReportFileName;
+ this.CheckedArithmetic = source.CheckedArithmetic;
+ this.CodePage = source.CodePage;
+ this.CompileAndExecute = source.CompileAndExecute;
+ this.CompilerOptions = source.CompilerOptions;
+ this.DefinedPreProcessorSymbols = source.DefinedPreProcessorSymbols;
+ this.DelaySign = source.DelaySign;
+#if ExtendedRuntime
+ this.DisableAssumeChecks = source.DisableAssumeChecks;
+ this.DisableDefensiveChecks = source.DisableDefensiveChecks;
+ this.DisableGuardedClassesChecks = source.DisableGuardedClassesChecks;
+ this.DisableInternalChecks = source.DisableInternalChecks;
+ this.DisableInternalContractsMetadata = source.DisableInternalContractsMetadata;
+ this.DisablePublicContractsMetadata = source.DisablePublicContractsMetadata;
+#endif
+ this.DisplayCommandLineHelp = source.DisplayCommandLineHelp;
+ if (source.EmbeddedResources != null)
+ foreach (string s in source.EmbeddedResources) this.EmbeddedResources.Add(s);
+ this.EmitManifest = source.EmitManifest;
+ this.EncodeOutputInUTF8 = source.EncodeOutputInUTF8;
+ this.Evidence = source.Evidence;
+ this.ExplicitOutputExtension = source.ExplicitOutputExtension;
+ this.FileAlignment = source.FileAlignment;
+ this.FullyQualifyPaths = source.FullyQualifyPaths;
+ this.GenerateExecutable = source.GenerateExecutable;
+ this.GenerateInMemory = source.GenerateInMemory;
+ this.HeuristicReferenceResolution = source.HeuristicReferenceResolution;
+ this.IncludeDebugInformation = source.IncludeDebugInformation;
+ this.IncrementalCompile = source.IncrementalCompile;
+#if ExtendedRuntime
+ this.IsContractAssembly = source.IsContractAssembly;
+#endif
+ if (source.LinkedResources != null)
+ foreach (string s in source.LinkedResources) this.LinkedResources.Add(s);
+ this.MainClass = source.MainClass;
+ this.MayLockFiles = source.MayLockFiles;
+ this.ModuleKind = source.ModuleKind;
+ this.NoStandardLibrary = source.NoStandardLibrary;
+ this.Optimize = source.Optimize;
+ this.OutputAssembly = source.OutputAssembly;
+ this.OutputPath = source.OutputPath;
+ this.PDBOnly = source.PDBOnly;
+ this.RecursiveWildcard = source.RecursiveWildcard;
+ if (source.ReferencedAssemblies != null)
+ foreach (string s in source.ReferencedAssemblies) this.ReferencedAssemblies.Add(s);
+ this.ReferencedModules = source.ReferencedModules;
+ this.RootNamespace = source.RootNamespace;
+ this.ShadowedAssembly = source.ShadowedAssembly;
+ this.SpecificWarningsToTreatAsErrors = source.SpecificWarningsToTreatAsErrors;
+ this.StandardLibraryLocation = source.StandardLibraryLocation;
+ this.SuppressLogo = source.SuppressLogo;
+ this.SuppressedWarnings = source.SuppressedWarnings;
+ this.TargetAppDomain = source.TargetAppDomain;
+ this.TargetInformation = source.TargetInformation;
+ this.TargetPlatform = source.TargetPlatform;
+ this.TargetPlatformLocation = source.TargetPlatformLocation;
+ this.TreatWarningsAsErrors = source.TreatWarningsAsErrors;
+ this.UserLocaleId = source.UserLocaleId;
+ this.UserToken = source.UserToken;
+ this.WarningLevel = source.WarningLevel;
+ this.Win32Icon = source.Win32Icon;
+ this.Win32Resource = source.Win32Resource;
+ this.XMLDocFileName = source.XMLDocFileName;
+ }
+ public virtual string GetOptionHelp()
+ {
+ return null;
+ }
+ public virtual CompilerOptions Clone()
+ {
+ return (CompilerOptions)this.MemberwiseClone();
+ }
+ }
+#endif
+ public sealed class MarshallingInformation
+ {
+ private string @class;
+ private string cookie;
+ private int elementSize;
+ private NativeType elementType;
+ private NativeType nativeType;
+ private int numberOfElements;
+ private int paramIndex;
+ private int size;
+ public MarshallingInformation Clone()
+ {
+ return (MarshallingInformation)base.MemberwiseClone();
+ }
+ public string Class
+ {
+ get { return this.@class; }
+ set { this.@class = value; }
+ }
+ public string Cookie
+ {
+ get { return this.cookie; }
+ set { this.cookie = value; }
+ }
+ public int ElementSize
+ {
+ get { return this.elementSize; }
+ set { this.elementSize = value; }
+ }
+ public NativeType ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+ public NativeType NativeType
+ {
+ get { return this.nativeType; }
+ set { this.nativeType = value; }
+ }
+ public int NumberOfElements
+ {
+ get { return this.numberOfElements; }
+ set { this.numberOfElements = value; }
+ }
+ public int ParamIndex
+ {
+ get { return this.paramIndex; }
+ set { this.paramIndex = value; }
+ }
+ public int Size
+ {
+ get { return this.size; }
+ set { this.size = value; }
+ }
+ }
+#if !NoWriter
+ public struct TargetInformation
+ {
+ public string Company;
+ public string Configuration;
+ public string Copyright;
+ public string Culture;
+ public string Description;
+ public string Product;
+ public string ProductVersion;
+ public string Title;
+ public string Trademark;
+ public string Version;
+ }
+#endif
+ public enum NativeType
+ {
+ Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
+ I1 = 0x3, // 1 byte signed value
+ U1 = 0x4, // 1 byte unsigned value
+ I2 = 0x5, // 2 byte signed value
+ U2 = 0x6, // 2 byte unsigned value
+ I4 = 0x7, // 4 byte signed value
+ U4 = 0x8, // 4 byte unsigned value
+ I8 = 0x9, // 8 byte signed value
+ U8 = 0xa, // 8 byte unsigned value
+ R4 = 0xb, // 4 byte floating point
+ R8 = 0xc, // 8 byte floating point
+ Currency = 0xf, // A currency
+ BStr = 0x13, // OLE Unicode BSTR
+ LPStr = 0x14, // Ptr to SBCS string
+ LPWStr = 0x15, // Ptr to Unicode string
+ LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
+ ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
+ IUnknown = 0x19, // COM IUnknown pointer.
+ IDispatch = 0x1a, // COM IDispatch pointer
+ Struct = 0x1b, // Structure
+ Interface = 0x1c, // COM interface
+ SafeArray = 0x1d, // OLE SafeArray
+ ByValArray = 0x1e, // Array of fixed size (only valid in structs)
+ SysInt = 0x1f, // Hardware natural sized signed integer
+ SysUInt = 0x20,
+ VBByRefStr = 0x22,
+ AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
+ TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
+ VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
+ FunctionPtr = 0x26, // Function pointer
+ AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
+ LPArray = 0x2a, // C style array
+ LPStruct = 0x2b, // Pointer to a structure
+ CustomMarshaler = 0x2c, // Native type supplied by custom code
+ Error = 0x2d,
+ NotSpecified = 0x50,
+ }
+ ///0-: Common
+ ///1000-: HScript
+ ///2000-: EcmaScript
+ ///3000-: Zonnon
+ ///4000-: Comega
+ ///5000-: X++
+ ///6000-: Spec#
+ ///7000-: Sing#
+ ///8000-: Xaml
+ ///9000-: C/AL
+ ///For your range contact hermanv@microsoft.com
+ public enum NodeType
+ {
+ //Dummy
+ Undefined = 0,
+
+ //IL instruction node tags
+ Add,
+ Add_Ovf,
+ Add_Ovf_Un,
+ And,
+ Arglist,
+ Box,
+ Branch,
+ Call,
+ Calli,
+ Callvirt,
+ Castclass,
+ Ceq,
+ Cgt,
+ Cgt_Un,
+ Ckfinite,
+ Clt,
+ Clt_Un,
+ Conv_I,
+ Conv_I1,
+ Conv_I2,
+ Conv_I4,
+ Conv_I8,
+ Conv_Ovf_I,
+ Conv_Ovf_I_Un,
+ Conv_Ovf_I1,
+ Conv_Ovf_I1_Un,
+ Conv_Ovf_I2,
+ Conv_Ovf_I2_Un,
+ Conv_Ovf_I4,
+ Conv_Ovf_I4_Un,
+ Conv_Ovf_I8,
+ Conv_Ovf_I8_Un,
+ Conv_Ovf_U,
+ Conv_Ovf_U_Un,
+ Conv_Ovf_U1,
+ Conv_Ovf_U1_Un,
+ Conv_Ovf_U2,
+ Conv_Ovf_U2_Un,
+ Conv_Ovf_U4,
+ Conv_Ovf_U4_Un,
+ Conv_Ovf_U8,
+ Conv_Ovf_U8_Un,
+ Conv_R_Un,
+ Conv_R4,
+ Conv_R8,
+ Conv_U,
+ Conv_U1,
+ Conv_U2,
+ Conv_U4,
+ Conv_U8,
+ Cpblk,
+ DebugBreak,
+ Div,
+ Div_Un,
+ Dup,
+ EndFilter,
+ EndFinally,
+ ExceptionHandler,
+ Initblk,
+ Isinst,
+ Jmp,
+ Ldftn,
+ Ldlen,
+ Ldtoken,
+ Ldvirtftn,
+ Localloc,
+ Mkrefany,
+ Mul,
+ Mul_Ovf,
+ Mul_Ovf_Un,
+ Neg,
+ Nop,
+ Not,
+ Or,
+ Pop,
+ ReadOnlyAddressOf,
+ Refanytype,
+ Refanyval,
+ Rem,
+ Rem_Un,
+ Rethrow,
+ Shl,
+ Shr,
+ Shr_Un,
+ Sizeof,
+ SkipCheck,
+ Sub,
+ Sub_Ovf,
+ Sub_Ovf_Un,
+ SwitchInstruction,
+ Throw,
+ Unbox,
+ UnboxAny,
+ Xor,
+
+ //AST tags that are relevant to the binary reader
+ AddressDereference,
+ AddressOf,
+ AssignmentStatement,
+ Block,
+ Catch,
+ Construct,
+ ConstructArray,
+ Eq,
+ ExpressionStatement,
+ FaultHandler,
+ Filter,
+ Finally,
+ Ge,
+ Gt,
+ Identifier,
+ Indexer,
+ Instruction,
+ InterfaceExpression,
+ Le,
+ Literal,
+ LogicalNot,
+ Lt,
+ MemberBinding,
+ NamedArgument,
+ Namespace,
+ Ne,
+ Return,
+ This,
+ Try,
+
+ //Metadata node tags
+ ArrayType,
+ @Assembly,
+ AssemblyReference,
+ Attribute,
+ Class,
+ ClassParameter,
+ DelegateNode,
+ EnumNode,
+ Event,
+ Field,
+ FunctionPointer,
+ InstanceInitializer,
+ Interface,
+ Local,
+ Method,
+ Module,
+ ModuleReference,
+ OptionalModifier,
+ Parameter,
+ Pointer,
+ Property,
+ Reference,
+ RequiredModifier,
+ SecurityAttribute,
+ StaticInitializer,
+ Struct,
+ TypeParameter,
+
+#if !MinimalReader
+ // The following NodeType definitions are not required
+ // for examining assembly metadata directly from binaries
+
+ //Serialization tags used for values that are not leaf nodes.
+ Array,
+ BlockReference,
+ CompilationParameters,
+ Document,
+ EndOfRecord,
+ Expression,
+ Guid,
+ List,
+ MarshallingInformation,
+ Member,
+ MemberReference,
+ MissingBlockReference,
+ MissingExpression,
+ MissingMemberReference,
+ String,
+ StringDictionary,
+ TypeNode,
+ Uri,
+ XmlNode,
+
+ //Source-based AST node tags
+ AddEventHandler,
+ AliasDefinition,
+ AnonymousNestedFunction,
+ ApplyToAll,
+ ArglistArgumentExpression,
+ ArglistExpression,
+ ArrayTypeExpression,
+ As,
+ Assertion,
+ AssignmentExpression,
+ Assumption,
+ Base,
+#endif
+#if FxCop
+ BlockExpression,
+ StackVariable,
+#endif
+#if !MinimalReader
+ BlockExpression,
+ BoxedTypeExpression,
+ ClassExpression,
+ CoerceTuple,
+ CollectionEnumerator,
+ Comma,
+ Compilation,
+ CompilationUnit,
+ CompilationUnitSnippet,
+ Conditional,
+ ConstructDelegate,
+ ConstructFlexArray,
+ ConstructIterator,
+ ConstructTuple,
+ Continue,
+ CopyReference,
+ CurrentClosure,
+ Decrement,
+ DefaultValue,
+ DoWhile,
+ Exit,
+ ExplicitCoercion,
+ ExpressionSnippet,
+ FieldInitializerBlock,
+ Fixed,
+ FlexArrayTypeExpression,
+ For,
+ ForEach,
+ FunctionDeclaration,
+ FunctionTypeExpression,
+ Goto,
+ GotoCase,
+ If,
+ ImplicitThis,
+ Increment,
+ InvariantTypeExpression,
+ Is,
+ LabeledStatement,
+ LocalDeclaration,
+ LocalDeclarationsStatement,
+ Lock,
+ LogicalAnd,
+ LogicalOr,
+ LRExpression,
+ MethodCall,
+ NameBinding,
+ NonEmptyStreamTypeExpression,
+ NonNullableTypeExpression,
+ NonNullTypeExpression,
+ NullableTypeExpression,
+ NullCoalesingExpression,
+ OutAddress,
+ Parentheses,
+ PointerTypeExpression,
+ PostfixExpression,
+ PrefixExpression,
+ QualifiedIdentifer,
+ RefAddress,
+ ReferenceTypeExpression,
+ RefTypeExpression,
+ RefValueExpression,
+ RemoveEventHandler,
+ Repeat,
+ ResourceUse,
+ SetterValue,
+ StackAlloc,
+ StatementSnippet,
+ StreamTypeExpression,
+ Switch,
+ SwitchCase,
+ SwitchCaseBottom,
+ TemplateInstance,
+ TupleTypeExpression,
+ TypeExpression,
+ TypeIntersectionExpression,
+ TypeMemberSnippet,
+ Typeof,
+ TypeReference,
+ Typeswitch,
+ TypeswitchCase,
+ TypeUnionExpression,
+ UnaryPlus,
+ UsedNamespace,
+ VariableDeclaration,
+ While,
+ Yield,
+
+ //Extended metadata node tags
+ ConstrainedType,
+ TupleType,
+ TypeAlias,
+ TypeIntersection,
+ TypeUnion,
+
+ //Query node tags
+ Composition,
+ QueryAggregate,
+ QueryAlias,
+ QueryAll,
+ QueryAny,
+ QueryAxis,
+ QueryCommit,
+ QueryContext,
+ QueryDelete,
+ QueryDifference,
+ QueryDistinct,
+ QueryExists,
+ QueryFilter,
+ QueryGeneratedType,
+ QueryGroupBy,
+ QueryInsert,
+ QueryIntersection,
+ QueryIterator,
+ QueryJoin,
+ QueryLimit,
+ QueryOrderBy,
+ QueryOrderItem,
+ QueryPosition,
+ QueryProject,
+ QueryQuantifiedExpression,
+ QueryRollback,
+ QuerySelect,
+ QuerySingleton,
+ QueryTransact,
+ QueryTypeFilter,
+ QueryUnion,
+ QueryUpdate,
+ QueryYielder,
+
+ //Contract node tags
+ Acquire,
+ Comprehension,
+ ComprehensionBinding,
+ Ensures,
+ EnsuresExceptional,
+ EnsuresNormal,
+ Iff,
+ Implies,
+ Invariant,
+ LogicalEqual,
+ LogicalImply,
+ Maplet,
+ MethodContract,
+ Modelfield,
+ ModelfieldContract,
+ OldExpression,
+ Range,
+ Read,
+ Requires,
+ RequiresOtherwise,
+ RequiresPlain,
+ TypeContract,
+ Write,
+
+ //Node tags for explicit modifiers in front-end
+ OptionalModifierTypeExpression,
+ RequiredModifierTypeExpression,
+
+ //Temporary node tags
+ Count,
+ Exists,
+ ExistsUnique,
+ Forall,
+ Max,
+ Min,
+ Product,
+ Sum,
+ Quantifier,
+#endif // MinimalReader
+ }
+ [Flags]
+ public enum AssemblyFlags
+ {
+ None = 0x0000,
+ PublicKey = 0x0001,
+ Library = 0x0002,
+ Platform = 0x0004,
+ NowPlatform = 0x0006,
+ SideBySideCompatible = 0x0000,
+ NonSideBySideCompatible = 0x0010,
+ NonSideBySideProcess = 0x0020,
+ NonSideBySideMachine = 0x0030,
+ CompatibilityMask = 0x00F0,
+ Retargetable = 0x0100,
+ DisableJITcompileOptimizer = 0x4000,
+ EnableJITcompileTracking = 0x8000
+ }
+ public enum AssemblyHashAlgorithm
+ {
+ None = 0x0000,
+ MD5 = 0x8003,
+ SHA1 = 0x8004
+ }
+ [Flags]
+ public enum CallingConventionFlags
+ {
+ Default = 0x0,
+ C = 0x1,
+ StandardCall = 0x2,
+ ThisCall = 0x3,
+ FastCall = 0x4,
+ VarArg = 0x5,
+ ArgumentConvention = 0x7,
+ Generic = 0x10,
+ HasThis = 0x20,
+ ExplicitThis = 0x40
+ }
+ [Flags]
+ public enum EventFlags
+ {
+ None = 0x0000,
+ SpecialName = 0x0200,
+ ReservedMask = 0x0400,
+ RTSpecialName = 0x0400,
+#if !MinimalReader
+ Extend = MethodFlags.Extend, // used for languages with type extensions, e.g. Sing#
+#endif
+ }
+ [Flags]
+ public enum FieldFlags
+ {
+ None = 0x0000,
+ FieldAccessMask = 0x0007,
+ CompilerControlled = 0x0000,
+ Private = 0x0001,
+ FamANDAssem = 0x0002,
+ Assembly = 0x0003,
+ Family = 0x0004,
+ FamORAssem = 0x0005,
+ Public = 0x0006,
+ Static = 0x0010,
+ InitOnly = 0x0020,
+ Literal = 0x0040,
+ NotSerialized = 0x0080,
+ SpecialName = 0x0200,
+ PinvokeImpl = 0x2000,
+ ReservedMask = 0x9500,
+ RTSpecialName = 0x0400,
+ HasFieldMarshal = 0x1000,
+ HasDefault = 0x8000,
+ HasFieldRVA = 0x0100,
+ }
+ [Flags]
+ public enum FileFlags
+ {
+ ContainsMetaData = 0x0000,
+ ContainsNoMetaData = 0x0001
+ }
+ [Flags]
+ public enum TypeParameterFlags
+ {
+ NonVariant = 0x0000,
+ Covariant = 0x0001,
+ Contravariant = 0x0002,
+ VarianceMask = 0x0003,
+ NoSpecialConstraint = 0x0000,
+ ReferenceTypeConstraint = 0x0004,
+ ValueTypeConstraint = 0x0008,
+ DefaultConstructorConstraint = 0x0010,
+ SpecialConstraintMask = 0x001C,
+ }
+ [Flags]
+ public enum MethodImplFlags
+ {
+ CodeTypeMask = 0x0003,
+ IL = 0x0000,
+ Native = 0x0001,
+ OPTIL = 0x0002,
+ Runtime = 0x0003,
+ ManagedMask = 0x0004,
+ Unmanaged = 0x0004,
+ Managed = 0x0000,
+ ForwardRef = 0x0010,
+ PreserveSig = 0x0080,
+ InternalCall = 0x1000,
+ Synchronized = 0x0020,
+ NoInlining = 0x0008,
+#if !MinimalReader
+ MaxMethodImplVal = 0xffff
+#endif
+ }
+ [Flags]
+ public enum MethodFlags
+ {
+ MethodAccessMask = 0x0007,
+ CompilerControlled = 0x0000,
+ Private = 0x0001,
+ FamANDAssem = 0x0002,
+ Assembly = 0x0003,
+ Family = 0x0004,
+ FamORAssem = 0x0005,
+ Public = 0x0006,
+ Static = 0x0010,
+ Final = 0x0020,
+ Virtual = 0x0040,
+ HideBySig = 0x0080,
+ VtableLayoutMask = 0x0100,
+ ReuseSlot = 0x0000,
+ NewSlot = 0x0100,
+ CheckAccessOnOverride = 0x0200,
+ Abstract = 0x0400,
+ SpecialName = 0x0800,
+ PInvokeImpl = 0x2000,
+ UnmanagedExport = 0xd000,
+ ReservedMask = 0xd000,
+ RTSpecialName = 0x1000,
+ HasSecurity = 0x4000,
+ RequireSecObject = 0x8000,
+#if !MinimalReader
+ Extend = 0x01000000, // used for languages with type extensions, e.g. Sing#
+#endif
+ }
+ public enum ModuleKindFlags
+ { //TODO: rename this to just ModuleKind
+ ConsoleApplication,
+ WindowsApplication,
+ DynamicallyLinkedLibrary,
+ ManifestResourceFile,
+ UnmanagedDynamicallyLinkedLibrary
+ }
+ [Flags]
+ public enum ParameterFlags
+ {
+ None = 0x0000,
+ In = 0x0001,
+ Out = 0x0002,
+ Optional = 0x0010,
+ ReservedMask = 0xf000,
+ HasDefault = 0x1000,
+ HasFieldMarshal = 0x2000
+ }
+ [Flags]
+ public enum PEKindFlags
+ {
+ ILonly = 0x0001,
+ Requires32bits = 0x0002,
+ Requires64bits = 0x0004,
+ AMD = 0x0008
+ }
+ [Flags]
+ public enum PInvokeFlags
+ {
+ None = 0x0000,
+ NoMangle = 0x0001,
+ BestFitDisabled = 0x0020,
+ BestFitEnabled = 0x0010,
+ BestFitUseAsm = 0x0000,
+ BestFitMask = 0x0030,
+ CharSetMask = 0x0006,
+ CharSetNotSpec = 0x0000,
+ CharSetAns = 0x0002,
+ CharSetUnicode = 0x0004,
+ CharSetAuto = 0x0006,
+ SupportsLastError = 0x0040,
+ CallingConvMask = 0x0700,
+ CallConvWinapi = 0x0100,
+ CallConvCdecl = 0x0200,
+ CallConvStdcall = 0x0300,
+ CallConvThiscall = 0x0400,
+ CallConvFastcall = 0x0500,
+ ThrowOnUnmappableCharMask = 0x3000,
+ ThrowOnUnmappableCharEnabled = 0x1000,
+ ThrowOnUnmappableCharDisabled = 0x2000,
+ ThrowOnUnmappableCharUseAsm = 0x0000
+ }
+ [Flags]
+ public enum PropertyFlags
+ {
+ None = 0x0000,
+ SpecialName = 0x0200,
+ ReservedMask = 0xf400,
+ RTSpecialName = 0x0400,
+#if !MinimalReader
+ Extend = MethodFlags.Extend, // used for languages with type extensions, e.g. Sing#
+#endif
+ }
+ public enum PESection
+ {
+ Text,
+ SData,
+ TLS
+ };
+#if !MinimalReader
+ public enum ProcessorType
+ {
+ Any,
+ x86,
+ x64,
+ Itanium,
+ }
+#endif
+ [Flags]
+ public enum TypeFlags
+ {
+ None = 0x00000000,
+ VisibilityMask = 0x00000007,
+ NotPublic = 0x00000000,
+ Public = 0x00000001,
+ NestedPublic = 0x00000002,
+ NestedPrivate = 0x00000003,
+ NestedFamily = 0x00000004,
+ NestedAssembly = 0x00000005,
+ NestedFamANDAssem = 0x00000006,
+ NestedFamORAssem = 0x00000007,
+ LayoutMask = 0x00000018,
+ AutoLayout = 0x00000000,
+ SequentialLayout = 0x00000008,
+ ExplicitLayout = 0x00000010,
+ ClassSemanticsMask = 0x00000020,
+ Class = 0x00000000,
+ Interface = 0x00000020,
+ LayoutOverridden = 0x00000040, // even AutoLayout can be explicit or implicit
+ Abstract = 0x00000080,
+ Sealed = 0x00000100,
+ SpecialName = 0x00000400,
+ Import = 0x00001000,
+ Serializable = 0x00002000,
+ StringFormatMask = 0x00030000,
+ AnsiClass = 0x00000000,
+ UnicodeClass = 0x00010000,
+ AutoClass = 0x00020000,
+ BeforeFieldInit = 0x00100000,
+ ReservedMask = 0x00040800,
+ RTSpecialName = 0x00000800,
+ HasSecurity = 0x00040000,
+ Forwarder = 0x00200000, //The type is a stub left behind for backwards compatibility. References to this type are forwarded to another type by the CLR.
+#if !MinimalReader
+ Extend = 0x01000000, // used for languages with type extensions, e.g. Sing#
+#endif
+ }
+
+ public sealed class TrivialHashtable
+ {
+ struct HashEntry
+ {
+ public int Key;
+ public object Value;
+ }
+
+ private HashEntry[]/*!*/ entries;
+ private int count;
+
+ public TrivialHashtable()
+ {
+ this.entries = new HashEntry[16];
+ //this.count = 0;
+ }
+ private TrivialHashtable(HashEntry[]/*!*/ entries, int count)
+ {
+ this.entries = entries;
+ this.count = count;
+ }
+ public TrivialHashtable(int expectedEntries)
+ {
+ int initialSize = 16;
+ expectedEntries <<= 1;
+ while (initialSize < expectedEntries && initialSize > 0) initialSize <<= 1;
+ if (initialSize < 0) initialSize = 16;
+ this.entries = new HashEntry[initialSize];
+ //this.count = 0;
+ }
+ public int Count
+ {
+ get
+ {
+ return this.count;
+ }
+ }
+ private void Expand()
+ {
+ HashEntry[] oldEntries = this.entries;
+ int n = oldEntries.Length;
+ int m = n * 2;
+ if (m <= 0) return;
+ HashEntry[] entries = new HashEntry[m];
+ int count = 0;
+ for (int i = 0; i < n; i++)
+ {
+ int key = oldEntries[i].Key;
+ if (key <= 0) continue; //No entry (0) or deleted entry (-1)
+ object value = oldEntries[i].Value;
+ Debug.Assert(value != null);
+ int j = key & (m - 1);
+ int k = entries[j].Key;
+ while (true)
+ {
+ if (k == 0)
+ {
+ entries[j].Value = value;
+ entries[j].Key = key;
+ count++;
+ break;
+ }
+ j++; if (j >= m) j = 0;
+ k = entries[j].Key;
+ }
+ }
+ this.entries = entries;
+ this.count = count;
+ }
+ public object this[int key]
+ {
+ get
+ {
+ if (key <= 0) throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
+ HashEntry[] entries = this.entries;
+ int n = entries.Length;
+ int i = key & (n - 1);
+ int k = entries[i].Key;
+ object result = null;
+ while (true)
+ {
+ if (k == key) { result = entries[i].Value; break; }
+ if (k == 0) break;
+ i++; if (i >= n) i = 0;
+ k = entries[i].Key;
+ }
+ return result;
+ }
+ set
+ {
+ if (key <= 0) throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
+ HashEntry[] entries = this.entries;
+ int n = entries.Length;
+ int i = key & (n - 1);
+ int k = entries[i].Key;
+ while (true)
+ {
+ if (k == key || k == 0)
+ {
+ entries[i].Value = value;
+ if (k == 0)
+ {
+ if (value == null) { return; }
+ entries[i].Key = key;
+ if (++this.count > n / 2) this.Expand();
+ return;
+ }
+ if (value == null) entries[i].Key = -1;
+ return;
+ }
+ i++; if (i >= n) i = 0;
+ k = entries[i].Key;
+ }
+ }
+ }
+ public TrivialHashtable Clone()
+ {
+ HashEntry[] clonedEntries = (HashEntry[])this.entries.Clone();
+ //^ assume clonedEntries != null;
+ return new TrivialHashtable(clonedEntries, this.count);
+ }
+ }
+#if !FxCop
+ public
+#endif
+ sealed class TrivialHashtableUsingWeakReferences
+ {
+ struct HashEntry
+ {
+ public int Key;
+ public WeakReference Value;
+ }
+
+ private HashEntry[]/*!*/ entries;
+ private int count;
+
+ public TrivialHashtableUsingWeakReferences()
+ {
+ this.entries = new HashEntry[16];
+ //this.count = 0;
+ }
+ private TrivialHashtableUsingWeakReferences(HashEntry[]/*!*/ entries, int count)
+ {
+ this.entries = entries;
+ this.count = count;
+ }
+ public TrivialHashtableUsingWeakReferences(int expectedEntries)
+ {
+ int initialSize = 16;
+ expectedEntries <<= 1;
+ while (initialSize < expectedEntries && initialSize > 0) initialSize <<= 1;
+ if (initialSize < 0) initialSize = 16;
+ this.entries = new HashEntry[initialSize];
+ //this.count = 0;
+ }
+ public int Count
+ {
+ get
+ {
+ return this.count;
+ }
+ }
+ private void Expand()
+ {
+ HashEntry[] oldEntries = this.entries;
+ int n = oldEntries.Length;
+ int m = n * 2;
+ if (m <= 0) return;
+ HashEntry[] entries = new HashEntry[m];
+ int count = 0;
+ for (int i = 0; i < n; i++)
+ {
+ int key = oldEntries[i].Key;
+ if (key <= 0) continue; //No entry (0) or deleted entry (-1)
+ WeakReference value = oldEntries[i].Value;
+ Debug.Assert(value != null);
+ if (value == null || !value.IsAlive) continue; //Collected entry.
+ int j = key & (m - 1);
+ int k = entries[j].Key;
+ while (true)
+ {
+ if (k == 0)
+ {
+ entries[j].Value = value;
+ entries[j].Key = key;
+ count++;
+ break;
+ }
+ j++; if (j >= m) j = 0;
+ k = entries[j].Key;
+ }
+ }
+ this.entries = entries;
+ this.count = count;
+ }
+ private void Contract()
+ {
+ HashEntry[] oldEntries = this.entries;
+ int n = oldEntries.Length;
+ int m = n / 2;
+ if (m < 16) return;
+ HashEntry[] entries = new HashEntry[m];
+ int count = 0;
+ for (int i = 0; i < n; i++)
+ {
+ int key = oldEntries[i].Key;
+ if (key <= 0) continue; //No entry (0) or deleted entry (-1)
+ WeakReference value = oldEntries[i].Value;
+ Debug.Assert(value != null);
+ if (value == null || !value.IsAlive) continue; //Collected entry.
+ int j = key & (m - 1);
+ int k = entries[j].Key;
+ while (true)
+ {
+ if (k == 0)
+ {
+ entries[j].Value = value;
+ entries[j].Key = key;
+ count++;
+ break;
+ }
+ j++; if (j >= m) j = 0;
+ k = entries[j].Key;
+ }
+ }
+ this.entries = entries;
+ this.count = count;
+ }
+ private void WeedOutCollectedEntries()
+ {
+ HashEntry[] oldEntries = this.entries;
+ int n = oldEntries.Length;
+ HashEntry[] entries = new HashEntry[n];
+ int count = 0;
+ for (int i = 0; i < n; i++)
+ {
+ int key = oldEntries[i].Key;
+ if (key <= 0) continue; //No entry (0) or deleted entry (-1)
+ WeakReference value = oldEntries[i].Value;
+ Debug.Assert(value != null);
+ if (value == null || !value.IsAlive) continue; //Collected entry.
+ int j = key & (n - 1);
+ int k = entries[j].Key;
+ while (true)
+ {
+ if (k == 0)
+ {
+ entries[j].Value = value;
+ entries[j].Key = key;
+ count++;
+ break;
+ }
+ j++; if (j >= n) j = 0;
+ k = entries[j].Key;
+ }
+ }
+ this.entries = entries;
+ this.count = count;
+ }
+ public object this[int key]
+ {
+ get
+ {
+ if (key <= 0) throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
+ HashEntry[] entries = this.entries;
+ int n = entries.Length;
+ int i = key & (n - 1);
+ int k = entries[i].Key;
+ object result = null;
+ while (true)
+ {
+ if (k == key)
+ {
+ WeakReference wref = entries[i].Value;
+ if (wref == null) { Debug.Assert(false); return null; }
+ result = wref.Target;
+ if (result != null) return result;
+ this.WeedOutCollectedEntries();
+ while (this.count < n / 4 && n > 16) { this.Contract(); n = this.entries.Length; }
+ return null;
+ }
+ if (k == 0) break;
+ i++; if (i >= n) i = 0;
+ k = entries[i].Key;
+ }
+ return result;
+ }
+ set
+ {
+ if (key <= 0) throw new ArgumentException(ExceptionStrings.KeyNeedsToBeGreaterThanZero, "key");
+ HashEntry[] entries = this.entries;
+ int n = entries.Length;
+ int i = key & (n - 1);
+ int k = entries[i].Key;
+ while (true)
+ {
+ if (k == key || k == 0)
+ {
+ if (value == null)
+ entries[i].Value = null;
+ else
+ entries[i].Value = new WeakReference(value);
+ if (k == 0)
+ {
+ if (value == null) return;
+ entries[i].Key = key;
+ if (++this.count > n / 2)
+ {
+ this.Expand(); //Could decrease this.count because of collected entries being deleted
+ while (this.count < n / 4 && n > 16) { this.Contract(); n = this.entries.Length; }
+ }
+ return;
+ }
+ if (value == null) entries[i].Key = -1;
+ return;
+ }
+ i++; if (i >= n) i = 0;
+ k = entries[i].Key;
+ }
+ }
+ }
+ public TrivialHashtableUsingWeakReferences Clone()
+ {
+ HashEntry[] clonedEntries = (HashEntry[])this.entries.Clone();
+ //^ assume clonedEntries != null;
+ return new TrivialHashtableUsingWeakReferences(clonedEntries, this.count);
+ }
+ }
+
+ public interface IUniqueKey
+ {
+ int UniqueId { get; }
+ }
+
+ /// <summary>
+ /// A node in an Abstract Syntax Tree.
+ /// </summary>
+ public abstract class Node : IUniqueKey
+ {
+#if !MinimalReader
+ public bool IsErroneous;
+#endif
+ /// <summary>
+ /// The region in the source code that contains the concrete syntax corresponding to this node in the Abstract Syntax Tree.
+ /// </summary>
+#if !FxCop
+ public SourceContext SourceContext;
+#else
+ internal SourceContext sourceContext;
+ public SourceContext SourceContext {
+ get{return this.sourceContext;}
+ internal set{this.sourceContext = value;}
+ }
+#endif
+#if DEBUG && !MinimalReader
+ public string DebugLabel; // useful for debugging.
+#endif
+ protected Node(NodeType nodeType)
+ {
+ this.NodeType = nodeType;
+ }
+ private NodeType nodeType;
+ /// <summary>
+ /// A scalar tag that identifies the concrete type of the node. This is provided to allow efficient type membership tests that
+ /// facilitate tree traversal.
+ /// </summary>
+ public NodeType NodeType
+ {
+ get { return this.nodeType; }
+ set { this.nodeType = value; }
+ }
+ private static int uniqueKeyCounter;
+ private int uniqueKey;
+ /// <summary>
+ /// An integer that uniquely identifies this node. This provides an efficient equality test to facilitate hashing.
+ /// Do not override this.
+ /// </summary>
+ public virtual int UniqueKey
+ {
+ get
+ {
+ if (this.uniqueKey == 0)
+ {
+ TryAgain:
+ int c = Node.uniqueKeyCounter;
+ int cp1 = c + 17;
+ if (cp1 <= 0) cp1 = 1000000;
+ if (System.Threading.Interlocked.CompareExchange(ref Node.uniqueKeyCounter, cp1, c) != c) goto TryAgain;
+ this.uniqueKey = cp1;
+ }
+ return this.uniqueKey;
+ }
+ }
+ /// <summary>
+ /// Makes a shallow copy of the node.
+ /// </summary>
+ /// <returns>A shallow copy of the node</returns>
+ public virtual Node/*!*/ Clone()
+ {
+ Node result = (Node)this.MemberwiseClone();
+ result.uniqueKey = 0;
+ return result;
+ }
+#if !MinimalReader
+ public virtual object GetVisitorFor(object/*!*/ callingVisitor, string/*!*/ visitorClassName)
+ {
+ if (callingVisitor == null || visitorClassName == null) { Debug.Fail(""); return null; }
+ return Node.GetVisitorFor(this.GetType(), callingVisitor, visitorClassName);
+ }
+ private static Hashtable VisitorTypeFor; //contains weak references
+ private static Object GetVisitorFor(System.Type/*!*/ nodeType, object/*!*/ callingVisitor, string/*!*/ visitorClassName)
+ {
+ if (nodeType == null || callingVisitor == null || visitorClassName == null) { Debug.Fail(""); return null; }
+ if (Node.VisitorTypeFor == null) Node.VisitorTypeFor = new Hashtable();
+ string customVisitorClassName = visitorClassName;
+ if (visitorClassName.IndexOf('.') < 0) customVisitorClassName = nodeType.Namespace + "." + visitorClassName;
+ if (customVisitorClassName == callingVisitor.GetType().FullName)
+ {
+ Debug.Assert(false); //This must be a bug, the calling visitor is the one that should handle the nodeType
+ return null;
+ }
+ System.Reflection.AssemblyName visitorAssemblyName = null;
+ System.Reflection.Assembly assembly = null;
+ WeakReference wref = (WeakReference)Node.VisitorTypeFor[customVisitorClassName];
+ Type visitorType = wref == null ? null : (System.Type)wref.Target;
+ if (visitorType == typeof(object)) return null;
+ string callerDirectory = null;
+ if (visitorType == null)
+ {
+ assembly = nodeType.Assembly;
+ if (assembly == null) return null;
+ visitorType = assembly.GetType(customVisitorClassName, false);
+ }
+ if (visitorType == null)
+ {
+ //^ assert assembly != null;
+ if (assembly.Location == null) return null;
+ callerDirectory = Path.GetDirectoryName(assembly.Location);
+ visitorAssemblyName = new System.Reflection.AssemblyName();
+ visitorAssemblyName.Name = "Visitors";
+ visitorAssemblyName.CodeBase = "file:///" + Path.Combine(callerDirectory, "Visitors.dll");
+ try
+ {
+ assembly = System.Reflection.Assembly.Load(visitorAssemblyName);
+ }
+ catch { }
+ if (assembly != null)
+ visitorType = assembly.GetType(customVisitorClassName, false);
+ if (visitorType == null)
+ {
+ visitorAssemblyName.Name = customVisitorClassName;
+ visitorAssemblyName.CodeBase = "file:///" + Path.Combine(callerDirectory, customVisitorClassName + ".dll");
+ try
+ {
+ assembly = System.Reflection.Assembly.Load(visitorAssemblyName);
+ }
+ catch { }
+ if (assembly != null)
+ visitorType = assembly.GetType(customVisitorClassName, false);
+ }
+ }
+ if (visitorType == null)
+ {
+ //Put fake entry into hashtable to short circuit future lookups
+ visitorType = typeof(object);
+ assembly = nodeType.Assembly;
+ }
+ if (assembly != null)
+ { //Only happens if there was a cache miss
+ lock (Node.VisitorTypeFor)
+ {
+ Node.VisitorTypeFor[customVisitorClassName] = new WeakReference(visitorType);
+ }
+ }
+ if (visitorType == typeof(object)) return null;
+ try
+ {
+ return System.Activator.CreateInstance(visitorType, new object[] { callingVisitor });
+ }
+ catch { }
+ return null;
+ }
+#endif
+ int IUniqueKey.UniqueId { get { return this.UniqueKey; } }
+#if MinimalReader
+ // Return a constant value for IsNormalized in the binary-only
+ // reader. This results in less code churn elsewhere.
+ internal bool IsNormalized{get{return true;}}
+#endif
+ }
+#if !MinimalReader
+ public abstract class ErrorNode : Node
+ {
+ public int Code;
+ public string[] MessageParameters;
+
+ protected ErrorNode(int code, params string[] messageParameters)
+ : base(NodeType.Undefined)
+ {
+ this.Code = code;
+ this.MessageParameters = messageParameters;
+ }
+ public virtual string GetErrorNumber()
+ {
+ return this.Code.ToString("0000");
+ }
+ public string GetMessage()
+ {
+ return this.GetMessage(null);
+ }
+#if ExtendedRuntime
+ [return: Microsoft.Contracts.NotNull]
+#endif
+ public abstract string GetMessage(System.Globalization.CultureInfo culture);
+ public virtual string GetMessage(string key, System.Resources.ResourceManager rm, System.Globalization.CultureInfo culture)
+ {
+ if (rm == null || key == null) return null;
+ string localizedString = rm.GetString(key, culture);
+ if (localizedString == null) localizedString = key;
+ string[] messageParameters = this.MessageParameters;
+ if (messageParameters == null || messageParameters.Length == 0) return localizedString;
+ return string.Format(localizedString, messageParameters);
+ }
+ public abstract int Severity
+ {
+ get;
+ }
+ public static int GetCountAtSeverity(ErrorNodeList errors, int minSeverity, int maxSeverity)
+ {
+ if (errors == null) return 0;
+ int n = 0;
+ for (int i = 0; i < errors.Count; i++)
+ {
+ ErrorNode e = errors[i];
+ if (e == null)
+ continue;
+ int s = e.Severity;
+ if (minSeverity <= s && s <= maxSeverity)
+ n++;
+ }
+ return n;
+ }
+ }
+ public class Expose : Statement
+ {
+ public Expression Instance;
+ public Block Body;
+ public bool IsLocal;
+ public Expose(NodeType nodeType)
+ : base(nodeType)
+ {
+ }
+ }
+ public class Acquire : Statement
+ {
+ public bool ReadOnly;
+ public Statement Target;
+ public Expression Condition;
+ public Expression ConditionFunction;
+ public Block Body;
+ public BlockScope ScopeForTemporaryVariable;
+ public Acquire()
+ : base(NodeType.Acquire)
+ {
+ }
+ }
+#endif
+ public class Expression : Node
+ {
+ private TypeNode type;
+#if FxCop
+ internal int ILOffset;
+#endif
+ public Expression(NodeType nodeType)
+ : base(nodeType)
+ {
+ }
+ public Expression(NodeType nodeType, TypeNode type)
+ : base(nodeType)
+ {
+ this.type = type;
+ }
+ public virtual TypeNode Type
+ {
+ get { return this.type; }
+ set { this.type = value; }
+ }
+ }
+#if !MinimalReader
+ public class ExpressionSnippet : Expression
+ {
+ public IParserFactory ParserFactory;
+
+ public ExpressionSnippet()
+ : base(NodeType.ExpressionSnippet)
+ {
+ }
+ public ExpressionSnippet(IParserFactory parserFactory, SourceContext sctx)
+ : base(NodeType.ExpressionSnippet)
+ {
+ this.ParserFactory = parserFactory;
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+ public class MemberBinding : Expression
+ {
+ private int alignment;
+ private Member boundMember;
+#if !MinimalReader
+ public Expression BoundMemberExpression;
+#endif
+ private Expression targetObject;
+ private bool @volatile;
+ public MemberBinding()
+ : base(NodeType.MemberBinding)
+ {
+ }
+ public MemberBinding(Expression targetObject, Member/*!*/ boundMember)
+ : this(targetObject, boundMember, false, -1)
+ {
+ if (boundMember is Field) this.Volatile = ((Field)boundMember).IsVolatile;
+ }
+#if !MinimalReader
+ public MemberBinding(Expression targetObject, Member/*!*/ boundMember, Expression boundMemberExpression)
+ : this(targetObject, boundMember, false, -1)
+ {
+ if (boundMember is Field) this.Volatile = ((Field)boundMember).IsVolatile;
+ this.BoundMemberExpression = boundMemberExpression;
+ }
+ public MemberBinding(Expression targetObject, Member/*!*/ boundMember, SourceContext sctx)
+ : this(targetObject, boundMember, false, -1)
+ {
+ if (boundMember is Field) this.Volatile = ((Field)boundMember).IsVolatile;
+ this.SourceContext = sctx;
+ }
+ public MemberBinding(Expression targetObject, Member/*!*/ boundMember, SourceContext sctx, Expression boundMemberExpression)
+ : this(targetObject, boundMember, false, -1)
+ {
+ if (boundMember is Field) this.Volatile = ((Field)boundMember).IsVolatile;
+ this.SourceContext = sctx;
+ this.BoundMemberExpression = boundMemberExpression;
+ }
+#endif
+ public MemberBinding(Expression targetObject, Member/*!*/ boundMember, bool @volatile, int alignment)
+ : base(NodeType.MemberBinding)
+ {
+ Debug.Assert(boundMember != null);
+ this.alignment = alignment;
+ this.boundMember = boundMember;
+ this.targetObject = targetObject;
+ this.@volatile = @volatile;
+ switch (boundMember.NodeType)
+ {
+ case NodeType.Field: this.Type = ((Field)boundMember).Type; break;
+ case NodeType.Method: this.Type = ((Method)boundMember).ReturnType; break;
+ case NodeType.Event: this.Type = ((Event)boundMember).HandlerType; break;
+ default: this.Type = boundMember as TypeNode; break;
+ }
+ }
+ public int Alignment
+ {
+ get { return this.alignment; }
+ set { this.alignment = value; }
+ }
+ public Member BoundMember
+ {
+ get { return this.boundMember; }
+ set { this.boundMember = value; }
+ }
+ public Expression TargetObject
+ {
+ get { return this.targetObject; }
+ set { this.targetObject = value; }
+ }
+ public bool Volatile
+ {
+ get { return this.@volatile; }
+ set { this.@volatile = value; }
+ }
+ }
+ public class AddressDereference : Expression
+ {
+ private Expression address;
+ private int alignment;
+ private bool isVolatile;
+#if !MinimalReader
+ public enum ExplicitOp { None = 0, Star, Arrow }
+ private ExplicitOp explicitOperation; // was explicit in source (* or ->)
+#endif
+ public AddressDereference()
+ : base(NodeType.AddressDereference)
+ {
+ }
+ public AddressDereference(Expression address, TypeNode type)
+ : this(address, type, false, -1)
+ {
+ }
+#if !MinimalReader
+ public AddressDereference(Expression address, TypeNode type, SourceContext sctx)
+ : this(address, type, false, -1, sctx)
+ {
+ }
+#endif
+ public AddressDereference(Expression address, TypeNode type, bool isVolatile, int alignment)
+ : base(NodeType.AddressDereference)
+ {
+ this.address = address;
+ this.alignment = alignment;
+ this.Type = type;
+ this.isVolatile = isVolatile;
+ }
+#if !MinimalReader
+ public AddressDereference(Expression address, TypeNode type, bool Volatile, int alignment, SourceContext sctx)
+ : base(NodeType.AddressDereference)
+ {
+ this.address = address;
+ this.alignment = alignment;
+ this.Type = type;
+ this.isVolatile = Volatile;
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Address
+ {
+ get { return this.address; }
+ set { this.address = value; }
+ }
+ public int Alignment
+ {
+ get { return this.alignment; }
+ set { this.alignment = value; }
+ }
+ public bool Volatile
+ {
+ get { return this.isVolatile; }
+ set { this.isVolatile = value; }
+ }
+#if !MinimalReader
+ public bool Explicit
+ {
+ get { return this.explicitOperation != ExplicitOp.None; }
+ }
+ public ExplicitOp ExplicitOperator
+ {
+ get { return this.explicitOperation; }
+ set { this.explicitOperation = value; }
+ }
+#endif
+ }
+ public class UnaryExpression : Expression
+ {
+ private Expression operand;
+ public UnaryExpression()
+ : base(NodeType.Nop)
+ {
+ }
+ public UnaryExpression(Expression operand, NodeType nodeType)
+ : base(nodeType)
+ {
+ this.Operand = operand;
+ }
+#if !MinimalReader
+ public UnaryExpression(Expression operand, NodeType nodeType, SourceContext sctx)
+ : base(nodeType)
+ {
+ this.operand = operand;
+ this.SourceContext = sctx;
+ }
+#endif
+ public UnaryExpression(Expression operand, NodeType nodeType, TypeNode type)
+ : base(nodeType)
+ {
+ this.operand = operand;
+ this.Type = type;
+ }
+#if !MinimalReader
+ public UnaryExpression(Expression operand, NodeType nodeType, TypeNode type, SourceContext sctx)
+ : base(nodeType)
+ {
+ this.operand = operand;
+ this.Type = type;
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Operand
+ {
+ get { return this.operand; }
+ set { this.operand = value; }
+ }
+ }
+#if !MinimalReader
+ public class PrefixExpression : Expression
+ {
+ public Expression Expression;
+ public NodeType Operator;
+ public Method OperatorOverload;
+ public PrefixExpression()
+ : base(NodeType.PrefixExpression)
+ {
+ }
+ public PrefixExpression(Expression expression, NodeType Operator, SourceContext sourceContext)
+ : base(NodeType.PrefixExpression)
+ {
+ this.Expression = expression;
+ this.Operator = Operator;
+ this.SourceContext = sourceContext;
+ }
+ }
+ public class PostfixExpression : Expression
+ {
+ public Expression Expression;
+ public NodeType Operator;
+ public Method OperatorOverload;
+ public PostfixExpression()
+ : base(NodeType.PostfixExpression)
+ {
+ }
+ public PostfixExpression(Expression expression, NodeType Operator, SourceContext sourceContext)
+ : base(NodeType.PostfixExpression)
+ {
+ this.Expression = expression;
+ this.Operator = Operator;
+ this.SourceContext = sourceContext;
+ }
+ }
+#endif
+ public class BinaryExpression : Expression
+ {
+ private Expression operand1;
+ private Expression operand2;
+ public BinaryExpression()
+ : base(NodeType.Nop)
+ {
+ }
+ public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType)
+ : base(nodeType)
+ {
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ }
+ public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, TypeNode resultType)
+ : base(nodeType)
+ {
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ this.Type = resultType;
+ }
+#if !MinimalReader
+ public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, SourceContext ctx)
+ : base(nodeType)
+ {
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ this.SourceContext = ctx;
+ }
+ public BinaryExpression(Expression operand1, Expression operand2, NodeType nodeType, TypeNode resultType, SourceContext ctx)
+ : base(nodeType)
+ {
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ this.Type = resultType;
+ this.SourceContext = ctx;
+ }
+#endif
+ public Expression Operand1
+ {
+ get { return this.operand1; }
+ set { this.operand1 = value; }
+ }
+ public Expression Operand2
+ {
+ get { return this.operand2; }
+ set { this.operand2 = value; }
+ }
+ }
+ public class TernaryExpression : Expression
+ {
+ private Expression operand1;
+ private Expression operand2;
+ private Expression operand3;
+ public TernaryExpression()
+ : base(NodeType.Nop)
+ {
+ }
+ public TernaryExpression(Expression operand1, Expression operand2, Expression operand3, NodeType nodeType, TypeNode resultType)
+ : base(nodeType)
+ {
+ this.operand1 = operand1;
+ this.operand2 = operand2;
+ this.operand3 = operand3;
+ this.Type = resultType;
+ }
+ public Expression Operand1
+ {
+ get { return this.operand1; }
+ set { this.operand1 = value; }
+ }
+ public Expression Operand2
+ {
+ get { return this.operand2; }
+ set { this.operand2 = value; }
+ }
+ public Expression Operand3
+ {
+ get { return this.operand3; }
+ set { this.operand3 = value; }
+ }
+ }
+ public abstract class NaryExpression : Expression
+ {
+#if !FxCop
+ public ExpressionList Operands;
+#else
+ private ExpressionList operands;
+ public ExpressionList Operands {
+ get {return this.operands;}
+ internal set{this.operands = value;}
+ }
+#endif
+ protected NaryExpression()
+ : base(NodeType.Nop)
+ {
+ }
+ protected NaryExpression(ExpressionList operands, NodeType nodeType)
+ : base(nodeType)
+ {
+ this.Operands = operands;
+ }
+ }
+#if !MinimalReader
+ public class ApplyToAll : BinaryExpression
+ {
+ public Local ElementLocal;
+ public Method ResultIterator;
+ public ApplyToAll()
+ : base(null, null, NodeType.ApplyToAll)
+ {
+ }
+ public ApplyToAll(Expression operand1, Expression operand2)
+ : base(operand1, operand2, NodeType.ApplyToAll)
+ {
+ }
+ public ApplyToAll(Expression operand1, Expression operand2, SourceContext ctx)
+ : base(operand1, operand2, NodeType.ApplyToAll)
+ {
+ this.SourceContext = ctx;
+ }
+ }
+#endif
+ public class NamedArgument : Expression
+ {
+ private bool isCustomAttributeProperty;
+ private Identifier name;
+ private Expression value;
+ private bool valueIsBoxed;
+ public NamedArgument()
+ : base(NodeType.NamedArgument)
+ {
+ }
+ public NamedArgument(Identifier name, Expression value)
+ : base(NodeType.NamedArgument)
+ {
+ this.Name = name;
+ this.Value = value;
+ }
+#if !MinimalReader
+ public NamedArgument(Identifier name, Expression value, SourceContext ctx)
+ : base(NodeType.NamedArgument)
+ {
+ this.Name = name;
+ this.Value = value;
+ this.SourceContext = ctx;
+ }
+#endif
+ public bool IsCustomAttributeProperty
+ { //TODO: rename this to IsProperty
+ get { return this.isCustomAttributeProperty; }
+ set { this.isCustomAttributeProperty = value; }
+ }
+ public Identifier Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ public Expression Value
+ {
+ get { return this.value; }
+ set { this.value = value; }
+ }
+ public bool ValueIsBoxed
+ {
+ get { return this.valueIsBoxed; }
+ set { this.valueIsBoxed = value; }
+ }
+ }
+ /// <summary>
+ /// This an Expression wrapper for compile time constants. It is assumed to be correct by construction.
+ /// In Normalized IR, the wrapped value must be a primitive numeric type or an enum or a string or null.
+ /// If used in custom attributes, types are also allowed as well as single dimensional arrays of other allowed types.
+ /// If the wrapped value is null, any reference type is allowed, except in custom attributes, where it must be Type or String.
+ /// </summary>
+ public class Literal : Expression
+ {
+ private object value;
+#if !MinimalReader
+ public bool TypeWasExplicitlySpecifiedInSource;
+ public Expression SourceExpression;
+#endif
+ public Literal()
+ : base(NodeType.Literal)
+ {
+ }
+#if !NoReflection
+ public Literal(object Value)
+ : base(NodeType.Literal)
+ {
+ this.value = Value;
+ }
+#endif
+ public Literal(object value, TypeNode type)
+ : base(NodeType.Literal)
+ {
+ this.value = value;
+ this.Type = type;
+ }
+ public Literal(object value, TypeNode type, SourceContext sourceContext)
+ : base(NodeType.Literal)
+ {
+ this.value = value;
+ this.SourceContext = sourceContext;
+ this.Type = type;
+ }
+ /// <summary>
+ /// Holds the wrapped compile time constant value.
+ /// </summary>
+ public object Value
+ {
+ get { return this.value; }
+ }
+ public override string ToString()
+ {
+ if (this.Value == null) return "Literal for null";
+ return this.Value.ToString();
+ }
+#if !NoWriter
+ public static bool IsNullLiteral(Expression expr)
+ {
+ Literal lit = expr as Literal;
+ if (lit == null) return false;
+ if (lit.Type != CoreSystemTypes.Object || lit.Value != null) return false;
+ return true;
+ }
+ //TODO: replace these with properties that freshly allocate them. It appears that Literals sometimes get clobbered.
+ public static Literal DoubleOne;
+ public static Literal False;
+ public static Literal Int32MinusOne;
+ public static Literal Int32Zero;
+ public static Literal Int32One;
+ public static Literal Int32Two;
+ public static Literal Int32Sixteen;
+ public static Literal Int64Zero;
+ public static Literal Int64One;
+ public static Literal Null;
+ public static Literal SingleOne;
+ public static Literal True;
+
+ public static void Initialize()
+ {
+ Literal.DoubleOne = new Literal(1.0, CoreSystemTypes.Double);
+ Literal.False = new Literal(false, CoreSystemTypes.Boolean);
+ Literal.Int32MinusOne = new Literal(-1, CoreSystemTypes.Int32);
+ Literal.Int32Zero = new Literal(0, CoreSystemTypes.Int32);
+ Literal.Int32One = new Literal(1, CoreSystemTypes.Int32);
+ Literal.Int32Two = new Literal(2, CoreSystemTypes.Int32);
+ Literal.Int32Sixteen = new Literal(16, CoreSystemTypes.Int32);
+ Literal.Int64Zero = new Literal(0L, CoreSystemTypes.Int64);
+ Literal.Int64One = new Literal(1L, CoreSystemTypes.Int64);
+ Literal.Null = new Literal(null, CoreSystemTypes.Object);
+ Literal.SingleOne = new Literal(1.0f, CoreSystemTypes.Single);
+ Literal.True = new Literal(true, CoreSystemTypes.Boolean);
+ }
+ public static void ClearStatics()
+ {
+ Literal.DoubleOne = null;
+ Literal.False = null;
+ Literal.Int32MinusOne = null;
+ Literal.Int32Zero = null;
+ Literal.Int32One = null;
+ Literal.Int32Two = null;
+ Literal.Int32Sixteen = null;
+ Literal.Int64Zero = null;
+ Literal.Int64One = null;
+ Literal.Null = null;
+ Literal.SingleOne = null;
+ Literal.True = null;
+ }
+#endif
+ }
+ public class This : Parameter
+ {
+ public This()
+ {
+ this.NodeType = NodeType.This;
+ this.Name = StandardIds.This;
+ }
+ public This(TypeNode type)
+ {
+ this.NodeType = NodeType.This;
+ this.Name = StandardIds.This;
+ this.Type = type;
+ }
+#if !MinimalReader
+ public bool IsCtorCall = false;
+ public This(SourceContext sctx, bool isCtorCall)
+ {
+ this.NodeType = NodeType.This;
+ this.Name = StandardIds.This;
+ this.SourceContext = sctx;
+ this.IsCtorCall = isCtorCall;
+ }
+ public This(TypeNode type, SourceContext sctx)
+ {
+ this.NodeType = NodeType.This;
+ this.Name = StandardIds.This;
+ this.Type = type;
+ this.SourceContext = sctx;
+ }
+ public override bool Equals(object obj)
+ {
+ ThisBinding binding = obj as ThisBinding;
+ return obj == this || binding != null && binding.BoundThis == this;
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+#endif
+#if ExtendedRuntime
+ public override bool IsUniversallyDelayed {
+ get {
+ if (this.DeclaringMethod is InstanceInitializer && this.DeclaringMethod.DeclaringType != null &&
+ !this.DeclaringMethod.DeclaringType.IsValueType) {
+ // by default, class constructors should be delayed
+ return !(this.DeclaringMethod.GetAttribute(ExtendedRuntimeTypes.NotDelayedAttribute) != null);
+ }
+ return (this.DeclaringMethod.GetAttribute(ExtendedRuntimeTypes.DelayedAttribute) != null);
+ }
+ }
+
+#endif
+ }
+#if !MinimalReader
+ public class ThisBinding : This, IUniqueKey
+ {
+ public This/*!*/ BoundThis;
+ public ThisBinding(This/*!*/ boundThis, SourceContext sctx)
+ {
+ if (boundThis == null) throw new ArgumentNullException("boundThis");
+ this.BoundThis = boundThis;
+ this.SourceContext = sctx;
+ this.Type = boundThis.Type;
+ this.Name = boundThis.Name;
+ this.TypeExpression = boundThis.TypeExpression;
+ this.Attributes = boundThis.Attributes;
+ this.DefaultValue = boundThis.DefaultValue;
+ this.Flags = boundThis.Flags;
+ this.MarshallingInformation = boundThis.MarshallingInformation;
+ this.DeclaringMethod = boundThis.DeclaringMethod;
+ this.ParameterListIndex = boundThis.ParameterListIndex;
+ this.ArgumentListIndex = boundThis.ArgumentListIndex;
+ //^ base();
+ }
+ public override int GetHashCode()
+ {
+ return this.BoundThis.GetHashCode();
+ }
+ public override bool Equals(object obj)
+ {
+ ThisBinding pb = obj as ThisBinding;
+ if (pb != null)
+ return this.BoundThis.Equals(pb.BoundThis);
+ else
+ return this.BoundThis.Equals(obj);
+ }
+ int IUniqueKey.UniqueId
+ {
+ get { return this.BoundThis.UniqueKey; }
+ }
+ /// <summary>
+ /// Must forward type to underlying binding, since ThisBindings get built at times when
+ /// the bound This node does not have its final type yet.
+ /// </summary>
+ public override TypeNode Type
+ {
+ get
+ {
+ return BoundThis.Type;
+ }
+ set
+ {
+ BoundThis.Type = value;
+ }
+ }
+ }
+ public class Base : Expression
+ {
+ /// <summary>
+ /// When the source uses the C# compatibility mode, base calls cannot be put after non-null
+ /// field initialization, but must be put before the body. But the user can specify where
+ /// the base ctor call should be performed by using "base;" as a marker. During parsing
+ /// this flag is set so the right code transformations can be performed at code generation.
+ /// </summary>
+ public bool UsedAsMarker;
+ public bool IsCtorCall = false;
+ public Base()
+ : base(NodeType.Base)
+ {
+ }
+ public Base(SourceContext sctx, bool isCtorCall)
+ : base(NodeType.Base)
+ {
+ this.SourceContext = sctx;
+ this.IsCtorCall = isCtorCall;
+ }
+ }
+ public class ImplicitThis : Expression
+ {
+ public int LexLevel;
+ public Class MostNestedScope;
+ public ImplicitThis()
+ : base(NodeType.ImplicitThis)
+ {
+ }
+ public ImplicitThis(Class mostNestedScope, int lexLevel)
+ : base(NodeType.ImplicitThis)
+ {
+ this.LexLevel = lexLevel;
+ this.MostNestedScope = mostNestedScope;
+ }
+ }
+ public class CurrentClosure : Expression
+ {
+ public Method Method;
+ public CurrentClosure()
+ : base(NodeType.CurrentClosure)
+ {
+ }
+ public CurrentClosure(Method method, TypeNode type)
+ : base(NodeType.CurrentClosure)
+ {
+ this.Method = method;
+ this.Type = type;
+ }
+ public CurrentClosure(Method method, TypeNode type, SourceContext sctx)
+ : base(NodeType.CurrentClosure)
+ {
+ this.Method = method;
+ this.Type = type;
+ this.SourceContext = sctx;
+ }
+ }
+ public class SetterValue : Expression
+ {
+ public SetterValue()
+ : base(NodeType.SetterValue)
+ {
+ }
+ }
+#endif
+ public class Identifier : Expression
+ {
+ private int hashCode;
+ internal int length;
+ private string name;
+ private int offset;
+#if !FxCop
+ private DocumentText text;
+#endif
+#if !MinimalReader
+ public Identifier Prefix;
+#endif
+ /// <summary>An identifier with the empty string ("") as its value.</summary>
+ public static readonly Identifier/*!*/ Empty = new Identifier("");
+#if !FxCop
+ private Identifier(DocumentText/*!*/ text, int offset, int length)
+ : base(NodeType.Identifier)
+ {
+ this.text = text;
+ this.offset = offset;
+ this.length = length;
+ ulong hcode = 0;
+ for (int i = offset, n = length + i; i < n; i++)
+ {
+ char ch = text[i];
+ hcode = hcode * 17 + ch;
+ }
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ }
+ public static Identifier/*!*/ For(SourceContext sctx)
+ {
+ DocumentText text = null;
+ if (sctx.Document != null) text = sctx.Document.Text;
+ if (text == null) text = new DocumentText("");
+ Identifier id = new Identifier(text, sctx.StartPos, sctx.EndPos - sctx.StartPos);
+ id.SourceContext = sctx;
+ return id;
+ }
+#endif
+ public Identifier(string name)
+ : base(NodeType.Identifier)
+ {
+ if (name == null) name = "";
+ this.name = name;
+ int n = this.length = name.Length;
+ ulong hcode = 0;
+ for (int i = 0; i < n; i++)
+ {
+ char ch = name[i];
+ hcode = hcode * 17 + ch;
+ }
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ }
+#if !MinimalReader
+ public Identifier(string name, SourceContext sctx)
+ : this(name)
+ {
+ this.SourceContext = sctx;
+ }
+#endif
+ public static Identifier/*!*/ For(string/*!*/ name)
+ {
+ return new Identifier(name);
+ }
+ private unsafe Identifier(byte* pointer, int offset)
+ : base(NodeType.Identifier)
+ {
+ this.offset = offset;
+ bool isASCII = true;
+ int length = 0;
+ ulong hcode = 0;
+ for (int i = offset; ; i++)
+ {
+ byte b = *(pointer + i);
+ if (b == 0) break;
+ if ((b & 0x80) != 0) isASCII = false;
+ hcode = hcode * 17 + b;
+ length++;
+ }
+ if (isASCII)
+ {
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ this.length = length;
+ this.name = new string((sbyte*)pointer, offset, length, Encoding.ASCII);
+ return;
+ }
+ hcode = 0;
+ string name = this.name = new string((sbyte*)pointer, offset, length, Encoding.UTF8);
+ for (int i = 0, n = this.length = name.Length; i < n; i++)
+ {
+ char ch = name[i];
+ hcode = hcode * 17 + ch;
+ }
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ }
+ /// <summary>
+ /// Use when pointer+offset points to a null terminated string of UTF8 code points.
+ /// </summary>
+ internal unsafe static Identifier/*!*/ For(byte* pointer, int offset)
+ {
+ //TODO: first look for identifier in cache
+ return new Identifier(pointer, offset);
+ }
+
+ private unsafe Identifier(byte* pointer, uint length)
+ : base(NodeType.Identifier)
+ {
+ //this.offset = 0;
+ this.length = (int)length;
+ ulong hcode = 0;
+ for (uint i = 0; i < length; i++)
+ {
+ byte b = *(pointer + i);
+ if ((b & 0x80) != 0) goto doUTF8decoding;
+ hcode = hcode * 17 + b;
+ }
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ this.name = new string((sbyte*)pointer, 0, this.length, Encoding.ASCII);
+ return;
+ doUTF8decoding:
+ string name = this.name = new string((sbyte*)pointer, 0, this.length, Encoding.UTF8);
+ for (int i = 0, n = this.length = name.Length; i < n; i++)
+ {
+ char ch = name[i];
+ hcode = hcode * 17 + ch;
+ }
+ this.hashCode = ((int)hcode) & int.MaxValue;
+ }
+ /// <summary>
+ /// Use when pointer points to a string of UTF8 code points of a given length
+ /// </summary>
+ internal unsafe static Identifier/*!*/ For(byte* pointer, uint length)
+ {
+ //TODO: first look for identifier in cache
+ return new Identifier(pointer, length);
+ }
+ private static readonly object/*!*/ Lock = new object();
+ private struct CanonicalIdentifier
+ {
+ internal string/*!*/ Name;
+ internal int UniqueIdKey;
+ internal int HashCode;
+
+ internal CanonicalIdentifier(string/*!*/ name, int uniqueIdKey, int hashCode)
+ {
+ this.Name = name;
+ this.UniqueIdKey = uniqueIdKey;
+ this.HashCode = hashCode;
+ }
+ }
+ private static CanonicalIdentifier[]/*!*/ HashTable = new CanonicalIdentifier[16 * 1024];
+ private static int count;
+ private int GetUniqueIdKey()
+ {
+ lock (Identifier.Lock)
+ {
+ int hcode = this.hashCode;
+ CanonicalIdentifier[] hTable = Identifier.HashTable;
+ int length = hTable.Length;
+ int i = hcode % length;
+ CanonicalIdentifier id = hTable[i];
+ while (id.Name != null)
+ {
+ if (this.HasSameNameAs(id)) return id.UniqueIdKey;
+ i = (i + 1) % length;
+ id = hTable[i];
+ }
+ int count = Identifier.count;
+ int countp1 = count + 1;
+ Identifier.count = countp1;
+ string name = this.Name; //Get a local copy of the name and drop any reference to a DocumentText instance
+ hTable[i] = new CanonicalIdentifier(name, countp1, hcode);
+ if (countp1 > length / 2) Rehash(); //Threshold exceeded, need to rehash
+ return countp1;
+ }
+ }
+ private unsafe bool HasSameNameAs(CanonicalIdentifier id)
+ {
+ int myLength = this.length;
+ int idLength = id.Name.Length;
+ if (myLength != idLength) return false;
+ string myName = this.name;
+ string idName = id.Name;
+#if !FxCop
+ if (myName == null)
+ {
+ int myOffset = this.offset;
+ if (this.text != null && this.text.Equals(idName, myOffset, myLength))
+ {
+ this.name = idName;
+ this.text = null;
+ return true;
+ }
+ return false;
+ }
+#endif
+ return myName == idName;
+ }
+ public string/*!*/ Name
+ { //TODO: need a better name for this property
+ get
+ {
+#if !FxCop
+ if (this.name != null) return this.name;
+ lock (this)
+ {
+ if (this.name != null) return this.name;
+ //^ assume this.text != null;
+ int length = this.length;
+ int offset = this.offset;
+ this.name = this.text.Substring(offset, length);
+ this.text = null;
+ return this.name;
+ }
+#else
+ return this.name;
+#endif
+ }
+ }
+ private static void Rehash()
+ {
+ CanonicalIdentifier[] hTable = Identifier.HashTable;
+ int n = hTable.Length;
+ int n2 = n * 2;
+ CanonicalIdentifier[] newhTable = new CanonicalIdentifier[n2];
+ for (int i = 0; i < n; i++)
+ {
+ CanonicalIdentifier id = hTable[i];
+ if (id.Name == null) continue;
+ int j = id.HashCode % n2;
+ CanonicalIdentifier id2 = newhTable[j];
+ while (id2.Name != null)
+ {
+ j = (j + 1) % n2;
+ id2 = newhTable[j];
+ }
+ newhTable[j] = id;
+ }
+ Identifier.HashTable = newhTable;
+ }
+ public override string/*!*/ ToString()
+ {
+#if !MinimalReader
+ if (this.Prefix != null)
+ return this.Prefix.Name + ":" + this.Name;
+#endif
+ if (this.Name == null) return "";
+ return this.Name;
+ }
+ private int uniqueIdKey;
+ /// <summary>
+ /// Returns an integer that is the same for every Identifier instance that has the same string value, and that is different from
+ /// every other identifier instance that has a different string value. Useful for efficient equality tests when hashing identifiers.
+ /// </summary>
+ public int UniqueIdKey
+ {
+ get
+ {
+ int result = this.uniqueIdKey;
+ if (result != 0) return result;
+ return this.uniqueIdKey = this.GetUniqueIdKey();
+ }
+ }
+ [Obsolete("Use Identifier.UniqueIdKey instead")]
+ public new int UniqueKey
+ {
+ get
+ {
+ int result = this.uniqueIdKey;
+ if (result != 0) return result;
+ return this.uniqueIdKey = this.GetUniqueIdKey();
+ }
+ }
+ }
+#if !MinimalReader
+ public class QualifiedIdentifier : Expression
+ {
+ public Identifier Identifier;
+ public Expression Qualifier;
+ public Expression BoundMember;
+ public bool QualifierIsNamespace;
+
+ public QualifiedIdentifier()
+ : base(NodeType.QualifiedIdentifer)
+ {
+ }
+ public QualifiedIdentifier(Expression qualifier, Identifier identifier)
+ : base(NodeType.QualifiedIdentifer)
+ {
+ this.Identifier = identifier;
+ this.Qualifier = qualifier;
+ }
+ public QualifiedIdentifier(Expression qualifier, Identifier identifier, SourceContext sourceContext)
+ : base(NodeType.QualifiedIdentifer)
+ {
+ this.Identifier = identifier;
+ this.Qualifier = qualifier;
+ this.SourceContext = sourceContext;
+ }
+ public QualifiedIdentifier(Expression qualifier, Identifier identifier, SourceContext sourceContext, bool qualifierIsNamespace)
+ : base(NodeType.QualifiedIdentifer)
+ {
+ this.Identifier = identifier;
+ this.Qualifier = qualifier;
+ this.SourceContext = sourceContext;
+ this.QualifierIsNamespace = qualifierIsNamespace;
+ }
+ public override string/*!*/ ToString()
+ {
+ string str = this.Identifier == null ? "" : this.Identifier.ToString();
+ if (this.Qualifier == null) return str;
+ string separator = this.QualifierIsNamespace ? "::" : "+";
+ return this.Qualifier.ToString() + separator + str;
+ }
+ }
+ public class Quantifier : Expression
+ {
+ public NodeType QuantifierType;
+ public TypeNode SourceType; // the type of elements the quantifier consumes
+ public Comprehension Comprehension;
+ public Quantifier()
+ : base(NodeType.Quantifier)
+ {
+ }
+ public Quantifier(Comprehension comprehension)
+ : base(NodeType.Quantifier)
+ {
+ this.Comprehension = comprehension;
+ }
+ public Quantifier(NodeType t, Comprehension comprehension)
+ : base(NodeType.Quantifier)
+ {
+ this.QuantifierType = t;
+ this.Comprehension = comprehension;
+ }
+ }
+ public enum ComprehensionBindingMode { In, Gets };
+ public class ComprehensionBinding : Expression
+ {
+ public ComprehensionBindingMode Mode = ComprehensionBindingMode.In;
+ public TypeNode TargetVariableType;
+ public TypeNode TargetVariableTypeExpression;
+ public Expression TargetVariable;
+
+ public TypeNode AsTargetVariableType;
+ public TypeNode AsTargetVariableTypeExpression;
+
+ public Expression SourceEnumerable;
+ public BlockScope ScopeForTemporaryVariables;
+ public ComprehensionBinding()
+ : base(NodeType.ComprehensionBinding)
+ {
+ }
+ }
+ public enum ComprehensionMode { Reduction, Comprehension };
+ // {1,2,3} ==> Comprehension with BindingsAndFilters = null and Elements = [1,2,3]
+ // i.e., for a "display", there are no bindings and the elements have one entry per value in the comprehension
+ // { int x in A, P(x); T(x); default } ==> Comprehension with BindingsAndFilters = [int x in A, P(x)] and Elements = [T(x), default]
+ // i.e., for "true" comprehensions, the list of elements will always have either one or two elements (two if there is a default)
+ public class Comprehension : Expression
+ {
+ public ComprehensionMode Mode = ComprehensionMode.Comprehension;
+ public ExpressionList BindingsAndFilters;
+ public ExpressionList Elements;
+
+ public Node nonEnumerableTypeCtor; // used only when the comprehension should generate code for an IList, e.g.
+ public Method AddMethod; // used only when the comprehension should generate code for an IList, e.g.
+ public TypeNode TemporaryHackToHoldType;
+
+ public Comprehension()
+ : base(NodeType.Comprehension)
+ {
+ }
+
+ public bool IsDisplay
+ {
+ get
+ {
+ return this.BindingsAndFilters == null;
+ }
+ }
+ }
+ public class NameBinding : Expression
+ {
+ public Identifier Identifier;
+ public MemberList BoundMembers;
+ public Expression BoundMember;
+ public int LexLevel;
+ public Class MostNestedScope;
+ public NameBinding()
+ : base(NodeType.NameBinding)
+ {
+ }
+ public NameBinding(Identifier identifier, MemberList boundMembers)
+ : base(NodeType.NameBinding)
+ {
+ this.Identifier = identifier;
+ this.BoundMembers = boundMembers;
+ }
+ public NameBinding(Identifier identifier, MemberList boundMembers, SourceContext sctx)
+ : base(NodeType.NameBinding)
+ {
+ this.Identifier = identifier;
+ this.BoundMembers = boundMembers;
+ this.SourceContext = sctx;
+ }
+ public NameBinding(Identifier identifier, MemberList boundMembers, Class mostNestedScope, int lexLevel)
+ : base(NodeType.NameBinding)
+ {
+ this.Identifier = identifier;
+ this.BoundMembers = boundMembers;
+ this.LexLevel = lexLevel;
+ this.MostNestedScope = mostNestedScope;
+ }
+ public NameBinding(Identifier identifier, MemberList boundMembers, Class mostNestedScope, int lexLevel, SourceContext sctx)
+ : base(NodeType.NameBinding)
+ {
+ this.Identifier = identifier;
+ this.BoundMembers = boundMembers;
+ this.LexLevel = lexLevel;
+ this.MostNestedScope = mostNestedScope;
+ this.SourceContext = sctx;
+ }
+ public override string ToString()
+ {
+ return this.Identifier == null ? "" : this.Identifier.ToString();
+ }
+ }
+ public class TemplateInstance : Expression
+ {
+ public Expression Expression;
+ public TypeNodeList TypeArguments;
+ public TypeNodeList TypeArgumentExpressions;
+ public bool IsMethodTemplate;
+ public MemberList BoundMembers;
+
+ public TemplateInstance()
+ : this(null, null)
+ {
+ }
+ public TemplateInstance(Expression expression, TypeNodeList typeArguments)
+ : base(NodeType.TemplateInstance)
+ {
+ this.Expression = expression;
+ this.TypeArguments = typeArguments;
+ }
+ }
+ public class StackAlloc : Expression
+ {
+ public TypeNode ElementType;
+ public TypeNode ElementTypeExpression;
+ public Expression NumberOfElements;
+
+ public StackAlloc()
+ : base(NodeType.StackAlloc)
+ {
+ }
+ public StackAlloc(TypeNode elementType, Expression numberOfElements, SourceContext sctx)
+ : base(NodeType.StackAlloc)
+ {
+ this.ElementType = this.ElementTypeExpression = elementType;
+ this.NumberOfElements = numberOfElements;
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+ public class MethodCall : NaryExpression
+ {
+ private Expression callee;
+ private TypeNode constraint;
+ private bool isTailCall;
+#if !MinimalReader
+ public Expression CalleeExpression;
+ public bool GiveErrorIfSpecialNameMethod;
+ public bool ArgumentListIsIncomplete;
+ public MethodCall()
+ {
+ this.NodeType = NodeType.MethodCall;
+ }
+ public MethodCall(Expression callee, ExpressionList arguments)
+ : base(arguments, NodeType.MethodCall)
+ {
+ this.callee = this.CalleeExpression = callee;
+ this.isTailCall = false;
+ }
+#endif
+ public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall)
+ : base(arguments, typeOfCall)
+ {
+ this.callee = callee;
+#if !MinimalReader
+ this.CalleeExpression = callee;
+#endif
+ //this.isTailCall = false;
+ }
+#if !MinimalReader
+ public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall, TypeNode resultType)
+ : this(callee, arguments, typeOfCall)
+ {
+ this.Type = resultType;
+ }
+ public MethodCall(Expression callee, ExpressionList arguments, NodeType typeOfCall, TypeNode resultType, SourceContext sctx)
+ : this(callee, arguments, typeOfCall, resultType)
+ {
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Callee
+ {
+ get { return this.callee; }
+ set { this.callee = value; }
+ }
+ public bool IsTailCall
+ {
+ get { return this.isTailCall; }
+ set { this.isTailCall = value; }
+ }
+ public TypeNode Constraint
+ {
+ get { return this.constraint; }
+ set { this.constraint = value; }
+ }
+ }
+ public class Construct : NaryExpression
+ {
+ private Expression constructor;
+#if !MinimalReader
+ public Expression Owner;
+#endif
+ public Construct()
+ {
+ this.NodeType = NodeType.Construct;
+ }
+ public Construct(Expression constructor, ExpressionList arguments)
+ : base(arguments, NodeType.Construct)
+ {
+ this.constructor = constructor;
+ }
+#if !MinimalReader
+ public Construct(Expression constructor, ExpressionList arguments, SourceContext sctx)
+ : base(arguments, NodeType.Construct)
+ {
+ this.constructor = constructor;
+ this.SourceContext = sctx;
+ }
+ public Construct(Expression constructor, ExpressionList arguments, TypeNode type)
+ : base(arguments, NodeType.Construct)
+ {
+ this.constructor = constructor;
+ this.Type = type;
+ }
+ public Construct(Expression constructor, ExpressionList arguments, TypeNode type, SourceContext sctx)
+ : base(arguments, NodeType.Construct)
+ {
+ this.constructor = constructor;
+ this.Type = type;
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Constructor
+ {
+ get { return this.constructor; }
+ set { this.constructor = value; }
+ }
+ }
+ public class ConstructArray : NaryExpression
+ {
+ private TypeNode elementType;
+ private int rank;
+#if !MinimalReader
+ public TypeNode ElementTypeExpression;
+ public ExpressionList Initializers;
+ public Expression Owner;
+#endif
+ public ConstructArray()
+ {
+ this.NodeType = NodeType.ConstructArray;
+ this.rank = 1;
+ }
+ public ConstructArray(TypeNode elementType, ExpressionList sizes, ExpressionList initializers)
+ : base(sizes, NodeType.ConstructArray)
+ {
+ this.elementType = elementType;
+ this.Operands = sizes;
+ this.rank = sizes == null ? 1 : sizes.Count;
+#if !MinimalReader
+ this.Initializers = initializers;
+#endif
+ }
+#if !MinimalReader
+ public ConstructArray(TypeNode elementType, ExpressionList initializers)
+ : base(null, NodeType.ConstructArray)
+ {
+ this.elementType = elementType;
+ this.Initializers = initializers;
+ this.rank = 1;
+ if (elementType != null)
+ this.Type = elementType.GetArrayType(1);
+ }
+ public ConstructArray(TypeNode elementType, int rank, ExpressionList initializers)
+ : base(null, NodeType.ConstructArray)
+ {
+ this.elementType = elementType;
+ this.Initializers = initializers;
+ this.rank = rank;
+ if (elementType != null)
+ this.Type = elementType.GetArrayType(1);
+ }
+#endif
+ public TypeNode ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+ public int Rank
+ {
+ get { return this.rank; }
+ set { this.rank = value; }
+ }
+ }
+#if !MinimalReader
+ public class ConstructFlexArray : NaryExpression
+ {
+ public TypeNode ElementType;
+ public TypeNode ElementTypeExpression;
+ public ExpressionList Initializers;
+ public ConstructFlexArray()
+ {
+ this.NodeType = NodeType.ConstructFlexArray;
+ }
+ public ConstructFlexArray(TypeNode elementType, ExpressionList sizes, ExpressionList initializers)
+ : base(sizes, NodeType.ConstructFlexArray)
+ {
+ this.ElementType = elementType;
+ this.Operands = sizes;
+ this.Initializers = initializers;
+ }
+ }
+ public class ConstructDelegate : Expression
+ {
+ public TypeNode DelegateType;
+ public TypeNode DelegateTypeExpression;
+ public Identifier MethodName;
+ public Expression TargetObject;
+ public ConstructDelegate()
+ : base(NodeType.ConstructDelegate)
+ {
+ }
+ public ConstructDelegate(TypeNode delegateType, Expression targetObject, Identifier methodName)
+ : base(NodeType.ConstructDelegate)
+ {
+ this.DelegateType = delegateType;
+ this.MethodName = methodName;
+ this.TargetObject = targetObject;
+ }
+ public ConstructDelegate(TypeNode delegateType, Expression targetObject, Identifier methodName, SourceContext sctx)
+ : base(NodeType.ConstructDelegate)
+ {
+ this.DelegateType = delegateType;
+ this.MethodName = methodName;
+ this.TargetObject = targetObject;
+ this.SourceContext = sctx;
+ }
+ }
+ public class ConstructIterator : Expression
+ {
+ public Class State;
+ public Block Body;
+ public TypeNode ElementType;
+ public ConstructIterator()
+ : base(NodeType.ConstructIterator)
+ {
+ }
+ public ConstructIterator(Class state, Block body, TypeNode elementType, TypeNode type)
+ : base(NodeType.ConstructIterator)
+ {
+ this.State = state;
+ this.Body = body;
+ this.ElementType = elementType;
+ this.Type = type;
+ }
+ }
+ public class ConstructTuple : Expression
+ {
+ public FieldList Fields;
+ public ConstructTuple()
+ : base(NodeType.ConstructTuple)
+ {
+ }
+ }
+ public class CoerceTuple : ConstructTuple
+ {
+ public Expression OriginalTuple;
+ public Local Temp;
+ public CoerceTuple()
+ {
+ this.NodeType = NodeType.CoerceTuple;
+ }
+ }
+#endif
+ public class Indexer : NaryExpression
+ {
+#if !MinimalReader
+ public Property CorrespondingDefaultIndexedProperty;
+ public bool ArgumentListIsIncomplete;
+#endif
+ public Indexer()
+ {
+ this.NodeType = NodeType.Indexer;
+ }
+ public Indexer(Expression @object, ExpressionList arguments)
+ : base(arguments, NodeType.Indexer)
+ {
+ this.@object = @object;
+ }
+#if !MinimalReader
+ public Indexer(Expression Object, ExpressionList arguments, SourceContext sctx)
+ : base(arguments, NodeType.Indexer)
+ {
+ this.@object = Object;
+ this.SourceContext = sctx;
+ }
+ public Indexer(Expression Object, ExpressionList arguments, TypeNode elementType)
+ : base(arguments, NodeType.Indexer)
+ {
+ this.@object = Object;
+ this.elementType = this.Type = elementType;
+ }
+ public Indexer(Expression Object, ExpressionList arguments, TypeNode elementType, SourceContext sctx)
+ : base(arguments, NodeType.Indexer)
+ {
+ this.@object = Object;
+ this.elementType = this.Type = elementType;
+ this.SourceContext = sctx;
+ }
+#endif
+ private Expression @object;
+ public Expression Object
+ {
+ get { return this.@object; }
+ set { this.@object = value; }
+ }
+ private TypeNode elementType;
+ /// <summary>
+ /// This type is normally expected to be the same the value of Type. However, if the indexer applies to an array of enums, then
+ /// Type will be the enum type and ElementType will be the underlying type of the enum.
+ /// </summary>
+ public TypeNode ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+ }
+#if !MinimalReader
+ public class CollectionEnumerator : Expression
+ {
+ public Expression Collection;
+ public Method DefaultIndexerGetter;
+ public Method LengthPropertyGetter;
+ public Method GetEnumerator;
+ public Method MoveNext;
+ public Method GetCurrent;
+ public Local ElementLocal;
+ public Expression ElementCoercion;
+ public CollectionEnumerator()
+ : base(NodeType.CollectionEnumerator)
+ {
+ }
+ }
+ /// <summary>
+ /// An expression that is used on the left hand as well as the right hand side of an assignment statement. For example, e in (e += 1).
+ /// </summary>
+ public class LRExpression : Expression
+ {
+ public Expression Expression;
+ public LocalList Temporaries;
+ public ExpressionList SubexpressionsToEvaluateOnce;
+ public LRExpression(Expression/*!*/ expression)
+ : base(NodeType.LRExpression)
+ {
+ this.Expression = expression;
+ this.Type = expression.Type;
+ }
+ }
+ public class AssignmentExpression : Expression
+ {
+ public Statement AssignmentStatement;
+ public AssignmentExpression()
+ : base(NodeType.AssignmentExpression)
+ {
+ }
+ public AssignmentExpression(AssignmentStatement assignment)
+ : base(NodeType.AssignmentExpression)
+ {
+ this.AssignmentStatement = assignment;
+ }
+ }
+#endif
+#if !MinimalReader || FxCop
+ public class BlockExpression : Expression
+ {
+ public Block Block;
+ public BlockExpression()
+ : base(NodeType.BlockExpression)
+ {
+ }
+ public BlockExpression(Block block)
+ : base(NodeType.BlockExpression)
+ {
+ this.Block = block;
+ }
+ public BlockExpression(Block block, TypeNode type)
+ : base(NodeType.BlockExpression)
+ {
+ this.Block = block;
+ this.Type = type;
+ }
+ public BlockExpression(Block block, TypeNode type, SourceContext sctx)
+ : base(NodeType.BlockExpression)
+ {
+ this.Block = block;
+ this.Type = type;
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+#if !MinimalReader
+ public class AnonymousNestedFunction : Expression
+ {
+ public ParameterList Parameters;
+ public Block Body;
+ public Method Method;
+ public Expression Invocation;
+
+ public AnonymousNestedFunction()
+ : base(NodeType.AnonymousNestedFunction)
+ {
+ }
+ public AnonymousNestedFunction(ParameterList parameters, Block body)
+ : base(NodeType.AnonymousNestedFunction)
+ {
+ this.Parameters = parameters;
+ this.Body = body;
+ }
+ public AnonymousNestedFunction(ParameterList parameters, Block body, SourceContext sctx)
+ : base(NodeType.AnonymousNestedFunction)
+ {
+ this.Parameters = parameters;
+ this.Body = body;
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+ public class Instruction : Node
+ {
+ private OpCode opCode;
+ private int offset;
+ private object value;
+ public Instruction()
+ : base(NodeType.Instruction)
+ {
+ }
+ public Instruction(OpCode opCode, int offset)
+ : this(opCode, offset, null)
+ {
+ }
+ public Instruction(OpCode opCode, int offset, object value)
+ : base(NodeType.Instruction)
+ {
+ this.opCode = opCode;
+ this.offset = offset;
+ this.value = value;
+ }
+ /// <summary>The actual value of the opcode</summary>
+ public OpCode OpCode
+ {
+ get { return this.opCode; }
+ set { this.opCode = value; }
+ }
+ /// <summary>The offset from the start of the instruction stream of a method</summary>
+ public int Offset
+ {
+ get { return this.offset; }
+ set { this.offset = value; }
+ }
+ /// <summary>Immediate data such as a string, the address of a branch target, or a metadata reference, such as a Field</summary>
+ public object Value
+ {
+ get { return this.value; }
+ set { this.value = value; }
+ }
+ }
+ public class Statement : Node
+ {
+#if FxCop
+ internal int ILOffset;
+#endif
+ public Statement(NodeType nodeType)
+ : base(nodeType)
+ {
+ }
+#if !MinimalReader
+ public Statement(NodeType nodeType, SourceContext sctx)
+ : base(nodeType)
+ {
+ this.SourceContext = sctx;
+ }
+#endif
+ }
+ public class Block : Statement
+ {
+ private StatementList statements;
+#if !MinimalReader
+ public bool Checked;
+ public bool SuppressCheck;
+#endif
+#if !MinimalReader || !NoWriter
+ public bool HasLocals;
+#endif
+#if !MinimalReader
+ public bool IsUnsafe;
+ public BlockScope Scope;
+#endif
+ public Block()
+ : base(NodeType.Block)
+ {
+ }
+ public Block(StatementList statements)
+ : base(NodeType.Block)
+ {
+ this.statements = statements;
+ }
+#if !MinimalReader
+ public Block(StatementList statements, SourceContext sourceContext)
+ : base(NodeType.Block)
+ {
+ this.SourceContext = sourceContext;
+ this.statements = statements;
+ }
+ public Block(StatementList statements, bool Checked, bool SuppressCheck, bool IsUnsafe)
+ : base(NodeType.Block)
+ {
+ this.Checked = Checked;
+ this.IsUnsafe = IsUnsafe;
+ this.SuppressCheck = SuppressCheck;
+ this.statements = statements;
+ }
+ public Block(StatementList statements, SourceContext sourceContext, bool Checked, bool SuppressCheck, bool IsUnsafe)
+ : base(NodeType.Block)
+ {
+ this.Checked = Checked;
+ this.IsUnsafe = IsUnsafe;
+ this.SuppressCheck = SuppressCheck;
+ this.SourceContext = sourceContext;
+ this.statements = statements;
+ }
+ public override string ToString()
+ {
+ return "B#" + this.UniqueKey.ToString();
+ }
+#endif
+ public StatementList Statements
+ {
+ get { return this.statements; }
+ set { this.statements = value; }
+ }
+ }
+#if !MinimalReader
+ public class LabeledStatement : Block
+ {
+ public Identifier Label;
+ public Statement Statement;
+ public LabeledStatement()
+ {
+ this.NodeType = NodeType.LabeledStatement;
+ }
+ }
+ public class FunctionDeclaration : Statement
+ {
+ public Identifier Name;
+ public ParameterList Parameters;
+ public TypeNode ReturnType;
+ public TypeNode ReturnTypeExpression;
+ public Block Body;
+ public Method Method;
+
+ public FunctionDeclaration()
+ : base(NodeType.FunctionDeclaration)
+ {
+ }
+ public FunctionDeclaration(Identifier name, ParameterList parameters, TypeNode returnType, Block body)
+ : base(NodeType.FunctionDeclaration)
+ {
+ this.Name = name;
+ this.Parameters = parameters;
+ this.ReturnType = returnType;
+ this.Body = body;
+ }
+ }
+ public class Assertion : Statement
+ {
+ public Expression Condition;
+ public Assertion()
+ : base(NodeType.Assertion)
+ {
+ }
+ public Assertion(Expression condition)
+ : base(NodeType.Assertion)
+ {
+ this.Condition = condition;
+ }
+ }
+ public class Assumption : Statement
+ {
+ public Expression Condition;
+ public Assumption()
+ : base(NodeType.Assumption)
+ {
+ }
+ public Assumption(Expression condition)
+ : base(NodeType.Assumption)
+ {
+ this.Condition = condition;
+ }
+ }
+#endif
+ public class AssignmentStatement : Statement
+ {
+ private NodeType @operator;
+ private Expression source;
+ private Expression target;
+#if !MinimalReader
+ public Method OperatorOverload;
+ ///<summary>A Type two which both operands must be coerced before carrying out the operation (if any).</summary>
+ public TypeNode UnifiedType;
+#endif
+ public AssignmentStatement()
+ : base(NodeType.AssignmentStatement)
+ {
+ this.Operator = NodeType.Nop;
+ }
+ public AssignmentStatement(Expression target, Expression source)
+ : this(target, source, NodeType.Nop)
+ {
+ }
+#if !MinimalReader
+ public AssignmentStatement(Expression target, Expression source, SourceContext context)
+ : this(target, source, NodeType.Nop)
+ {
+ this.SourceContext = context;
+ }
+#endif
+ public AssignmentStatement(Expression target, Expression source, NodeType @operator)
+ : base(NodeType.AssignmentStatement)
+ {
+ this.target = target;
+ this.source = source;
+ this.@operator = @operator;
+ }
+#if !MinimalReader
+ public AssignmentStatement(Expression target, Expression source, NodeType Operator, SourceContext context)
+ : this(target, source, Operator)
+ {
+ this.SourceContext = context;
+ }
+#endif
+ public NodeType Operator
+ {
+ get { return this.@operator; }
+ set { this.@operator = value; }
+ }
+ public Expression Source
+ {
+ get { return this.source; }
+ set { this.source = value; }
+ }
+ public Expression Target
+ {
+ get { return this.target; }
+ set { this.target = value; }
+ }
+ }
+ public class ExpressionStatement : Statement
+ {
+ private Expression expression;
+ public ExpressionStatement()
+ : base(NodeType.ExpressionStatement)
+ {
+ }
+ public ExpressionStatement(Expression expression)
+ : base(NodeType.ExpressionStatement)
+ {
+ this.Expression = expression;
+ }
+#if !MinimalReader
+ public ExpressionStatement(Expression expression, SourceContext sctx)
+ : base(NodeType.ExpressionStatement)
+ {
+ this.Expression = expression;
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Expression
+ {
+ get { return this.expression; }
+ set { this.expression = value; }
+ }
+ }
+ public class Branch : Statement
+ {
+ private Expression condition;
+ private bool leavesExceptionBlock;
+ internal bool shortOffset;
+ private Block target;
+ public bool BranchIfUnordered;
+ public Branch()
+ : base(NodeType.Branch)
+ {
+ }
+#if !MinimalReader
+ public Branch(Expression condition, Block target)
+ : this(condition, target, false, false, false)
+ {
+ }
+ public Branch(Expression condition, Block target, SourceContext sourceContext)
+ : this(condition, target, false, false, false)
+ {
+ this.SourceContext = sourceContext;
+ }
+ public Branch(Expression condition, Block target, SourceContext sourceContext, bool unordered)
+ : this(condition, target, false, false, false)
+ {
+ this.BranchIfUnordered = unordered;
+ this.SourceContext = sourceContext;
+ }
+#endif
+ public Branch(Expression condition, Block target, bool shortOffset, bool unordered, bool leavesExceptionBlock)
+ : base(NodeType.Branch)
+ {
+ this.BranchIfUnordered = unordered;
+ this.condition = condition;
+ this.leavesExceptionBlock = leavesExceptionBlock;
+ this.shortOffset = shortOffset;
+ this.target = target;
+ }
+ public Expression Condition
+ {
+ get { return this.condition; }
+ set { this.condition = value; }
+ }
+ public bool LeavesExceptionBlock
+ {
+ get { return this.leavesExceptionBlock; }
+ set { this.leavesExceptionBlock = value; }
+ }
+ public bool ShortOffset
+ {
+ get { return this.shortOffset; }
+ set { this.shortOffset = value; }
+ }
+ public Block Target
+ {
+ get { return this.target; }
+ set { this.target = value; }
+ }
+ }
+#if FxCop
+ public class ReturnNode : ExpressionStatement{
+ public ReturnNode()
+#else
+ public class Return : ExpressionStatement
+ {
+ public Return()
+#endif
+ : base()
+ {
+ this.NodeType = NodeType.Return;
+ }
+#if FxCop
+ public ReturnNode(Expression expression)
+#else
+ public Return(Expression expression)
+#endif
+ : base(expression)
+ {
+ this.NodeType = NodeType.Return;
+ }
+#if !MinimalReader
+ public Return(SourceContext sctx)
+ : base()
+ {
+ this.NodeType = NodeType.Return;
+ this.SourceContext = sctx;
+ }
+ public Return(Expression expression, SourceContext sctx)
+ : base(expression)
+ {
+ this.NodeType = NodeType.Return;
+ this.SourceContext = sctx;
+ }
+#endif
+ }
+#if !MinimalReader
+ public class Yield : ExpressionStatement
+ {
+ public Yield()
+ : base()
+ {
+ this.NodeType = NodeType.Yield;
+ }
+ public Yield(Expression expression)
+ : base(expression)
+ {
+ this.NodeType = NodeType.Yield;
+ }
+ public Yield(Expression expression, SourceContext sctx)
+ : base(expression)
+ {
+ this.NodeType = NodeType.Yield;
+ this.SourceContext = sctx;
+ }
+ }
+ public class Try : Statement
+ {
+ private CatchList catchers;
+ private FilterList filters;
+ private FaultHandlerList faultHandlers;
+ private Finally finallyClause;
+ private Block tryBlock;
+ public Try()
+ : base(NodeType.Try)
+ {
+ }
+ public Try(Block tryBlock, CatchList catchers, FilterList filters, FaultHandlerList faultHandlers, Finally Finally)
+ : base(NodeType.Try)
+ {
+ this.catchers = catchers;
+ this.faultHandlers = faultHandlers;
+ this.filters = filters;
+ this.finallyClause = Finally;
+ this.tryBlock = tryBlock;
+ }
+ public CatchList Catchers
+ {
+ get { return this.catchers; }
+ set { this.catchers = value; }
+ }
+ public FilterList Filters
+ {
+ get { return this.filters; }
+ set { this.filters = value; }
+ }
+ public FaultHandlerList FaultHandlers
+ {
+ get { return this.faultHandlers; }
+ set { this.faultHandlers = value; }
+ }
+ public Finally Finally
+ {
+ get { return this.finallyClause; }
+ set { this.finallyClause = value; }
+ }
+ public Block TryBlock
+ {
+ get { return this.tryBlock; }
+ set { this.tryBlock = value; }
+ }
+ }
+ public class Catch : Statement
+ {
+ private Block block;
+ private TypeNode type;
+ private Expression variable;
+ public TypeNode TypeExpression;
+ public Catch()
+ : base(NodeType.Catch)
+ {
+ }
+ public Catch(Block block, Expression variable, TypeNode type)
+ : base(NodeType.Catch)
+ {
+ this.block = block;
+ this.variable = variable;
+ this.type = type;
+ }
+ public Block Block
+ {
+ get { return this.block; }
+ set { this.block = value; }
+ }
+ public TypeNode Type
+ {
+ get { return this.type; }
+ set { this.type = value; }
+ }
+ public Expression Variable
+ {
+ get { return this.variable; }
+ set { this.variable = value; }
+ }
+ }
+ public class Finally : Statement
+ {
+ private Block block;
+ public Finally()
+ : base(NodeType.Finally)
+ {
+ }
+ public Finally(Block block)
+ : base(NodeType.Finally)
+ {
+ this.block = block;
+ }
+ public Block Block
+ {
+ get { return this.block; }
+ set { this.block = value; }
+ }
+ }
+#endif
+ public class EndFinally : Statement
+ {
+ public EndFinally()
+ : base(NodeType.EndFinally)
+ {
+ }
+ }
+#if !MinimalReader || FxCop
+ public class Filter : Statement
+ {
+ private Block block;
+ private Expression expression;
+#if FxCop
+ internal int handlerEnd;
+#endif
+ public Filter()
+ : base(NodeType.Filter)
+ {
+ }
+ public Filter(Block block, Expression expression)
+ : base(NodeType.Filter)
+ {
+ this.block = block;
+ this.expression = expression;
+ }
+ public Block Block
+ {
+ get { return this.block; }
+ set { this.block = value; }
+ }
+ public Expression Expression
+ {
+ get { return this.expression; }
+ set { this.expression = value; }
+ }
+ }
+#endif
+ public class EndFilter : Statement
+ {
+ private Expression value;
+ public EndFilter()
+ : base(NodeType.EndFilter)
+ {
+ }
+ public EndFilter(Expression value)
+ : base(NodeType.EndFilter)
+ {
+ this.value = value;
+ }
+ public Expression Value
+ {
+ get { return this.value; }
+ set { this.value = value; }
+ }
+ }
+#if !MinimalReader || FxCop
+ public class FaultHandler : Statement
+ {
+ private Block block;
+#if FxCop
+ internal int handlerEnd;
+#endif
+ public FaultHandler()
+ : base(NodeType.FaultHandler)
+ {
+ }
+ public FaultHandler(Block block)
+ : base(NodeType.FaultHandler)
+ {
+ this.block = block;
+ }
+ public Block Block
+ {
+ get { return this.block; }
+ set { this.block = value; }
+ }
+ }
+#endif
+#if FxCop
+ public class ThrowNode : Statement{
+#else
+ public class Throw : Statement
+ {
+#endif
+ private Expression expression;
+#if FxCop
+ public ThrowNode()
+ : base(NodeType.Throw){
+ }
+ public ThrowNode(Expression expression)
+ : base(NodeType.Throw){
+ this.expression = expression;
+ }
+#else
+ public Throw()
+ : base(NodeType.Throw)
+ {
+ }
+ public Throw(Expression expression)
+ : base(NodeType.Throw)
+ {
+ this.expression = expression;
+ }
+#endif
+#if !MinimalReader
+ public Throw(Expression expression, SourceContext context)
+ : base(NodeType.Throw)
+ {
+ this.expression = expression;
+ this.SourceContext = context;
+ }
+#endif
+ public Expression Expression
+ {
+ get { return this.expression; }
+ set { this.expression = value; }
+ }
+ }
+#if !MinimalReader
+ public class If : Statement
+ {
+ public Expression Condition;
+ public Block TrueBlock;
+ public Block FalseBlock;
+ public SourceContext ConditionContext;
+ public SourceContext ElseContext;
+ public SourceContext EndIfContext;
+ public If()
+ : base(NodeType.If)
+ {
+ }
+ public If(Expression condition, Block trueBlock, Block falseBlock)
+ : base(NodeType.If)
+ {
+ this.Condition = condition;
+ if (condition != null)
+ this.ConditionContext = condition.SourceContext;
+ this.TrueBlock = trueBlock;
+ this.FalseBlock = falseBlock;
+ }
+ }
+ public class For : Statement
+ {
+ public Block Body;
+ public Expression Condition;
+ public StatementList Incrementer;
+ public StatementList Initializer;
+ public ExpressionList Invariants;
+ public For()
+ : base(NodeType.For)
+ {
+ }
+ public For(StatementList initializer, Expression condition, StatementList incrementer, Block body)
+ : base(NodeType.For)
+ {
+ this.Body = body;
+ this.Condition = condition;
+ this.Incrementer = incrementer;
+ this.Initializer = initializer;
+ }
+ }
+ public class ForEach : Statement
+ {
+ public Block Body;
+ public Expression SourceEnumerable;
+ public BlockScope ScopeForTemporaryVariables;
+ public Expression TargetVariable;
+ public TypeNode TargetVariableType;
+ public TypeNode TargetVariableTypeExpression;
+ public Expression InductionVariable;
+ public ExpressionList Invariants;
+ public bool StatementTerminatesNormallyIfEnumerableIsNull = true;
+ public bool StatementTerminatesNormallyIfEnumeratorIsNull = true;
+ public ForEach()
+ : base(NodeType.ForEach)
+ {
+ }
+ public ForEach(TypeNode targetVariableType, Expression targetVariable, Expression sourceEnumerable, Block body)
+ : base(NodeType.ForEach)
+ {
+ this.TargetVariable = targetVariable;
+ this.TargetVariableType = targetVariableType;
+ this.SourceEnumerable = sourceEnumerable;
+ this.Body = body;
+ }
+ }
+ public class Exit : Statement
+ {
+ public Literal Level;
+ public Exit()
+ : base(NodeType.Exit)
+ {
+ }
+ public Exit(Literal level)
+ : base(NodeType.Exit)
+ {
+ this.Level = level;
+ }
+ }
+ public class Continue : Statement
+ {
+ public Literal Level;
+ public Continue()
+ : base(NodeType.Continue)
+ {
+ }
+ public Continue(Literal level)
+ : base(NodeType.Continue)
+ {
+ this.Level = level;
+ }
+ }
+ public class Switch : Statement
+ {
+ public SwitchCaseList Cases;
+ public Expression Expression;
+ public Local Nullable;
+ public Expression NullableExpression;
+ public BlockScope Scope;
+ public Switch()
+ : base(NodeType.Switch)
+ {
+ }
+ public Switch(Expression expression, SwitchCaseList cases)
+ : base(NodeType.Switch)
+ {
+ this.Cases = cases;
+ this.Expression = expression;
+ }
+ }
+ public class SwitchCase : Node
+ {
+ public Block Body;
+ public Expression Label;
+ public SwitchCase()
+ : base(NodeType.SwitchCase)
+ {
+ }
+ public SwitchCase(Expression label, Block body)
+ : base(NodeType.SwitchCase)
+ {
+ this.Body = body;
+ this.Label = label;
+ }
+ }
+ public class GotoCase : Statement
+ {
+ public Expression CaseLabel;
+ public GotoCase(Expression caseLabel)
+ : base(NodeType.GotoCase)
+ {
+ this.CaseLabel = caseLabel;
+ }
+ }
+#endif
+ public class SwitchInstruction : Statement
+ {
+ private Expression expression;
+ private BlockList targets;
+ public SwitchInstruction()
+ : base(NodeType.SwitchInstruction)
+ {
+ }
+ public SwitchInstruction(Expression expression, BlockList targets)
+ : base(NodeType.SwitchInstruction)
+ {
+ this.expression = expression;
+ this.targets = targets;
+ }
+ public Expression Expression
+ {
+ get { return this.expression; }
+ set { this.expression = value; }
+ }
+ public BlockList Targets
+ {
+ get { return this.targets; }
+ set { this.targets = value; }
+ }
+ }
+#if !MinimalReader
+ public class Typeswitch : Statement
+ {
+ public TypeswitchCaseList Cases;
+ public Expression Expression;
+ public Typeswitch()
+ : base(NodeType.Typeswitch)
+ {
+ }
+ public Typeswitch(Expression expression, TypeswitchCaseList cases)
+ : base(NodeType.Typeswitch)
+ {
+ this.Cases = cases;
+ this.Expression = expression;
+ }
+ }
+ public class TypeswitchCase : Node
+ {
+ public Block Body;
+ public TypeNode LabelType;
+ public TypeNode LabelTypeExpression;
+ public Expression LabelVariable;
+ public TypeswitchCase()
+ : base(NodeType.TypeswitchCase)
+ {
+ }
+ public TypeswitchCase(TypeNode labelType, Expression labelVariable, Block body)
+ : base(NodeType.TypeswitchCase)
+ {
+ this.Body = body;
+ this.LabelType = labelType;
+ this.LabelVariable = labelVariable;
+ }
+ }
+ public class While : Statement
+ {
+ public Expression Condition;
+ public ExpressionList Invariants;
+ public Block Body;
+ public While()
+ : base(NodeType.While)
+ {
+ }
+ public While(Expression condition, Block body)
+ : base(NodeType.While)
+ {
+ this.Condition = condition;
+ this.Body = body;
+ }
+ }
+ public class DoWhile : Statement
+ {
+ public Expression Condition;
+ public ExpressionList Invariants;
+ public Block Body;
+ public DoWhile()
+ : base(NodeType.DoWhile)
+ {
+ }
+ public DoWhile(Expression condition, Block body)
+ : base(NodeType.DoWhile)
+ {
+ this.Condition = condition;
+ this.Body = body;
+ }
+ }
+ public class Repeat : Statement
+ {
+ public Expression Condition;
+ public Block Body;
+ public Repeat()
+ : base(NodeType.Repeat)
+ {
+ }
+ public Repeat(Expression condition, Block body)
+ : base(NodeType.Repeat)
+ {
+ this.Condition = condition;
+ this.Body = body;
+ }
+ }
+ public class Fixed : Statement
+ {
+ public Statement Declarators;
+ public Block Body;
+ public BlockScope ScopeForTemporaryVariables;
+ public Fixed()
+ : base(NodeType.Fixed)
+ {
+ }
+ }
+ public class Lock : Statement
+ {
+ public Expression Guard;
+ public Block Body;
+ public BlockScope ScopeForTemporaryVariable;
+ public Lock()
+ : base(NodeType.Lock)
+ {
+ }
+ }
+ public class ResourceUse : Statement
+ {
+ public Statement ResourceAcquisition;
+ public Block Body;
+ public BlockScope ScopeForTemporaryVariable;
+ public ResourceUse()
+ : base(NodeType.ResourceUse)
+ {
+ }
+ }
+ public class Goto : Statement
+ {
+ public Identifier TargetLabel;
+ public Goto()
+ : base(NodeType.Goto)
+ {
+ }
+ public Goto(Identifier targetLabel)
+ : base(NodeType.Goto)
+ {
+ this.TargetLabel = targetLabel;
+ }
+ }
+ public class VariableDeclaration : Statement
+ {
+ public Expression Initializer;
+ public Identifier Name;
+ public TypeNode Type;
+ public TypeNode TypeExpression;
+ public Field Field;
+ public VariableDeclaration()
+ : base(NodeType.VariableDeclaration)
+ {
+ }
+ public VariableDeclaration(Identifier name, TypeNode type, Expression initializer)
+ : base(NodeType.VariableDeclaration)
+ {
+ this.Initializer = initializer;
+ this.Name = name;
+ this.Type = type;
+ }
+ }
+ public class LocalDeclaration : Node
+ {
+ public Field Field;
+ public Identifier Name;
+ public Expression InitialValue;
+ /// <summary>
+ /// Used when converting a declaration with initializer into an assignment statement.
+ /// Usually Nop, but could be set to CopyReference to avoid dereferencing on either side.
+ /// </summary>
+ public NodeType AssignmentNodeType = NodeType.Nop;
+ public LocalDeclaration()
+ : base(NodeType.LocalDeclaration)
+ {
+ }
+ public LocalDeclaration(Identifier name, Expression initialValue)
+ : base(NodeType.LocalDeclaration)
+ {
+ this.Name = name;
+ this.InitialValue = initialValue;
+ }
+ public LocalDeclaration(Identifier name, Expression initialValue, NodeType assignmentNodeType)
+ : base(NodeType.LocalDeclaration)
+ {
+ this.Name = name;
+ this.InitialValue = initialValue;
+ this.AssignmentNodeType = assignmentNodeType;
+ }
+
+ }
+ public class LocalDeclarationsStatement : Statement
+ {
+ public bool Constant;
+ public bool InitOnly;
+ public TypeNode Type;
+ public TypeNode TypeExpression;
+ public LocalDeclarationList Declarations;
+ public LocalDeclarationsStatement()
+ : base(NodeType.LocalDeclarationsStatement)
+ {
+ }
+ public LocalDeclarationsStatement(LocalDeclaration ldecl, TypeNode type)
+ : base(NodeType.LocalDeclarationsStatement)
+ {
+ Declarations = new LocalDeclarationList();
+ Declarations.Add(ldecl);
+ this.Type = type;
+ }
+ }
+ public class StatementSnippet : Statement
+ {
+ public IParserFactory ParserFactory;
+
+ public StatementSnippet()
+ : base(NodeType.StatementSnippet)
+ {
+ }
+ public StatementSnippet(IParserFactory parserFactory, SourceContext sctx)
+ : base(NodeType.StatementSnippet)
+ {
+ this.ParserFactory = parserFactory;
+ this.SourceContext = sctx;
+ }
+ }
+ /// <summary>
+ /// Associates an identifier with a type or a namespace or a Uri or a list of assemblies.
+ /// In C# alias identifiers are used as root identifiers in qualified expressions, or as identifier prefixes.
+ /// </summary>
+ public class AliasDefinition : Node
+ {
+
+ /// <summary>The identifier that serves as an alias for the type, namespace, Uri or list of assemblies.</summary>
+ public Identifier Alias;
+
+ /// <summary>The list of assemblies being aliased.</summary>
+ public AssemblyReferenceList AliasedAssemblies;
+
+ /// <summary>The expression that was (or should be) resolved into a type, namespace or Uri.</summary>
+ public Expression AliasedExpression;
+
+ /// <summary>The namespace being aliased.</summary>
+ public Identifier AliasedNamespace;
+
+ /// <summary>A reference to the type being aliased.</summary>
+ public TypeReference AliasedType;
+
+ /// <summary>The Uri being aliased.</summary>
+ public Identifier AliasedUri;
+
+ /// <summary>
+ /// If an alias definition conflicts with a type definition and this causes an ambiguity, the conflicting type is stored here
+ /// by the code that detects the ambiguity. A later visitor is expected to report an error if this is not null.
+ /// </summary>
+ public TypeNode ConflictingType;
+
+ public bool RestrictToInterfaces;
+ public bool RestrictToClassesAndInterfaces;
+
+ public AliasDefinition()
+ : base(NodeType.AliasDefinition)
+ {
+ }
+ public AliasDefinition(Identifier alias, Expression aliasedExpression)
+ : base(NodeType.AliasDefinition)
+ {
+ this.Alias = alias;
+ this.AliasedExpression = aliasedExpression;
+ }
+ public AliasDefinition(Identifier alias, Expression aliasedExpression, SourceContext sctx)
+ : base(NodeType.AliasDefinition)
+ {
+ this.Alias = alias;
+ this.AliasedExpression = aliasedExpression;
+ this.SourceContext = sctx;
+ }
+ }
+ public class UsedNamespace : Node
+ {
+ public Identifier Namespace;
+ public Identifier URI;
+ public UsedNamespace()
+ : base(NodeType.UsedNamespace)
+ {
+ }
+ public UsedNamespace(Identifier Namespace)
+ : base(NodeType.UsedNamespace)
+ {
+ this.Namespace = Namespace;
+ }
+ public UsedNamespace(Identifier Namespace, SourceContext sctx)
+ : base(NodeType.UsedNamespace)
+ {
+ this.Namespace = Namespace;
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+#if !FxCop
+ public class ExceptionHandler : Node
+ {
+ private NodeType handlerType;
+ private Block tryStartBlock;
+ private Block blockAfterTryEnd;
+ private Block handlerStartBlock;
+ private Block blockAfterHandlerEnd;
+ private Block filterExpression;
+ private TypeNode filterType;
+ public ExceptionHandler()
+ : base(NodeType.ExceptionHandler)
+ {
+ }
+ public NodeType HandlerType
+ {
+ get { return this.handlerType; }
+ set { this.handlerType = value; }
+ }
+ public Block TryStartBlock
+ {
+ get { return this.tryStartBlock; }
+ set { this.tryStartBlock = value; }
+ }
+ public Block BlockAfterTryEnd
+ {
+ get { return this.blockAfterTryEnd; }
+ set { this.blockAfterTryEnd = value; }
+ }
+ public Block HandlerStartBlock
+ {
+ get { return this.handlerStartBlock; }
+ set { this.handlerStartBlock = value; }
+ }
+ public Block BlockAfterHandlerEnd
+ {
+ get { return this.blockAfterHandlerEnd; }
+ set { this.blockAfterHandlerEnd = value; }
+ }
+ public Block FilterExpression
+ {
+ get { return this.filterExpression; }
+ set { this.filterExpression = value; }
+ }
+ public TypeNode FilterType
+ {
+ get { return this.filterType; }
+ set { this.filterType = value; }
+ }
+ }
+#endif
+ public class AttributeNode : Node
+ {
+#if !MinimalReader
+ public bool IsPseudoAttribute;
+#endif
+ public AttributeNode()
+ : base(NodeType.Attribute)
+ {
+ }
+ public AttributeNode(Expression constructor, ExpressionList expressions)
+ : base(NodeType.Attribute)
+ {
+ this.constructor = constructor;
+ this.expressions = expressions;
+ this.target = AttributeTargets.All;
+ }
+#if !MinimalReader
+ public AttributeNode(Expression constructor, ExpressionList expressions, AttributeTargets target)
+ : base(NodeType.Attribute)
+ {
+ this.constructor = constructor;
+ this.expressions = expressions;
+ this.target = target;
+ }
+#endif
+ private Expression constructor;
+ public Expression Constructor
+ {
+ get { return this.constructor; }
+ set { this.constructor = value; }
+ }
+ private ExpressionList expressions;
+ /// <summary>
+ /// Invariant: positional arguments occur first and in order in the expression list. Named arguments
+ /// follow posititional arguments in any order.
+ /// </summary>
+ public ExpressionList Expressions
+ {
+ get { return this.expressions; }
+ set { this.expressions = value; }
+ }
+ private AttributeTargets target;
+ public AttributeTargets Target
+ {
+ get { return this.target; }
+ set { this.target = value; }
+ }
+ private bool allowMultiple;
+ public virtual bool AllowMultiple
+ {
+ get
+ {
+ if (this.usageAttribute == null) this.GetUsageInformation();
+ return this.allowMultiple;
+ }
+ set
+ {
+ this.allowMultiple = value;
+ }
+ }
+ private bool inherited;
+ public virtual bool Inherited
+ {
+ get
+ {
+ if (this.usageAttribute == null) this.GetUsageInformation();
+ return this.inherited;
+ }
+ set
+ {
+ this.inherited = value;
+ }
+ }
+ private AttributeTargets validOn;
+ public virtual AttributeTargets ValidOn
+ {
+ get
+ {
+ if (this.usageAttribute == null) this.GetUsageInformation();
+ return this.validOn;
+ }
+ set
+ {
+ this.validOn = value;
+ }
+ }
+ private TypeNode type;
+ public virtual TypeNode Type
+ {
+ get
+ {
+ if (this.type == null)
+ {
+ MemberBinding mb = this.Constructor as MemberBinding;
+ Member cons = mb == null ? null : mb.BoundMember;
+ this.type = cons == null ? null : cons.DeclaringType;
+ }
+ return this.type;
+ }
+ set
+ {
+ this.type = value;
+ }
+ }
+ private AttributeNode usageAttribute;
+ private void GetUsageInformation()
+ {
+ AttributeNode attr = null;
+ TypeNode attrType = this.Type;
+ while (attrType != null)
+ {
+ attr = attrType.GetAttribute(SystemTypes.AttributeUsageAttribute);
+ if (attr != null) break;
+ attrType = attrType.BaseType;
+ }
+ if (attr == null)
+ {
+ this.usageAttribute = AttributeNode.DoesNotExist;
+ return;
+ }
+ ExpressionList args = attr.Expressions;
+ if (args == null || args.Count < 1) return;
+ Literal lit = args[0] as Literal;
+ if (lit == null || !(lit.Value is int))
+ {
+#if ExtendedRuntime
+ MemberBinding mb = args[0] as MemberBinding;
+ if (mb != null) {
+ Field f = mb.BoundMember as Field;
+ if (f != null && f.IsLiteral) {
+ lit = f.Initializer as Literal;
+ }
+ }
+ if (lit == null || !(lit.Value is int))
+#endif
+ return;
+ }
+ //^ assert lit.Value != null;
+ this.validOn = (AttributeTargets)(int)lit.Value;
+ for (int i = 1, n = args.Count; i < n; i++)
+ {
+ NamedArgument narg = args[i] as NamedArgument;
+ if (narg == null || narg.Name == null) continue;
+ lit = narg.Value as Literal;
+ if (lit == null) continue;
+ if (narg.Name.UniqueIdKey == StandardIds.AllowMultiple.UniqueIdKey)
+ {
+ if (lit.Value == null || !(lit.Value is bool)) continue;
+ this.allowMultiple = (bool)lit.Value;
+ }
+ else if (narg.Name.UniqueIdKey == StandardIds.Inherited.UniqueIdKey)
+ {
+ if (lit.Value == null || !(lit.Value is bool)) continue;
+ this.inherited = (bool)lit.Value;
+ }
+ }
+ }
+ public static readonly AttributeNode DoesNotExist = new AttributeNode();
+#if !NoReflection
+ public virtual System.Attribute GetRuntimeAttribute()
+ {
+ MemberBinding mb = this.Constructor as MemberBinding;
+ if (mb == null) return null;
+ InstanceInitializer constr = mb.BoundMember as InstanceInitializer;
+ if (constr == null) return null;
+ ParameterList parameters = constr.Parameters;
+ int paramCount = parameters == null ? 0 : parameters.Count;
+ object[] argumentValues = new object[paramCount];
+ ExpressionList argumentExpressions = this.Expressions;
+ int exprCount = argumentExpressions == null ? 0 : argumentExpressions.Count;
+ for (int i = 0, j = 0; i < paramCount; i++)
+ {
+ if (j >= exprCount) return null;
+ //^ assert argumentExpressions != null;
+ Expression argExpr = argumentExpressions[j++];
+ Literal lit = argExpr as Literal;
+ if (lit == null) continue;
+ argumentValues[i] = this.GetCoercedLiteralValue(lit.Type, lit.Value);
+ }
+ System.Attribute attr = this.ConstructAttribute(constr, argumentValues);
+ if (attr == null) return null;
+ for (int i = 0; i < exprCount; i++)
+ {
+ //^ assert argumentExpressions != null;
+ NamedArgument namedArg = argumentExpressions[i] as NamedArgument;
+ if (namedArg == null) continue;
+ if (namedArg.Name == null) continue;
+ Literal lit = namedArg.Value as Literal;
+ if (lit == null) continue;
+ object val = this.GetCoercedLiteralValue(lit.Type, lit.Value);
+ if (namedArg.IsCustomAttributeProperty)
+ {
+ TypeNode t = constr.DeclaringType;
+ while (t != null)
+ {
+ Property prop = t.GetProperty(namedArg.Name);
+ if (prop != null)
+ {
+ this.SetAttributeProperty(prop, attr, val);
+ t = null;
+ }
+ else
+ t = t.BaseType;
+ }
+ }
+ else
+ {
+ TypeNode t = constr.DeclaringType;
+ while (t != null)
+ {
+ Field f = constr.DeclaringType.GetField(namedArg.Name);
+ if (f != null)
+ {
+ System.Reflection.FieldInfo fieldInfo = f.GetFieldInfo();
+ if (fieldInfo != null) fieldInfo.SetValue(attr, val);
+ t = null;
+ }
+ else
+ t = t.BaseType;
+ }
+ }
+ }
+ return attr;
+ }
+ /// <summary>
+ /// Gets the value of the literal coercing literals of TypeNode, EnumNode, TypeNode[], and EnumNode[] as needed.
+ /// </summary>
+ /// <param name="type">A TypeNode representing the type of the literal</param>
+ /// <param name="value">The value of the literal</param>
+ /// <returns>An object that has been coerced to the appropiate runtime type</returns>
+ protected object GetCoercedLiteralValue(TypeNode type, object value)
+ {
+ if (type == null || value == null) return null;
+ switch (type.typeCode)
+ {
+ case ElementType.Class:
+ return ((TypeNode)value).GetRuntimeType();
+ case ElementType.ValueType:
+ return System.Enum.ToObject(type.GetRuntimeType(), value);
+ case ElementType.SzArray:
+ return this.GetCoercedArrayLiteral((ArrayType)type, (Array)value);
+ default:
+ Literal lit = value as Literal;
+ if (lit != null && type == CoreSystemTypes.Object && lit.Type is EnumNode)
+ return this.GetCoercedLiteralValue(lit.Type, lit.Value);
+ break;
+ }
+ return value;
+ }
+ /// <summary>
+ /// Gets the array literal in arrayValue coercing TypeNode[] and EnumNode[] as needed.
+ /// </summary>
+ /// <param name="arrayType">A TypeNode representing the array type</param>
+ /// <param name="arrayValue">The value of the array literal to coerce</param>
+ /// <returns>An Array object that has been coerced to the appropriate runtime type</returns>
+ protected Array GetCoercedArrayLiteral(ArrayType arrayType, Array arrayValue)
+ {
+ if (arrayType == null) return null;
+ if (arrayValue == null) return null;
+ // Multi-dimensional arrays are not legal in attribute instances according section 17.1.3 of the C# 1.0 spec
+ if (arrayValue.Rank != 1) return null;
+ TypeNode elemType = arrayType.ElementType;
+ if (elemType.typeCode != ElementType.ValueType && elemType.typeCode != ElementType.Class)
+ return arrayValue;
+ int arraySize = arrayValue.GetLength(0);
+ Type et = elemType.GetRuntimeType();
+ if (et == null) return null;
+ Array val = Array.CreateInstance(et, arraySize);
+ for (int i = 0; i < arraySize; i++)
+ val.SetValue(this.GetCoercedLiteralValue(elemType, arrayValue.GetValue(i)), i);
+ return val;
+ }
+ private void SetAttributeProperty(Property/*!*/ prop, System.Attribute attr, object val)
+ {
+ //This could execute partially trusted code, so set up a very restrictive execution environment
+ //TODO: skip this if the attribute is from a trusted assembly
+ System.Reflection.PropertyInfo propInfo = prop.GetPropertyInfo();
+ if (propInfo == null) return;
+ //Because we invoke the setter through reflection, a stack walk is performed. The following two commented-out statements
+ //would cause the stack walk to fail.
+ //For now, we will run the setter in full trust until we work around this.
+ //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that.
+
+ //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
+ //perm.PermitOnly();
+ try
+ {
+ propInfo.SetValue(attr, val, null);
+ }
+ catch { }
+ }
+ private System.Attribute ConstructAttribute(InstanceInitializer/*!*/ constr, object[] argumentValues)
+ {
+ //This could execute partially trusted code, so set up a very restrictive execution environment
+ //TODO: skip this if the attribute is from a trusted assembly
+ System.Reflection.ConstructorInfo consInfo = constr.GetConstructorInfo();
+ if (consInfo == null) return null;
+ //Because we invoke the constructor through reflection, a stack walk is performed. The following two commented-out statements
+ //would cause the stack walk to fail.
+ //For VS2003 and earlier, we will run the constructor in full trust.
+ //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that.
+
+ //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
+ //perm.PermitOnly();
+ try
+ {
+ return consInfo.Invoke(argumentValues) as System.Attribute;
+ }
+ catch { }
+ return null;
+ }
+#endif
+ public Expression GetPositionalArgument(int position)
+ {
+ if (this.Expressions == null || this.Expressions.Count <= position) return null;
+ Expression e = this.Expressions[position];
+ NamedArgument na = e as NamedArgument;
+ if (na != null) return null;
+ return e;
+ }
+ public Expression GetNamedArgument(Identifier name)
+ {
+ if (name == null || this.Expressions == null) return null;
+ foreach (Expression e in this.Expressions)
+ {
+ NamedArgument na = e as NamedArgument;
+ if (na == null) continue;
+ if (na.Name == null) continue;
+ if (na.Name.UniqueIdKey == name.UniqueIdKey) return na.Value;
+ }
+ return null;
+ }
+ }
+ public class SecurityAttribute : Node
+ {
+ public SecurityAttribute()
+ : base(NodeType.SecurityAttribute)
+ {
+ }
+ private System.Security.Permissions.SecurityAction action;
+ public System.Security.Permissions.SecurityAction Action
+ {
+ get { return this.action; }
+ set { this.action = value; }
+ }
+ private AttributeList permissionAttributes;
+ public AttributeList PermissionAttributes
+ {
+ get { return this.permissionAttributes; }
+ set { this.permissionAttributes = value; }
+ }
+ protected string serializedPermissions;
+ public string SerializedPermissions
+ {
+ get
+ {
+#if !NoReflection || FxCop
+ if (this.serializedPermissions == null && this.PermissionAttributes != null)
+ {
+ lock (this)
+ {
+ if (this.serializedPermissions != null) return this.serializedPermissions;
+ System.Security.PermissionSet permissions = this.Permissions;
+ if (permissions == null) return null;
+ System.Security.SecurityElement xml = permissions.ToXml();
+ if (xml == null) return null;
+ this.serializedPermissions = xml.ToString();
+ //TODO: if the target platform is different from the host platform, replace references to host platform
+ //assemblies with references to target platform assemblies
+ }
+ }
+#endif
+ return this.serializedPermissions;
+ }
+ set
+ {
+ this.serializedPermissions = value;
+ }
+ }
+#if !NoReflection || FxCop
+ protected System.Security.PermissionSet permissions;
+ public System.Security.PermissionSet Permissions
+ {
+ get
+ {
+ if (this.permissions == null)
+ {
+ lock (this)
+ {
+ if (this.permissions != null) return this.permissions;
+ System.Security.PermissionSet permissions = null;
+#if !FxCop
+ if (this.PermissionAttributes != null)
+ {
+ permissions = this.InstantiatePermissionAttributes();
+ }
+ else if (this.serializedPermissions != null)
+ {
+ permissions = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
+ permissions.FromXml(this.GetSecurityElement());
+ }
+#elif !TestBuild
+ permissions = PermissionsHelper.GetPermissions(this);
+#endif
+ this.permissions = permissions;
+ }
+ }
+ return this.permissions;
+ }
+ set
+ {
+ this.permissions = value;
+ }
+ }
+#endif
+#if !NoReflection
+ protected System.Security.SecurityElement GetSecurityElement()
+ {
+#if WHIDBEY
+ return System.Security.SecurityElement.FromString(this.serializedPermissions);
+#else
+ System.Reflection.Assembly mscorlib = CoreSystemTypes.SystemAssembly.GetRuntimeAssembly();
+ if (mscorlib == null) { Debug.Fail(""); return null; }
+ Type parserType = mscorlib.GetType("System.Security.Util.Parser", true, false);
+ if (parserType == null) { Debug.Fail(""); return null; }
+ System.Reflection.MethodInfo getTopElement = parserType.GetMethod("GetTopElement", BindingFlags.NonPublic|BindingFlags.Instance, null, new Type[]{}, null);
+ if (getTopElement == null) { Debug.Fail(""); return null; }
+ object parser = Activator.CreateInstance(parserType, BindingFlags.Instance|BindingFlags.NonPublic, null, new Object[]{this.serializedPermissions}, null);
+ return (System.Security.SecurityElement)getTopElement.Invoke(parser, null);
+#endif
+ }
+ protected System.Security.PermissionSet InstantiatePermissionAttributes()
+ {
+ System.Security.PermissionSet permissions = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
+ AttributeList permissionAttributes = this.PermissionAttributes;
+ for (int i = 0, n = permissionAttributes == null ? 0 : permissionAttributes.Count; i < n; i++)
+ {
+ //^ assert permissionAttributes != null;
+ object result = this.GetPermissionOrSetOfPermissionsFromAttribute(permissionAttributes[i]);
+ if (result == null) continue;
+ if (result is System.Security.PermissionSet)
+ permissions = permissions.Union((System.Security.PermissionSet)result);
+ else
+ {
+ System.Security.IPermission permission = result as System.Security.IPermission;
+ if (permission == null) continue;
+ permissions.AddPermission(permission);
+ }
+ }
+ return permissions;
+ }
+ protected object GetPermissionOrSetOfPermissionsFromAttribute(AttributeNode attr)
+ {
+ if (attr == null) return null;
+ System.Security.Permissions.SecurityAttribute secAttr = attr.GetRuntimeAttribute() as System.Security.Permissions.SecurityAttribute;
+ if (secAttr == null) return null;
+ System.Security.Permissions.PermissionSetAttribute pSetAttr = secAttr as System.Security.Permissions.PermissionSetAttribute;
+ if (pSetAttr != null)
+ return pSetAttr.CreatePermissionSet();
+ else
+ return this.CreatePermission(secAttr);
+ }
+ private System.Security.IPermission CreatePermission(System.Security.Permissions.SecurityAttribute/*!*/ secAttr)
+ {
+ //This could execute partially trusted code, so set up a very restrictive execution environment
+ System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
+ //TODO: add permissions if the attribute is from a trusted assembly
+ perm.PermitOnly();
+ try
+ {
+ return secAttr.CreatePermission();
+ }
+ catch { }
+ return null;
+ }
+#endif
+ }
+ public struct Resource
+ {
+ private bool isPublic;
+ private string name;
+ private Module definingModule;
+ private byte[] data;
+ public bool IsPublic
+ {
+ get { return this.isPublic; }
+ set { this.isPublic = value; }
+ }
+ public string Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ public Module DefiningModule
+ {
+ get { return this.definingModule; }
+ set { this.definingModule = value; }
+ }
+ public byte[] Data
+ {
+ get { return this.data; }
+ set { this.data = value; }
+ }
+ }
+ public struct Win32Resource
+ {
+ private string typeName;
+ private int typeId;
+ private string name;
+ private int id;
+ private int languageId;
+ private int codePage;
+ private byte[] data;
+ public string TypeName
+ {
+ get { return this.typeName; }
+ set { this.typeName = value; }
+ }
+ public int TypeId
+ {
+ get { return this.typeId; }
+ set { this.typeId = value; }
+ }
+ public string Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ public int Id
+ {
+ get { return this.id; }
+ set { this.id = value; }
+ }
+ public int LanguageId
+ {
+ get { return this.languageId; }
+ set { this.languageId = value; }
+ }
+ public int CodePage
+ {
+ get { return this.codePage; }
+ set { this.codePage = value; }
+ }
+ public byte[] Data
+ {
+ get { return this.data; }
+ set { this.data = value; }
+ }
+ }
+#if FxCop
+ public class ModuleNode : Node, IDisposable{
+#else
+ public class Module : Node, IDisposable
+ {
+#endif
+ internal Reader reader;
+ public delegate void TypeNodeListProvider(Module/*!*/ module);
+ protected TypeNodeListProvider provideTypeNodeList;
+ public delegate TypeNode TypeNodeProvider(Identifier/*!*/ @namespace, Identifier/*!*/ name);
+ protected TypeNodeProvider provideTypeNode;
+ protected TrivialHashtable namespaceTable = new TrivialHashtable();
+ protected NamespaceList namespaceList;
+ protected int savedTypesLength;
+ public delegate void CustomAttributeProvider(Module/*!*/ module);
+ protected CustomAttributeProvider provideCustomAttributes;
+ public delegate void ResourceProvider(Module/*!*/ module);
+ protected ResourceProvider provideResources;
+ public delegate AssemblyNode AssemblyReferenceResolver(AssemblyReference/*!*/ assemblyReference, Module/*!*/ referencingModule);
+ public event AssemblyReferenceResolver AssemblyReferenceResolution;
+ public event AssemblyReferenceResolver AssemblyReferenceResolutionAfterProbingFailed;
+#if !MinimalReader
+ public delegate void PostAssemblyLoadProcessor(AssemblyNode loadedAssembly);
+ public event PostAssemblyLoadProcessor AfterAssemblyLoad;
+#endif
+#if !NoXml
+ public delegate XmlDocument DocumentationResolver(Module referencingModule);
+ public event DocumentationResolver DocumentationResolution = null;
+#endif
+#if !MinimalReader
+ public bool IsNormalized;
+#endif
+#if !NoWriter
+ public bool UsePublicKeyTokensForAssemblyReferences = true;
+#endif
+ internal int FileAlignment = 512;
+ internal readonly static object GlobalLock = new object();
+#if !NoWriter
+ public bool StripOptionalModifiersFromLocals = true;
+#endif
+#if FxCop
+ public ModuleNode()
+#else
+ public Module()
+#endif
+ : base(NodeType.Module)
+ {
+#if !MinimalReader
+ this.IsNormalized = false;
+#endif
+ }
+#if FxCop
+ public ModuleNode(TypeNodeProvider provider, TypeNodeListProvider listProvider, CustomAttributeProvider provideCustomAttributes, ResourceProvider provideResources)
+#else
+ public Module(TypeNodeProvider provider, TypeNodeListProvider listProvider, CustomAttributeProvider provideCustomAttributes, ResourceProvider provideResources)
+#endif
+ : base(NodeType.Module)
+ {
+ this.provideCustomAttributes = provideCustomAttributes;
+ this.provideResources = provideResources;
+ this.provideTypeNode = provider;
+ this.provideTypeNodeList = listProvider;
+#if !MinimalReader
+ this.IsNormalized = true;
+#endif
+ }
+ public virtual void Dispose()
+ {
+ if (this.reader != null) this.reader.Dispose();
+ this.reader = null;
+ ModuleReferenceList mrefs = this.moduleReferences;
+ for (int i = 0, n = mrefs == null ? 0 : mrefs.Count; i < n; i++)
+ {
+ //^ assert mrefs != null;
+ ModuleReference mr = mrefs[i];
+ if (mr != null && mr.Module == null) continue;
+ mr.Module.Dispose();
+ }
+ this.moduleReferences = null;
+ }
+ private AssemblyReferenceList assemblyReferences;
+ public AssemblyReferenceList AssemblyReferences
+ {
+ get { return this.assemblyReferences; }
+ set { this.assemblyReferences = value; }
+ }
+ private AssemblyNode containingAssembly;
+ /// <summary>The assembly, if any, that includes this module in its ModuleReferences.</summary>
+ public AssemblyNode ContainingAssembly
+ {
+ get { return this.containingAssembly; }
+ set { this.containingAssembly = value; }
+ }
+ private string directory;
+ public string Directory
+ {
+ get { return this.directory; }
+ set { this.directory = value; }
+ }
+ private AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.SHA1;
+ public AssemblyHashAlgorithm HashAlgorithm
+ {
+ get { return this.hashAlgorithm; }
+ set { this.hashAlgorithm = value; }
+ }
+ private byte[] hashValue;
+ public byte[] HashValue
+ {
+ get { return this.hashValue; }
+ set { this.hashValue = value; }
+ }
+ private ModuleKindFlags kind;
+ /// <summary>An enumeration that indicates if the module is an executable, library or resource, and so on.</summary>
+ public ModuleKindFlags Kind
+ {
+ get { return this.kind; }
+ set { this.kind = value; }
+ }
+ private string location;
+ /// <summary>The path of the file from which this module or assembly was loaded or will be stored in.</summary>
+ public string Location
+ {
+ get { return this.location; }
+ set { this.location = value; }
+ }
+ private System.Guid mvid;
+ public System.Guid Mvid
+ {
+ get { return this.mvid; }
+ set { this.mvid = value; }
+ }
+ private string targetRuntimeVersion;
+ /// <summary>Identifies the version of the CLR that is required to load this module or assembly.</summary>
+ public string TargetRuntimeVersion
+ {
+ get { return this.targetRuntimeVersion; }
+ set { this.targetRuntimeVersion = value; }
+ }
+ private int linkerMajorVersion = 6;
+ public int LinkerMajorVersion
+ {
+ get { return this.linkerMajorVersion; }
+ set { this.linkerMajorVersion = value; }
+ }
+ private int linkerMinorVersion;
+ public int LinkerMinorVersion
+ {
+ get { return this.linkerMinorVersion; }
+ set { this.linkerMinorVersion = value; }
+ }
+ private int metadataFormatMajorVersion;
+ public int MetadataFormatMajorVersion
+ {
+ get { return this.metadataFormatMajorVersion; }
+ set { this.metadataFormatMajorVersion = value; }
+ }
+ private int metadataFormatMinorVersion;
+ public int MetadataFormatMinorVersion
+ {
+ get { return this.metadataFormatMinorVersion; }
+ set { this.metadataFormatMinorVersion = value; }
+ }
+ private string name;
+ /// <summary>The name of the module or assembly. Includes the file extension if the module is not an assembly.</summary>
+ public string Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ private PEKindFlags peKind = PEKindFlags.ILonly;
+ public PEKindFlags PEKind
+ {
+ get { return this.peKind; }
+ set { this.peKind = value; }
+ }
+ private bool trackDebugData;
+ public bool TrackDebugData
+ {
+ get { return this.trackDebugData; }
+ set { this.trackDebugData = value; }
+ }
+#if !FxCop
+ private ArrayList metadataImportErrors;
+ /// <summary>
+ /// If any exceptions were encountered while reading in this module, they are recorded here. Since reading is lazy,
+ /// this list can grow dynamically during the use of a module.
+ /// </summary>
+ public ArrayList MetadataImportErrors
+ {
+ get { return this.metadataImportErrors; }
+ set { this.metadataImportErrors = value; }
+ }
+#endif
+ protected AttributeList attributes;
+ /// <summary>
+ /// The attributes associated with this module or assembly. This corresponds to C# custom attributes with the assembly or module target specifier.
+ /// </summary>
+ public virtual AttributeList Attributes
+ {
+ get
+ {
+ if (this.attributes != null) return this.attributes;
+ if (this.provideCustomAttributes != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.attributes == null)
+ this.provideCustomAttributes(this);
+ }
+ }
+ else
+ this.attributes = new AttributeList();
+ return this.attributes;
+ }
+ set
+ {
+ this.attributes = value;
+ }
+ }
+
+ protected SecurityAttributeList securityAttributes;
+ /// <summary>
+ /// Declarative security for the module or assembly.
+ /// </summary>
+ public virtual SecurityAttributeList SecurityAttributes
+ {
+ get
+ {
+ if (this.securityAttributes != null) return this.securityAttributes;
+ if (this.provideCustomAttributes != null)
+ {
+ AttributeList dummy = this.Attributes; //As a side effect, this.securityAttributes gets populated
+ if (dummy != null) dummy = null;
+ }
+ else
+ this.securityAttributes = new SecurityAttributeList();
+ return this.securityAttributes;
+ }
+ set
+ {
+ this.securityAttributes = value;
+ }
+ }
+#if !MinimalReader
+ /// <summary>The source code, if any, corresponding to the value in Documentation.</summary>
+ public Node DocumentationNode;
+#endif
+#if !NoXml
+ protected XmlDocument documentation;
+ /// <summary>An XML Document Object Model for a document containing all of the documentation comments applicable to members
+ /// defined in this module.</summary>
+ public virtual XmlDocument Documentation
+ {
+ get
+ {
+ XmlDocument documentation = this.documentation;
+ if (documentation != null) return documentation;
+ if (this.DocumentationResolution != null)
+ documentation = this.documentation = this.DocumentationResolution(this);
+ if (documentation != null) return documentation;
+ XmlDocument doc = null;
+ if (this.Directory != null && this.Name != null)
+ {
+ string fileName = this.Name + ".xml";
+ System.Globalization.CultureInfo cc = System.Globalization.CultureInfo.CurrentUICulture;
+ while (cc != null && cc != System.Globalization.CultureInfo.InvariantCulture)
+ {
+ doc = this.ProbeForXmlDocumentation(this.Directory, cc.Name, fileName);
+ if (doc != null) break;
+ cc = cc.Parent;
+ }
+ if (doc == null)
+ doc = this.ProbeForXmlDocumentation(this.Directory, null, fileName);
+ }
+ if (doc == null) doc = new XmlDocument();
+ return this.documentation = doc;
+ }
+ set
+ {
+ this.documentation = value;
+ }
+ }
+ public virtual XmlDocument ProbeForXmlDocumentation(string dir, string subDir, string fileName)
+ {
+ try
+ {
+ if (dir == null || fileName == null) return null;
+ if (subDir != null) dir = Path.Combine(dir, subDir);
+ string docFileName = Path.Combine(dir, fileName);
+ if (File.Exists(docFileName))
+ {
+ XmlDocument doc = new XmlDocument();
+ using (TextReader reader = File.OpenText(docFileName))
+ {
+ doc.Load(reader);
+ return doc;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ if (this.MetadataImportErrors == null) this.MetadataImportErrors = new ArrayList();
+ this.MetadataImportErrors.Add(e);
+ }
+ return null;
+ }
+#endif
+ protected internal static readonly Method NoSuchMethod = new Method();
+ protected Method entryPoint;
+ /// <summary>If this module is an executable, this method is the one that gets called to start the execution of managed code.</summary>
+ public virtual Method EntryPoint
+ {
+ get
+ {
+ if (this.entryPoint == null)
+ {
+ if (this.provideCustomAttributes != null)
+ {
+ AttributeList dummy = this.Attributes; //Gets the entry point as a side effect
+ if (dummy != null) dummy = null;
+ }
+ else
+ this.entryPoint = Module.NoSuchMethod;
+ }
+ if (this.entryPoint == Module.NoSuchMethod) return null;
+ return this.entryPoint;
+ }
+ set
+ {
+ this.entryPoint = value;
+ }
+ }
+ protected ModuleReferenceList moduleReferences;
+ /// <summary>The list of modules (excluding assemblies) defining members that are referred to in this module or assembly.</summary>
+ public ModuleReferenceList ModuleReferences
+ {
+ get
+ {
+ //Populating the type list may cause module references to be added
+ if (this.Types == null) return this.moduleReferences;
+ return this.moduleReferences;
+ }
+ set
+ {
+ this.moduleReferences = value;
+ }
+ }
+#if !MinimalReader
+ public virtual bool ContainsModule(Module module)
+ {
+ if (module == null || this.ModuleReferences == null || this.ModuleReferences.Count == 0) return false;
+ int n = this.ModuleReferences.Count;
+ for (int i = 0; i < n; ++i)
+ {
+ ModuleReference mr = this.ModuleReferences[i];
+ if (mr == null) continue;
+ if (mr.Module == module)
+ return true;
+ }
+ return false;
+ }
+#endif
+ protected ResourceList resources;
+ /// <summary>
+ /// A list of managed resources linked or embedded into this module or assembly.
+ /// </summary>
+ public virtual ResourceList Resources
+ {
+ get
+ {
+ if (this.resources != null) return this.resources;
+ if (this.provideResources != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.resources == null)
+ this.provideResources(this);
+ }
+ }
+ else
+ this.resources = new ResourceList();
+ return this.resources;
+ }
+ set
+ {
+ this.resources = value;
+ }
+ }
+ protected Win32ResourceList win32Resources;
+ /// <summary>
+ /// A list of Win32 resources embedded in this module or assembly.
+ /// </summary>
+ public virtual Win32ResourceList Win32Resources
+ {
+ get
+ {
+ if (this.win32Resources != null) return this.win32Resources;
+ if (this.provideResources != null)
+ {
+ ResourceList dummy = this.Resources; //gets the win32 resources as as side effect
+ if (dummy != null) dummy = null;
+ }
+ else
+ this.win32Resources = new Win32ResourceList();
+ return this.win32Resources;
+ }
+ set
+ {
+ this.win32Resources = value;
+ }
+ }
+#if !NoWriter
+ public virtual void AddWin32ResourceFile(string win32ResourceFilePath)
+ {
+ if (win32ResourceFilePath == null) return;
+ Writer.AddWin32ResourceFileToModule(this, win32ResourceFilePath);
+ }
+ public virtual void AddWin32ResourceFile(Stream win32ResourceStream)
+ {
+ if (win32ResourceStream == null) return;
+ Writer.AddWin32ResourceFileToModule(this, win32ResourceStream);
+ }
+ public virtual void AddWin32Icon(string win32IconFilePath)
+ {
+ if (win32IconFilePath == null) return;
+ Writer.AddWin32Icon(this, win32IconFilePath);
+ }
+ public virtual void AddWin32Icon(Stream win32IconStream)
+ {
+ Writer.AddWin32Icon(this, win32IconStream);
+ }
+ public void AddWin32VersionInfo(CompilerOptions options)
+ {
+ if (options == null) return;
+ Writer.AddWin32VersionInfo(this, options);
+ }
+#endif
+ /// <summary>
+ /// Gets the first attribute of the given type in the custom attribute list of this module. Returns null if none found.
+ /// This should not be called until the module has been processed to replace symbolic references
+ /// to members with references to the actual members.
+ /// </summary>
+ public virtual AttributeNode GetAttribute(TypeNode attributeType)
+ {
+ AttributeList attributes = this.GetAttributes(attributeType, 1);
+ if (attributes != null && attributes.Count > 0)
+ return attributes[0];
+ return null;
+ }
+
+ public virtual AttributeList GetAttributes(TypeNode attributeType)
+ {
+ return GetAttributes(attributeType, Int32.MaxValue);
+ }
+
+ public virtual AttributeList GetAttributes(TypeNode attributeType, int maxCount)
+ {
+ AttributeList foundAttributes = new AttributeList();
+ if (attributeType == null) return foundAttributes;
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, count = 0, n = attributes == null ? 0 : attributes.Count; i < n && count < maxCount; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != attributeType) continue;
+ foundAttributes.Add(attr);
+ count++;
+ continue;
+ }
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != attributeType) continue;
+ foundAttributes.Add(attr);
+ count++;
+ }
+ return foundAttributes;
+ }
+#if !NoXml
+ protected TrivialHashtable memberDocumentationCache;
+ public TrivialHashtable GetMemberDocumentationCache()
+ {
+ TrivialHashtable cache = this.memberDocumentationCache;
+ if (cache != null) return cache;
+ lock (this)
+ {
+ if (this.memberDocumentationCache != null) return this.memberDocumentationCache;
+ XmlDocument doc = this.Documentation;
+ if (doc == null && this.ContainingAssembly != null && this.ContainingAssembly != this)
+ return this.memberDocumentationCache = this.ContainingAssembly.memberDocumentationCache;
+ cache = this.memberDocumentationCache = new TrivialHashtable();
+ if (doc == null) return cache;
+ XmlNode docElem = doc.DocumentElement;
+ if (docElem == null) return cache;
+ XmlNode membersNode = null;
+ if (docElem.HasChildNodes)
+ {
+ foreach (XmlNode dec in docElem.ChildNodes)
+ if (dec.Name == "members") { membersNode = dec; break; }
+ }
+ if (membersNode == null) return cache;
+ if (membersNode.HasChildNodes)
+ {
+ foreach (XmlNode member in membersNode.ChildNodes)
+ {
+ if (member.Name != "member") continue;
+ XmlNode nameAttr = member.Attributes.GetNamedItem("name");
+ if (nameAttr == null) continue;
+ cache[Identifier.For(nameAttr.Value).UniqueIdKey] = member;
+ }
+ }
+ return cache;
+ }
+ }
+#endif
+ protected TrivialHashtable validNamespaces;
+ public NamespaceList GetNamespaceList()
+ {
+ if (this.reader != null) return this.GetNamespaceListFromReader();
+#if !MinimalReader
+ TypeNodeList types = this.Types;
+ int n = types == null ? 0 : types.Count;
+ if (this.namespaceList == null || n > this.savedTypesLength)
+ {
+ lock (this)
+ {
+ if (this.namespaceList != null && this.types != null && this.types.Count == this.savedTypesLength)
+ return this.namespaceList;
+ NamespaceList nsList = this.namespaceList = new NamespaceList();
+ TrivialHashtable nsTable = this.validNamespaces = new TrivialHashtable();
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert this.types != null;
+ TypeNode t = this.types[i];
+ if (t == null) continue;
+ if (t.Namespace == null) t.Namespace = Identifier.Empty;
+ Namespace ns = nsTable[t.Namespace.UniqueIdKey] as Namespace;
+ if (ns != null)
+ {
+ if (t.IsPublic) ns.isPublic = true;
+ ns.Types.Add(t); continue;
+ }
+ ns = new Namespace(t.Namespace);
+ ns.isPublic = t.IsPublic;
+ ns.Types = new TypeNodeList();
+ ns.Types.Add(t);
+ nsTable[t.Namespace.UniqueIdKey] = ns;
+ nsList.Add(ns);
+ }
+ }
+ }
+#endif
+ return this.namespaceList;
+ }
+ private NamespaceList GetNamespaceListFromReader()
+ //^ requires this.reader != null;
+ {
+ if (this.namespaceList == null)
+ {
+ lock (Module.GlobalLock)
+ {
+ this.reader.GetNamespaces();
+ NamespaceList nsList = this.namespaceList = this.reader.namespaceList;
+ TrivialHashtable nsTable = this.validNamespaces = new TrivialHashtable();
+ for (int i = 0, n = nsList == null ? 0 : nsList.Count; i < n; i++)
+ {
+ //^ assert nsList != null;
+ Namespace ns = nsList[i];
+ if (ns == null || ns.Name == null) continue;
+ ns.ProvideTypes = new Namespace.TypeProvider(this.GetTypesForNamespace);
+ nsTable[ns.Name.UniqueIdKey] = ns;
+ }
+ }
+ }
+ return this.namespaceList;
+ }
+ private void GetTypesForNamespace(Namespace nspace, object handle)
+ {
+ if (nspace == null || nspace.Name == null) return;
+ lock (Module.GlobalLock)
+ {
+ int key = nspace.Name.UniqueIdKey;
+ TypeNodeList types = this.Types;
+ TypeNodeList nsTypes = nspace.Types = new TypeNodeList();
+ for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++)
+ {
+ TypeNode t = types[i];
+ if (t == null || t.Namespace == null) continue;
+ if (t.Namespace.UniqueIdKey == key) nsTypes.Add(t);
+ }
+ }
+ }
+ public bool IsValidNamespace(Identifier nsName)
+ {
+ if (nsName == null) return false;
+ this.GetNamespaceList();
+ //^ assert this.validNamespaces != null;
+ return this.validNamespaces[nsName.UniqueIdKey] != null;
+ }
+ public bool IsValidTypeName(Identifier nsName, Identifier typeName)
+ {
+ if (nsName == null || typeName == null) return false;
+ if (!this.IsValidNamespace(nsName)) return false;
+ if (this.reader != null) return this.reader.IsValidTypeName(nsName, typeName);
+ return this.GetType(nsName, typeName) != null;
+ }
+ public Module GetNestedModule(string moduleName)
+ {
+ if (this.Types == null) { Debug.Assert(false); } //Just get the types to pull in any exported types
+ ModuleReferenceList moduleReferences = this.ModuleReferences; //This should now contain all interesting referenced modules
+ for (int i = 0, n = moduleReferences == null ? 0 : moduleReferences.Count; i < n; i++)
+ {
+ ModuleReference mref = moduleReferences[i];
+ if (mref == null) continue;
+ if (mref.Name == moduleName) return mref.Module;
+ }
+ return null;
+ }
+ internal TrivialHashtableUsingWeakReferences/*!*/ StructurallyEquivalentType
+ {
+ get
+ {
+ if (this.structurallyEquivalentType == null)
+ this.structurallyEquivalentType = new TrivialHashtableUsingWeakReferences();
+ return this.structurallyEquivalentType;
+ }
+ }
+ private TrivialHashtableUsingWeakReferences structurallyEquivalentType;
+ /// <summary>
+ /// The identifier represents the structure via some mangling scheme. The result can be either from this module,
+ /// or any module this module has a reference to.
+ /// </summary>
+ public virtual TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id)
+ {
+ return this.GetStructurallyEquivalentType(ns, id, id, true);
+ }
+ public virtual TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id, Identifier uniqueMangledName, bool lookInReferencedAssemblies)
+ {
+ if (uniqueMangledName == null) uniqueMangledName = id;
+ TypeNode result = (TypeNode)this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey];
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ lock (Module.GlobalLock)
+ {
+ result = this.GetType(ns, id);
+ if (result != null)
+ {
+ this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
+ return result;
+ }
+ if (!lookInReferencedAssemblies)
+ goto notfound;
+ AssemblyReferenceList refs = this.AssemblyReferences;
+ for (int i = 0, n = refs == null ? 0 : refs.Count; i < n; i++)
+ {
+ AssemblyReference ar = refs[i];
+ if (ar == null) continue;
+ AssemblyNode a = ar.Assembly;
+ if (a == null) continue;
+ result = a.GetType(ns, id);
+ if (result != null)
+ {
+ this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
+ return result;
+ }
+ }
+ notfound:
+ this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = Class.DoesNotExist;
+ return null;
+ }
+ }
+ public virtual TypeNode GetType(Identifier @namespace, Identifier name, bool lookInReferencedAssemblies)
+ {
+ return this.GetType(@namespace, name, lookInReferencedAssemblies, lookInReferencedAssemblies ? new TrivialHashtable() : null);
+ }
+ protected virtual TypeNode GetType(Identifier @namespace, Identifier name, bool lookInReferencedAssemblies, TrivialHashtable assembliesAlreadyVisited)
+ {
+ if (assembliesAlreadyVisited != null)
+ {
+ if (assembliesAlreadyVisited[this.UniqueKey] != null) return null;
+ assembliesAlreadyVisited[this.UniqueKey] = this;
+ }
+ TypeNode result = this.GetType(@namespace, name);
+ if (result != null || !lookInReferencedAssemblies) return result;
+ AssemblyReferenceList refs = this.AssemblyReferences;
+ for (int i = 0, n = refs == null ? 0 : refs.Count; i < n; i++)
+ {
+ AssemblyReference ar = refs[i];
+ if (ar == null) continue;
+ AssemblyNode a = ar.Assembly;
+ if (a == null) continue;
+ result = a.GetType(@namespace, name, true, assembliesAlreadyVisited);
+ if (result != null) return result;
+ }
+ return null;
+ }
+ public virtual TypeNode GetType(Identifier @namespace, Identifier name)
+ {
+ if (@namespace == null || name == null) return null;
+ TypeNode result = null;
+ if (this.namespaceTable == null) this.namespaceTable = new TrivialHashtable();
+ TrivialHashtable nsTable = (TrivialHashtable)this.namespaceTable[@namespace.UniqueIdKey];
+ if (nsTable != null)
+ {
+ result = (TypeNode)nsTable[name.UniqueIdKey];
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ }
+ else
+ {
+ lock (Module.GlobalLock)
+ {
+ nsTable = (TrivialHashtable)this.namespaceTable[@namespace.UniqueIdKey];
+ if (nsTable == null)
+ this.namespaceTable[@namespace.UniqueIdKey] = nsTable = new TrivialHashtable(32);
+ }
+ }
+ if (this.provideTypeNode != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ result = (TypeNode)nsTable[name.UniqueIdKey];
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ result = this.provideTypeNode(@namespace, name);
+ if (result != null)
+ {
+ nsTable[name.UniqueIdKey] = result;
+ return result;
+ }
+ nsTable[name.UniqueIdKey] = Class.DoesNotExist;
+ return null;
+ }
+ }
+ if (this.types != null && this.types.Count > this.savedTypesLength)
+ {
+ int n = this.savedTypesLength = this.types.Count;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.types[i];
+ if (t == null) continue;
+ if (t.Namespace == null) t.Namespace = Identifier.Empty;
+ nsTable = (TrivialHashtable)this.namespaceTable[t.Namespace.UniqueIdKey];
+ if (nsTable == null) this.namespaceTable[t.Namespace.UniqueIdKey] = nsTable = new TrivialHashtable();
+ nsTable[t.Name.UniqueIdKey] = t;
+ }
+ return this.GetType(@namespace, name);
+ }
+ return null;
+ }
+ protected internal TypeNodeList types;
+ /// <summary>The types contained in this module or assembly.</summary>
+ public virtual TypeNodeList Types
+ {
+ get
+ {
+ if (this.types != null) return this.types;
+ if (this.provideTypeNodeList != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.types == null)
+ this.provideTypeNodeList(this);
+ }
+ }
+ else
+ this.types = new TypeNodeList();
+ return this.types;
+ }
+ set
+ {
+ this.types = value;
+ }
+ }
+#if !MinimalReader
+ protected TrivialHashtable referencedModulesAndAssemblies;
+#endif
+ public virtual bool HasReferenceTo(Module module)
+ {
+ if (module == null) return false;
+ AssemblyNode assembly = module as AssemblyNode;
+ if (assembly != null)
+ {
+ AssemblyReferenceList arefs = this.AssemblyReferences;
+ for (int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
+ {
+ AssemblyReference aref = arefs[i];
+ if (aref == null) continue;
+ if (aref.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken))
+ return true;
+ }
+ }
+ if (this.ContainingAssembly != module.ContainingAssembly)
+ return false;
+ ModuleReferenceList mrefs = this.ModuleReferences;
+ for (int i = 0, n = mrefs == null ? 0 : mrefs.Count; i < n; i++)
+ {
+ //^ assert mrefs != null;
+ ModuleReference mref = mrefs[i];
+ if (mref == null || mref.Name == null) continue;
+ if (0 == PlatformHelpers.StringCompareOrdinalIgnoreCase(mref.Name, module.Name))
+ return true;
+ }
+ return false;
+ }
+ internal void InitializeAssemblyReferenceResolution(Module referringModule)
+ {
+ if (this.AssemblyReferenceResolution == null && referringModule != null)
+ {
+ this.AssemblyReferenceResolution = referringModule.AssemblyReferenceResolution;
+ this.AssemblyReferenceResolutionAfterProbingFailed = referringModule.AssemblyReferenceResolutionAfterProbingFailed;
+ }
+ }
+#if !MinimalReader
+ public static Module GetModule(byte[] buffer)
+ {
+ return Module.GetModule(buffer, null, false, false, true, false);
+ }
+ public static Module GetModule(byte[] buffer, IDictionary cache)
+ {
+ return Module.GetModule(buffer, null, false, false, false, false);
+ }
+ public static Module GetModule(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return Module.GetModule(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static Module GetModule(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (buffer == null) return null;
+ return (new Reader(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false)).ReadModule();
+ }
+#endif
+ public static Module GetModule(string location)
+ {
+ return Module.GetModule(location, null, false, false, true, false);
+ }
+ public static Module GetModule(string location, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return Module.GetModule(location, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static Module GetModule(string location, IDictionary cache)
+ {
+ return Module.GetModule(location, cache, false, false, false, false);
+ }
+ public static Module GetModule(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return Module.GetModule(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static Module GetModule(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (location == null) return null;
+ return (new Reader(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule();
+ }
+ public virtual AssemblyNode Resolve(AssemblyReference assemblyReference)
+ {
+ if (this.AssemblyReferenceResolution == null) return null;
+ return this.AssemblyReferenceResolution(assemblyReference, this);
+ }
+ public virtual AssemblyNode ResolveAfterProbingFailed(AssemblyReference assemblyReference)
+ {
+ if (this.AssemblyReferenceResolutionAfterProbingFailed == null) return null;
+ return this.AssemblyReferenceResolutionAfterProbingFailed(assemblyReference, this);
+ }
+#if !MinimalReader
+ public virtual void AfterAssemblyLoadProcessing()
+ {
+ if (this.AfterAssemblyLoad != null)
+ {
+ this.AfterAssemblyLoad(this as AssemblyNode);
+ }
+ }
+#endif
+#if !NoWriter
+ public virtual void WriteModule(string/*!*/ location, bool writeDebugSymbols)
+ {
+ this.Location = location;
+ Writer.WritePE(location, writeDebugSymbols, this);
+ }
+ public virtual void WriteModule(Stream/*!*/ executable, Stream debugSymbols)
+ {
+ Writer.WritePE(executable, debugSymbols, this);
+ }
+ public virtual void WriteModule(out byte[] executable)
+ {
+ Writer.WritePE(out executable, this);
+ }
+ public virtual void WriteModule(out byte[] executable, out byte[] debugSymbols)
+ {
+ Writer.WritePE(out executable, out debugSymbols, this);
+ }
+ public virtual void WriteModule(string/*!*/ location, System.CodeDom.Compiler.CompilerParameters/*!*/ options)
+ {
+ this.Location = location;
+ Writer.WritePE(options, this);
+ }
+#endif
+#if !NoXml
+ public virtual void WriteDocumentation(System.IO.TextWriter doc)
+ {
+ if (this.documentation == null) return;
+ XmlTextWriter xwriter = new XmlTextWriter(doc);
+ xwriter.Formatting = Formatting.Indented;
+ xwriter.Indentation = 2;
+ xwriter.WriteProcessingInstruction("xml", "version=\"1.0\"");
+ xwriter.WriteStartElement("doc");
+ AssemblyNode assem = this as AssemblyNode;
+ if (assem != null)
+ {
+ xwriter.WriteStartElement("assembly");
+ xwriter.WriteElementString("name", assem.Name);
+ xwriter.WriteEndElement();
+ }
+ xwriter.WriteStartElement("members");
+ TypeNodeList types = this.Types;
+ for (int i = 1, n = types == null ? 0 : types.Count; i < n; i++)
+ {
+ //^ assert types != null;
+ TypeNode t = types[i]; if (t == null) continue;
+ t.WriteDocumentation(xwriter);
+ }
+ xwriter.WriteEndElement();
+ xwriter.WriteEndElement();
+ xwriter.Close();
+ }
+#endif
+#if !NoWriter
+ public delegate MethodBodySpecializer/*!*/ MethodBodySpecializerFactory(Module/*!*/ m, TypeNodeList/*!*/ pars, TypeNodeList/*!*/ args);
+ public MethodBodySpecializerFactory CreateMethodBodySpecializer;
+ public MethodBodySpecializer/*!*/ GetMethodBodySpecializer(TypeNodeList/*!*/ pars, TypeNodeList/*!*/ args)
+ {
+ if (CreateMethodBodySpecializer != null)
+ return this.CreateMethodBodySpecializer(this, pars, args);
+ return new MethodBodySpecializer(this, pars, args);
+ }
+#endif
+ }
+ public class AssemblyNode : Module
+ { //An assembly is a module with a strong name
+#if !NoWriter
+ public string KeyContainerName;
+ public byte[] KeyBlob;
+#endif
+#if !NoReflection
+ private static Hashtable CompiledAssemblies;// so we can find in-memory compiled assemblies later (contains weak references)
+#endif
+#if !MinimalReader
+ protected AssemblyNode contractAssembly;
+ /// <summary>A separate assembly that supplied the type and method contracts for this assembly.</summary>
+ public virtual AssemblyNode ContractAssembly
+ {
+ get
+ {
+ return this.contractAssembly;
+ }
+ set
+ {
+ if (this.contractAssembly != null) { Debug.Assert(false); return; }
+ this.contractAssembly = value;
+ if (value == null) return;
+ #region Copy over any external references from the contract assembly to this one (if needed)
+ // These external references are needed only for the contract deserializer
+ AssemblyReferenceList ars = new AssemblyReferenceList();
+ AssemblyReferenceList contractReferences = value.AssemblyReferences;
+ // see if contractReferences[i] is already in the external references of "this"
+ for (int i = 0, n = contractReferences == null ? 0 : contractReferences.Count; i < n; i++)
+ {
+ //^ assert contractReferences != null;
+ AssemblyReference aref = contractReferences[i];
+ if (aref == null) continue;
+ if (aref.Assembly != this)
+ { // don't copy the contract's external reference to "this"
+ int j = 0;
+ int m = this.AssemblyReferences == null ? 0 : this.AssemblyReferences.Count;
+ while (j < m)
+ {
+ if (aref.Assembly.Name != null &&
+ this.AssemblyReferences[j].Name != null &&
+ aref.Assembly.Name.Equals(this.AssemblyReferences[j].Name))
+ break;
+ j++;
+ }
+ if (j == m)
+ { // then it wasn't found in the list of the real references
+ ars.Add(contractReferences[i]);
+ }
+ }
+ }
+ if (this.AssemblyReferences == null)
+ this.AssemblyReferences = new AssemblyReferenceList();
+ for (int i = 0, n = ars.Count; i < n; i++)
+ {
+ this.AssemblyReferences.Add(ars[i]);
+ }
+ #endregion Copy over any external references from the contract assembly to this one (if needed)
+
+#if ExtendedRuntime
+ #region Copy over any assembly-level attributes from the Contracts namespace
+ int contractsNamespaceKey = SystemTypes.NonNullType.Namespace.UniqueIdKey;
+ // Copy the assembly-level contract attributes over to the shadowed assembly.
+ foreach(AttributeNode attr in contractAssembly.Attributes) {
+ if(attr.Type != SystemTypes.ShadowsAssemblyAttribute // can't copy this one or the real assembly will be treated as a shadow assembly!
+ &&
+ attr.Type.Namespace != null && attr.Type.Namespace.UniqueIdKey == contractsNamespaceKey)
+ this.Attributes.Add(attr);
+ }
+ #endregion Copy over any assembly-level attributes from the Contracts namespace
+#endif
+
+ TypeNodeList instantiatedTypes = null;
+ if (this.reader != null) instantiatedTypes = this.reader.GetInstantiatedTypes();
+ if (instantiatedTypes != null)
+ for (int i = 0, n = instantiatedTypes.Count; i < n; i++)
+ {
+ TypeNode t = instantiatedTypes[i];
+ if (t == null) continue;
+
+ if (t.members == null)
+ {
+#if ExtendedRuntime
+ // Then will never get to ApplyOutOfBandContracts and will never have any
+ // type-level attributes copied over. So need to do this here as well as
+ // within ApplyOutOfBandContracts
+ TypeNode contractType = this.ContractAssembly.GetType(t.Namespace, t.Name);
+ if (contractType == null) continue;
+ // Copy the type-level contract attributes over to the shadowed type.
+ foreach (AttributeNode attr in contractType.Attributes) {
+ if (attr.Type.Namespace != null && attr.Type.Namespace.UniqueIdKey == contractsNamespaceKey)
+ t.Attributes.Add(attr);
+ }
+#endif
+ continue;
+ }
+#if ExtendedRuntime
+ t.ApplyOutOfBandContracts();
+#endif
+ }
+ }
+ }
+#endif
+ internal static readonly AssemblyNode/*!*/ Dummy = new AssemblyNode();
+ protected string strongName;
+ /// <summary>
+ /// A string containing the name, version, culture and key of this assembly, formatted as required by the CLR loader.
+ /// </summary>
+ public virtual string/*!*/ StrongName
+ {
+ get
+ {
+ if (this.strongName == null)
+ this.strongName = AssemblyNode.GetStrongName(this.Name, this.Version, this.Culture, this.PublicKeyOrToken, (this.Flags & AssemblyFlags.Retargetable) != 0);
+ return this.strongName;
+ }
+ }
+
+ [Obsolete("Please use GetAttribute(TypeNode attributeType)")]
+ public virtual AttributeNode GetAttributeByName(TypeNode attributeType)
+ {
+ if (attributeType == null) return null;
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ //^ assert attributes != null;
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null || mb.BoundMember.DeclaringType == null) continue;
+ if (mb.BoundMember.DeclaringType.FullName != attributeType.FullName) continue;
+ return attr;
+ }
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Gets the first attribute of the given type in the custom attribute list of this member. Returns null if none found.
+ /// The member is assumed to be either imported, or already in a form suitable for export.
+ /// </summary>
+ public virtual AttributeNode GetModuleAttribute(TypeNode attributeType)
+ {
+ if (attributeType == null) return null;
+ AttributeList attributes = this.ModuleAttributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ //^ assert attributes != null;
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != attributeType) continue;
+ return attr;
+ }
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != attributeType) continue;
+ return attr;
+ }
+ return null;
+ }
+
+ public AssemblyNode()
+ : base()
+ {
+ this.NodeType = NodeType.Assembly;
+ this.ContainingAssembly = this;
+ }
+ public AssemblyNode(TypeNodeProvider provider, TypeNodeListProvider listProvider,
+ CustomAttributeProvider provideCustomAttributes, ResourceProvider provideResources, string directory)
+ : base(provider, listProvider, provideCustomAttributes, provideResources)
+ {
+ this.Directory = directory;
+ this.NodeType = NodeType.Assembly;
+ this.ContainingAssembly = this;
+ }
+ public override void Dispose()
+ {
+#if !NoReflection
+ if (this.cachedRuntimeAssembly != null)
+ this.cachedRuntimeAssembly.Dispose();
+ this.cachedRuntimeAssembly = null;
+#endif
+ lock (Reader.StaticAssemblyCache)
+ {
+ foreach (object key in new ArrayList(Reader.StaticAssemblyCache.Keys))
+ {
+ if (Reader.StaticAssemblyCache[key] == this)
+ Reader.StaticAssemblyCache.Remove(key);
+ }
+ AssemblyReference aRef = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[Identifier.For(this.Name).UniqueIdKey];
+ if (aRef != null && aRef.Assembly == this)
+ {
+ aRef.Assembly = null;
+ //TODO: what about other static references to the assembly, such as SystemTypes.SystemXmlAssembly?
+ }
+ }
+ base.Dispose();
+ }
+ private string culture;
+ /// <summary>The target culture of any localized resources in this assembly.</summary>
+ public string Culture
+ {
+ get { return this.culture; }
+ set { this.culture = value; }
+ }
+ private AssemblyFlags flags;
+ /// <summary>An enumeration that identifies the what kind of assembly this is.</summary>
+ public AssemblyFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private string moduleName;
+ /// <summary>Attributes that specifically target a module rather an assembly.</summary>
+ public string ModuleName
+ { //An assembly can have a different name from the module.
+ get { return this.moduleName; }
+ set { this.moduleName = value; }
+ }
+ private byte[] publicKeyOrToken;
+ /// <summary>The public part of the key pair used to sign this assembly, or a hash of the public key.</summary>
+ public byte[] PublicKeyOrToken
+ {
+ get { return this.publicKeyOrToken; }
+ set { this.publicKeyOrToken = value; }
+ }
+ private System.Version version;
+ /// <summary>The version of this assembly.</summary>
+ public System.Version Version
+ {
+ get { return this.version; }
+ set { this.version = value; }
+ }
+ private DateTime fileLastWriteTimeUtc;
+ public DateTime FileLastWriteTimeUtc
+ {
+ get { return this.fileLastWriteTimeUtc; }
+ set { this.fileLastWriteTimeUtc = value; }
+ }
+ protected TypeNodeList exportedTypes;
+ /// <summary>
+ /// Public types defined in other modules making up this assembly and to which other assemblies may refer to.
+ /// </summary>
+ public virtual TypeNodeList ExportedTypes
+ {
+ get
+ {
+ if (this.exportedTypes != null) return this.exportedTypes;
+ if (this.provideTypeNodeList != null)
+ {
+ TypeNodeList types = this.Types; //Gets the exported types as a side-effect
+ if (types != null) types = null;
+ }
+ else
+ this.exportedTypes = new TypeNodeList();
+ return this.exportedTypes;
+ }
+ set
+ {
+ this.exportedTypes = value;
+ }
+ }
+ public bool GetDebugSymbols
+ {
+ get
+ {
+ if (this.reader == null) return false;
+ return this.reader.getDebugSymbols;
+ }
+ set
+ {
+ if (this.reader == null) return;
+ this.reader.getDebugSymbols = value;
+ }
+ }
+#if !MinimalReader
+ public static AssemblyNode GetAssembly(byte[] buffer)
+ {
+ return AssemblyNode.GetAssembly(buffer, null, false, false, true, false);
+ }
+ public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache)
+ {
+ return AssemblyNode.GetAssembly(buffer, cache, false, false, false, false);
+ }
+ public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(byte[] buffer, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (buffer == null) return null;
+ if (CoreSystemTypes.SystemAssembly == null) Debug.Fail("");
+ return (new Reader(buffer, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule() as AssemblyNode;
+ }
+#endif
+ public static AssemblyNode GetAssembly(string location)
+ {
+ return AssemblyNode.GetAssembly(location, null, false, false, true, false);
+ }
+ public static AssemblyNode GetAssembly(string location, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(location, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(string location, IDictionary cache)
+ {
+ return AssemblyNode.GetAssembly(location, cache, false, false, false, false);
+ }
+ public static AssemblyNode GetAssembly(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(string location, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (location == null) return null;
+ if (CoreSystemTypes.SystemAssembly == null) Debug.Fail("");
+ return (new Reader(location, cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches)).ReadModule() as AssemblyNode;
+ }
+#if !MinimalReader || !NoXml || !NoData
+ public static AssemblyNode GetAssembly(AssemblyReference assemblyReference)
+ {
+ return AssemblyNode.GetAssembly(assemblyReference, null, false, false, true, false);
+ }
+ public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(assemblyReference, null, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache)
+ {
+ return AssemblyNode.GetAssembly(assemblyReference, cache, false, false, false, false);
+ }
+ public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(assemblyReference, cache, doNotLockFile, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(AssemblyReference assemblyReference, IDictionary cache, bool doNotLockFile, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (assemblyReference == null) return null;
+ if (CoreSystemTypes.SystemAssembly == null) Debug.Fail("");
+ Reader reader = new Reader(cache, doNotLockFile, getDebugInfo, useGlobalCache, preserveShortBranches);
+ return assemblyReference.Assembly = reader.GetAssemblyFromReference(assemblyReference);
+ }
+#endif
+#if !NoReflection
+ public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly)
+ {
+ return AssemblyNode.GetAssembly(runtimeAssembly, null, false, true, false);
+ }
+ public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache)
+ {
+ return AssemblyNode.GetAssembly(runtimeAssembly, cache, false, false, false);
+ }
+ public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache, bool getDebugInfo, bool useGlobalCache)
+ {
+ return AssemblyNode.GetAssembly(runtimeAssembly, cache, getDebugInfo, useGlobalCache, false);
+ }
+ public static AssemblyNode GetAssembly(System.Reflection.Assembly runtimeAssembly, IDictionary cache, bool getDebugInfo, bool useGlobalCache, bool preserveShortBranches)
+ {
+ if (runtimeAssembly == null) return null;
+ if (CoreSystemTypes.SystemAssembly == null) Debug.Fail("");
+ if (runtimeAssembly.GetName().Name == "mscorlib")
+ {
+ return CoreSystemTypes.SystemAssembly;
+ }
+ if (AssemblyNode.CompiledAssemblies != null)
+ {
+ WeakReference weakRef = (WeakReference)AssemblyNode.CompiledAssemblies[runtimeAssembly];
+ if (weakRef != null)
+ {
+ AssemblyNode assem = (AssemblyNode)weakRef.Target;
+ if (assem == null) AssemblyNode.CompiledAssemblies.Remove(runtimeAssembly); //Remove the dead WeakReference
+ return assem;
+ }
+ }
+ if (runtimeAssembly.Location != null && runtimeAssembly.Location.Length > 0)
+ return AssemblyNode.GetAssembly(runtimeAssembly.Location, cache, false, getDebugInfo, useGlobalCache, preserveShortBranches);
+ //Get here for in memory assemblies that were not loaded from a known AssemblyNode
+ //Need CLR support to handle such assemblies. For now return null.
+ return null;
+ }
+#endif
+ public void SetupDebugReader(string pdbSearchPath)
+ {
+ if (this.reader == null) { Debug.Assert(false); return; }
+ this.reader.SetupDebugReader(this.Location, pdbSearchPath);
+ }
+ internal static string/*!*/ GetStrongName(string name, Version version, string culture, byte[] publicKey, bool retargetable)
+ {
+ if (version == null) version = new Version();
+ StringBuilder result = new StringBuilder();
+ result.Append(name);
+ result.Append(", Version="); result.Append(version.ToString());
+ result.Append(", Culture="); result.Append(((culture == null || culture.Length == 0) ? "neutral" : culture));
+ result.Append(AssemblyNode.GetKeyString(publicKey));
+ if (retargetable)
+ result.Append(", Retargetable=Yes");
+ return result.ToString();
+ }
+ private System.Reflection.AssemblyName assemblyName;
+ public System.Reflection.AssemblyName GetAssemblyName()
+ {
+ if (this.assemblyName == null)
+ {
+ System.Reflection.AssemblyName aName = new System.Reflection.AssemblyName();
+ if (this.Location != null && this.Location != "unknown:location")
+ {
+ StringBuilder sb = new StringBuilder("file:///");
+ sb.Append(Path.GetFullPath(this.Location));
+ sb.Replace('\\', '/');
+ aName.CodeBase = sb.ToString();
+ }
+ aName.CultureInfo = new System.Globalization.CultureInfo(this.Culture);
+ if (this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 8)
+ aName.Flags = System.Reflection.AssemblyNameFlags.PublicKey;
+ if ((this.Flags & AssemblyFlags.Retargetable) != 0)
+ aName.Flags |= (System.Reflection.AssemblyNameFlags)AssemblyFlags.Retargetable;
+ aName.HashAlgorithm = (System.Configuration.Assemblies.AssemblyHashAlgorithm)this.HashAlgorithm;
+ if (this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 0)
+ aName.SetPublicKey(this.PublicKeyOrToken);
+ else
+ aName.SetPublicKey(new byte[0]);
+ aName.Name = this.Name;
+ aName.Version = this.Version;
+ switch (this.Flags & AssemblyFlags.CompatibilityMask)
+ {
+ case AssemblyFlags.NonSideBySideCompatible:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameDomain;
+ break;
+ case AssemblyFlags.NonSideBySideProcess:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
+ break;
+ case AssemblyFlags.NonSideBySideMachine:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameMachine;
+ break;
+ }
+ this.assemblyName = aName;
+ }
+ return this.assemblyName;
+ }
+#if !NoReflection
+ private sealed class CachedRuntimeAssembly : IDisposable
+ {
+ internal System.Reflection.Assembly Value;
+ internal CachedRuntimeAssembly(System.Reflection.Assembly assembly)
+ {
+ this.Value = assembly;
+ }
+ ~CachedRuntimeAssembly()
+ {
+ this.Dispose();
+ }
+ public void Dispose()
+ {
+ if (this.Value != null)
+ {
+ if (AssemblyNode.CompiledAssemblies != null)
+ AssemblyNode.CompiledAssemblies.Remove(this.Value);
+ }
+ this.Value = null;
+ GC.SuppressFinalize(this);
+ }
+ }
+ private CachedRuntimeAssembly cachedRuntimeAssembly;
+ public System.Reflection.Assembly GetRuntimeAssembly()
+ {
+ return this.GetRuntimeAssembly(null, null);
+ }
+#endif
+#if !NoReflection
+ public System.Reflection.Assembly GetRuntimeAssembly(System.Security.Policy.Evidence evidence)
+ {
+ return this.GetRuntimeAssembly(evidence, null);
+ }
+ public System.Reflection.Assembly GetRuntimeAssembly(AppDomain targetAppDomain)
+ {
+ return this.GetRuntimeAssembly(null, targetAppDomain);
+ }
+ public System.Reflection.Assembly GetRuntimeAssembly(System.Security.Policy.Evidence evidence, AppDomain targetAppDomain)
+ {
+ System.Reflection.Assembly result = this.cachedRuntimeAssembly == null ? null : this.cachedRuntimeAssembly.Value;
+ if (result == null || evidence != null || targetAppDomain != null)
+ {
+ lock (this)
+ {
+ if (this.cachedRuntimeAssembly != null && evidence == null && targetAppDomain == null) return this.cachedRuntimeAssembly.Value;
+ if (targetAppDomain == null) targetAppDomain = AppDomain.CurrentDomain;
+ if (this.Location != null)
+ {
+ string name = this.StrongName;
+ System.Reflection.Assembly[] alreadyLoadedAssemblies = targetAppDomain.GetAssemblies();
+ if (alreadyLoadedAssemblies != null)
+ for (int i = 0, n = alreadyLoadedAssemblies.Length; i < n; i++)
+ {
+ System.Reflection.Assembly a = alreadyLoadedAssemblies[i];
+ if (a == null) continue;
+ if (a.FullName == name)
+ {
+ result = a; break;
+ }
+ }
+ if (result == null)
+ {
+ if (evidence != null)
+ result = targetAppDomain.Load(this.GetAssemblyName(), evidence);
+ else
+ result = targetAppDomain.Load(this.GetAssemblyName());
+ }
+ }
+#if !NoWriter
+ // without the writer, it is impossible to get the runtime
+ // assembly for an AssemblyNode which does not correspond
+ // to a file on disk, we will return null in that case.
+ else
+ {
+ byte[] executable = null;
+ byte[] debugSymbols = null;
+ if ((this.Flags & (AssemblyFlags.EnableJITcompileTracking | AssemblyFlags.DisableJITcompileOptimizer)) != 0)
+ {
+ this.WriteModule(out executable, out debugSymbols);
+ if (evidence != null)
+ result = targetAppDomain.Load(executable, debugSymbols, evidence);
+ else
+ result = targetAppDomain.Load(executable, debugSymbols);
+ }
+ else
+ {
+ this.WriteModule(out executable);
+ if (evidence != null)
+ result = targetAppDomain.Load(executable, null, evidence);
+ else
+ result = targetAppDomain.Load(executable);
+ }
+ }
+#endif
+ if (result != null && evidence == null && targetAppDomain == AppDomain.CurrentDomain)
+ {
+ this.AddCachedAssembly(result);
+ this.cachedRuntimeAssembly = new CachedRuntimeAssembly(result);
+ }
+ }
+ }
+ return result;
+ }
+ private void AddCachedAssembly(System.Reflection.Assembly/*!*/ runtimeAssembly)
+ {
+ if (AssemblyNode.CompiledAssemblies == null)
+ AssemblyNode.CompiledAssemblies = Hashtable.Synchronized(new Hashtable());
+ AssemblyNode.CompiledAssemblies[runtimeAssembly] = new WeakReference(this);
+ }
+#endif
+ private static string GetKeyString(byte[] publicKey)
+ {
+ if (publicKey == null) return null;
+ int n = publicKey.Length;
+ StringBuilder str;
+ if (n > 8)
+ {
+#if !ROTOR
+ System.Security.Cryptography.SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
+ publicKey = sha1.ComputeHash(publicKey);
+ byte[] token = new byte[8];
+ for (int i = 0, m = publicKey.Length - 1; i < 8; i++)
+ token[i] = publicKey[m - i];
+ publicKey = token;
+ n = 8;
+#else
+ n = 0; //TODO: figure out how to compute the token on ROTOR
+#endif
+ }
+ if (n == 0)
+ str = new StringBuilder(", PublicKeyToken=null");
+ else
+ str = new StringBuilder(", PublicKeyToken=", n * 2 + 17);
+ for (int i = 0; i < n; i++)
+ str.Append(publicKey[i].ToString("x2"));
+ return str.ToString();
+ }
+ protected TrivialHashtable friends;
+ public virtual bool MayAccessInternalTypesOf(AssemblyNode assembly)
+ {
+ if (this == assembly) return true;
+ if (assembly == null || SystemTypes.InternalsVisibleToAttribute == null) return false;
+ if (this.friends == null) this.friends = new TrivialHashtable();
+ object ob = this.friends[assembly.UniqueKey];
+ if (ob == (object)string.Empty) return false;
+ if (ob == this) return true;
+ AttributeList attributes = assembly.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ //^ assert attributes != null;
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.InternalsVisibleToAttribute) continue;
+ }
+ else
+ {
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != SystemTypes.InternalsVisibleToAttribute) continue;
+ }
+ if (attr.Expressions == null || attr.Expressions.Count < 1) continue;
+ Literal argLit = attr.Expressions[0] as Literal;
+ if (argLit == null) continue;
+ string friendName = argLit.Value as string;
+ if (friendName == null) continue;
+ try
+ {
+ AssemblyReference ar = new AssemblyReference(friendName);
+ byte[] tok = ar.PublicKeyToken;
+ if (tok != null && this.PublicKeyOrToken != null) tok = this.PublicKeyToken;
+ if (!ar.Matches(this.Name, ar.Version, ar.Culture, tok)) continue;
+#if !FxCop
+ }
+ catch (ArgumentException e)
+ {
+ if (this.MetadataImportErrors == null) this.MetadataImportErrors = new ArrayList();
+ this.MetadataImportErrors.Add(e.Message);
+ continue;
+ }
+#else
+ }finally{}
+#endif
+ this.friends[assembly.UniqueKey] = this;
+ return true;
+ }
+ this.friends[assembly.UniqueKey] = string.Empty;
+ return false;
+ }
+ public AssemblyReferenceList GetFriendAssemblies()
+ {
+ if (SystemTypes.InternalsVisibleToAttribute == null) return null;
+ AttributeList attributes = this.Attributes;
+ if (attributes == null) return null;
+ int n = attributes.Count; if (n == 0) return null;
+ AssemblyReferenceList result = new AssemblyReferenceList(n);
+ for (int i = 0; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.InternalsVisibleToAttribute) continue;
+ }
+ else
+ {
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != SystemTypes.InternalsVisibleToAttribute) continue;
+ }
+ if (attr.Expressions == null || attr.Expressions.Count < 1) continue;
+ Literal argLit = attr.Expressions[0] as Literal;
+ if (argLit == null) continue;
+ string friendName = argLit.Value as string;
+ if (friendName == null) continue;
+ result.Add(new AssemblyReference(friendName));
+ }
+ return result;
+ }
+ /// <summary>
+ /// The attributes associated with this module. This corresponds to C# custom attributes with the module target specifier.
+ /// </summary>
+ public virtual AttributeList ModuleAttributes
+ {
+ get
+ {
+ if (this.moduleAttributes != null) return this.moduleAttributes;
+ if (this.provideCustomAttributes != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.moduleAttributes == null)
+ this.provideCustomAttributes(this);
+ }
+ }
+ else
+ this.moduleAttributes = new AttributeList();
+ return this.moduleAttributes;
+ }
+ set
+ {
+ this.moduleAttributes = value;
+ }
+ }
+ protected AttributeList moduleAttributes;
+
+ protected byte[] token;
+ public virtual byte[] PublicKeyToken
+ {
+ get
+ {
+ if (this.token != null) return this.token;
+ if (this.PublicKeyOrToken == null || this.PublicKeyOrToken.Length == 0) return null;
+ if (this.PublicKeyOrToken.Length == 8) return this.token = this.PublicKeyOrToken;
+#if !ROTOR
+ System.Security.Cryptography.SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
+ byte[] hashedKey = sha1.ComputeHash(this.PublicKeyOrToken);
+ byte[] token = new byte[8];
+ for (int i = 0, n = hashedKey.Length - 1; i < 8; i++) token[i] = hashedKey[n - i];
+ return this.token = token;
+#else
+ return null;
+#endif
+ }
+ }
+#if !MinimalReader
+ public override string ToString()
+ {
+ return this.Name;
+ }
+#endif
+ }
+ public class AssemblyReference : Node
+ {
+#if !MinimalReader
+ public IdentifierList Aliases;
+#endif
+ private byte[] token;
+ internal Reader Reader;
+ public AssemblyReference()
+ : base(NodeType.AssemblyReference)
+ {
+ }
+ public AssemblyReference(AssemblyNode/*!*/ assembly)
+ : base(NodeType.AssemblyReference)
+ {
+ this.culture = assembly.Culture;
+ this.flags = assembly.Flags & ~AssemblyFlags.PublicKey;
+ this.hashValue = assembly.HashValue;
+ this.name = assembly.Name;
+ this.publicKeyOrToken = assembly.PublicKeyOrToken;
+ if (assembly.PublicKeyOrToken != null && assembly.PublicKeyOrToken.Length > 8)
+ this.flags |= AssemblyFlags.PublicKey;
+ this.location = assembly.Location;
+ this.version = assembly.Version;
+ this.assembly = assembly;
+ }
+#if !MinimalReader
+ public AssemblyReference(string assemblyStrongName, SourceContext sctx)
+ : this(assemblyStrongName)
+ {
+ this.SourceContext = sctx;
+ }
+#endif
+ public AssemblyReference(string assemblyStrongName)
+ : base(NodeType.AssemblyReference)
+ {
+ AssemblyFlags flags = AssemblyFlags.None;
+ if (assemblyStrongName == null) { Debug.Assert(false); assemblyStrongName = ""; }
+ int i = 0, n = assemblyStrongName.Length;
+ string name = ParseToken(assemblyStrongName, ref i);
+ string version = null;
+ string culture = null;
+ string token = null;
+ while (i < n)
+ {
+ if (assemblyStrongName[i] != ',') throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
+ i++;
+ while (i < n && char.IsWhiteSpace(assemblyStrongName[i])) i++;
+ switch (assemblyStrongName[i])
+ {
+ case 'v':
+ case 'V': version = ParseAssignment(assemblyStrongName, "Version", ref i); break;
+ case 'c':
+ case 'C': culture = ParseAssignment(assemblyStrongName, "Culture", ref i); break;
+ case 'p':
+ case 'P':
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(assemblyStrongName, i, "PublicKeyToken", 0, "PublicKeyToken".Length) == 0)
+ token = ParseAssignment(assemblyStrongName, "PublicKeyToken", ref i);
+ else
+ {
+ token = ParseAssignment(assemblyStrongName, "PublicKey", ref i);
+ flags |= AssemblyFlags.PublicKey;
+ }
+ break;
+ case 'r':
+ case 'R':
+ string yesOrNo = ParseAssignment(assemblyStrongName, "Retargetable", ref i);
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(yesOrNo, "Yes") == 0)
+ flags |= AssemblyFlags.Retargetable;
+ break;
+ }
+ while (i < n && assemblyStrongName[i] == ']') i++;
+ }
+ while (i < n && char.IsWhiteSpace(assemblyStrongName[i])) i++;
+ if (i < n) throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(culture, "neutral") == 0)
+ culture = null;
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(token, "null") == 0)
+ token = null;
+ byte[] tok = null;
+ if (token != null && (n = token.Length) > 0)
+ {
+ if (n > 16)
+ {
+ ArrayList tokArr = new ArrayList();
+ if (n % 2 == 1)
+ {
+ tokArr.Add(byte.Parse(token.Substring(0, 1), System.Globalization.NumberStyles.HexNumber, null));
+ n--;
+ }
+ for (i = 0; i < n; i += 2)
+ {
+#if WHIDBEY
+ byte b = 0;
+ bool goodByte = byte.TryParse(token.Substring(i, 2), System.Globalization.NumberStyles.HexNumber, null, out b);
+ Debug.Assert(goodByte);
+#else
+ byte b = byte.Parse(token.Substring(i, 2), System.Globalization.NumberStyles.HexNumber, null);
+#endif
+ tokArr.Add(b);
+ }
+ tok = (byte[])tokArr.ToArray(typeof(byte));
+ }
+ else
+ {
+ ulong tk = ulong.Parse(token, System.Globalization.NumberStyles.HexNumber, null);
+ tok = new byte[8];
+ tok[0] = (byte)(tk >> 56);
+ tok[1] = (byte)(tk >> 48);
+ tok[2] = (byte)(tk >> 40);
+ tok[3] = (byte)(tk >> 32);
+ tok[4] = (byte)(tk >> 24);
+ tok[5] = (byte)(tk >> 16);
+ tok[6] = (byte)(tk >> 8);
+ tok[7] = (byte)tk;
+ }
+ }
+ this.culture = culture;
+ this.name = name;
+ this.publicKeyOrToken = tok;
+ this.version = version == null || version.Length == 0 ? null : new Version(version);
+ this.flags = flags;
+ }
+ private static string ParseToken(string/*!*/ assemblyStrongName, ref int i)
+ {
+ Debug.Assert(assemblyStrongName != null);
+ int n = assemblyStrongName.Length;
+ Debug.Assert(0 <= i && i < n);
+ while (i < n && char.IsWhiteSpace(assemblyStrongName[i])) i++;
+ StringBuilder sb = new StringBuilder(n);
+ while (i < n)
+ {
+ char ch = assemblyStrongName[i];
+ if (ch == ',' || ch == ']' || char.IsWhiteSpace(ch)) break;
+ sb.Append(ch);
+ i++;
+ }
+ while (i < n && char.IsWhiteSpace(assemblyStrongName[i])) i++;
+ return sb.ToString();
+ }
+ private static string ParseAssignment(string/*!*/ assemblyStrongName, string/*!*/ target, ref int i)
+ {
+ Debug.Assert(assemblyStrongName != null && target != null);
+ int n = assemblyStrongName.Length;
+ Debug.Assert(0 < i && i < n);
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(assemblyStrongName, i, target, 0, target.Length) != 0)
+ goto throwError;
+ i += target.Length;
+ while (i < n && char.IsWhiteSpace(assemblyStrongName[i])) i++;
+ if (i >= n || assemblyStrongName[i] != '=') goto throwError;
+ i++;
+ if (i >= n) goto throwError;
+ return ParseToken(assemblyStrongName, ref i);
+ throwError:
+ throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.InvalidAssemblyStrongName, assemblyStrongName), "assemblyStrongName");
+ }
+ private string culture;
+ public string Culture
+ {
+ get { return this.culture; }
+ set { this.culture = value; }
+ }
+ private AssemblyFlags flags;
+ public AssemblyFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private byte[] hashValue;
+ public byte[] HashValue
+ {
+ get { return this.hashValue; }
+ set { this.hashValue = value; }
+ }
+ private string name;
+ public string Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ private byte[] publicKeyOrToken;
+ public byte[] PublicKeyOrToken
+ {
+ get { return this.publicKeyOrToken; }
+ set { this.publicKeyOrToken = value; }
+ }
+ private System.Version version;
+ public System.Version Version
+ {
+ get { return this.version; }
+ set { this.version = value; }
+ }
+ private string location;
+ public string Location
+ {
+ get { return this.location; }
+ set { this.location = value; }
+ }
+ protected internal AssemblyNode assembly;
+ public virtual AssemblyNode Assembly
+ {
+ get
+ {
+ if (this.assembly != null) return this.assembly;
+ if (this.Reader != null)
+ return this.assembly = this.Reader.GetAssemblyFromReference(this);
+ return null;
+ }
+ set
+ {
+ this.assembly = value;
+ }
+ }
+ protected string strongName;
+ public virtual string StrongName
+ {
+ get
+ {
+ if (this.strongName == null)
+ this.strongName = AssemblyNode.GetStrongName(this.Name, this.Version, this.Culture, this.PublicKeyOrToken, (this.Flags & AssemblyFlags.Retargetable) != 0);
+ return this.strongName;
+ }
+ }
+ private System.Reflection.AssemblyName assemblyName;
+ public System.Reflection.AssemblyName GetAssemblyName()
+ {
+ if (this.assemblyName == null)
+ {
+ System.Reflection.AssemblyName aName = new System.Reflection.AssemblyName();
+ aName.CultureInfo = new System.Globalization.CultureInfo(this.Culture == null ? "" : this.Culture);
+ if (this.PublicKeyOrToken != null && this.PublicKeyOrToken.Length > 8)
+ aName.Flags = System.Reflection.AssemblyNameFlags.PublicKey;
+ if ((this.Flags & AssemblyFlags.Retargetable) != 0)
+ aName.Flags |= (System.Reflection.AssemblyNameFlags)AssemblyFlags.Retargetable;
+ aName.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.SHA1;
+ if (this.PublicKeyOrToken != null)
+ {
+ if (this.PublicKeyOrToken.Length > 8)
+ aName.SetPublicKey(this.PublicKeyOrToken);
+ else if (this.PublicKeyOrToken.Length > 0)
+ aName.SetPublicKeyToken(this.PublicKeyOrToken);
+ }
+ else
+ aName.SetPublicKey(new byte[0]);
+ aName.Name = this.Name;
+ aName.Version = this.Version;
+ switch (this.Flags & AssemblyFlags.CompatibilityMask)
+ {
+ case AssemblyFlags.NonSideBySideCompatible:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameDomain;
+ break;
+ case AssemblyFlags.NonSideBySideProcess:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
+ break;
+ case AssemblyFlags.NonSideBySideMachine:
+ aName.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameMachine;
+ break;
+ }
+ this.assemblyName = aName;
+ }
+ return this.assemblyName;
+ }
+ public bool Matches(string name, Version version, string culture, byte[] publicKeyToken)
+ {
+ if (culture != null && culture.Length == 0) culture = null;
+ if (this.Culture != null && this.Culture.Length == 0) this.Culture = null;
+ if (this.Version != version && this.Version != null && (version == null || !this.Version.Equals(version))) return false;
+ if (PlatformHelpers.StringCompareOrdinalIgnoreCase(this.Name, name) != 0 ||
+ PlatformHelpers.StringCompareOrdinalIgnoreCase(this.Culture, culture) != 0) return false;
+ if ((this.Flags & AssemblyFlags.Retargetable) != 0) return true;
+ byte[] thisToken = this.PublicKeyToken;
+ if (publicKeyToken == null) return thisToken == null;
+ if (thisToken == publicKeyToken) return true;
+ if (thisToken == null) return false;
+ int n = publicKeyToken.Length;
+ if (n != thisToken.Length) return false;
+ for (int i = 0; i < n; i++) if (thisToken[i] != publicKeyToken[i]) return false;
+ return true;
+ }
+ public bool MatchesIgnoringVersion(AssemblyReference reference)
+ {
+ if (reference == null) return false;
+ return this.Matches(reference.Name, this.Version, reference.Culture, reference.PublicKeyToken);
+ }
+ public byte[] PublicKeyToken
+ {
+ get
+ {
+ if (this.token != null) return this.token;
+ if (this.PublicKeyOrToken == null || this.PublicKeyOrToken.Length == 0) return null;
+ if (this.PublicKeyOrToken.Length == 8) return this.token = this.PublicKeyOrToken;
+#if !ROTOR
+ System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();
+ byte[] hashedKey = sha.ComputeHash(this.PublicKeyOrToken);
+ byte[] token = new byte[8];
+ for (int i = 0, n = hashedKey.Length - 1; i < 8; i++) token[i] = hashedKey[n - i];
+ return this.token = token;
+#else
+ return null;
+#endif
+ }
+ }
+ }
+ public class ModuleReference : Node
+ {
+ private Module module;
+ private string name;
+ public ModuleReference()
+ : base(NodeType.ModuleReference)
+ {
+ }
+ public ModuleReference(string name, Module module)
+ : base(NodeType.ModuleReference)
+ {
+ this.name = name;
+ this.module = module;
+ }
+ public Module Module
+ {
+ get { return this.module; }
+ set { this.module = value; }
+ }
+ public string Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ }
+ /// <summary>
+ /// A member of a Namespace or a TypeNode
+ /// </summary>
+ public abstract class Member : Node
+ {
+#if !MinimalReader
+ /// <summary>The namespace of which this node is a member. Null if this node is a member of type.</summary>
+ public Namespace DeclaringNamespace;
+ /// <summary>
+ /// Indicates that the signature of this member may include unsafe types such as pointers. For methods and properties, it also indicates that the
+ /// code may contain unsafe constructions such as pointer arithmetic.
+ /// </summary>
+ public bool IsUnsafe;
+ /// <summary>A list of other nodes that refer to this member. Must be filled in by client code.</summary>
+ public NodeList References;
+#endif
+ protected Member(NodeType nodeType)
+ : base(nodeType)
+ {
+ }
+ protected Member(TypeNode declaringType, AttributeList attributes, Identifier name, NodeType nodeType)
+ : base(nodeType)
+ {
+ this.attributes = attributes;
+ this.declaringType = declaringType;
+ this.name = name;
+ }
+ private TypeNode declaringType;
+ /// <summary>The type of which this node is a member. Null if this node is a member of a Namespace.</summary>
+ public TypeNode DeclaringType
+ {
+ get { return this.declaringType; }
+ set { this.declaringType = value; }
+ }
+ private Identifier name;
+ /// <summary>The unqualified name of the member.</summary>
+ public Identifier Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+#if ExtendedRuntime
+ private Anonymity anonymity;
+#endif
+ protected AttributeList attributes;
+ private bool notObsolete;
+ private ObsoleteAttribute obsoleteAttribute;
+
+ /// <summary>
+ /// The attributes of this member. Corresponds to custom attribute annotations in C#.
+ /// </summary>
+ public virtual AttributeList Attributes
+ {
+ get
+ {
+ if (this.attributes != null) return this.attributes;
+ return this.attributes = new AttributeList();
+ }
+ set
+ {
+ this.attributes = value;
+ }
+ }
+ protected Member hiddenMember;
+ public virtual Member HiddenMember
+ {
+ get
+ {
+ return this.hiddenMember;
+ }
+ set
+ {
+ this.hiddenMember = value;
+ }
+ }
+ protected bool hidesBaseClassMemberSpecifiedExplicitly;
+ protected bool hidesBaseClassMember;
+ /// <summary>Indicates if this is a member of a subclass that intentionally has the same signature as a member of a base class. Corresponds to the "new" modifier in C#.</summary>
+ public bool HidesBaseClassMember
+ {
+ get
+ {
+ if (this.hidesBaseClassMemberSpecifiedExplicitly)
+ return this.hidesBaseClassMember;
+ else
+ return this.HiddenMember != null;
+ }
+ set
+ {
+ this.hidesBaseClassMember = value;
+ this.hidesBaseClassMemberSpecifiedExplicitly = true;
+ }
+ }
+ protected Member overriddenMember;
+ public virtual Member OverriddenMember
+ {
+ get
+ {
+ return this.overriddenMember;
+ }
+ set
+ {
+ this.overriddenMember = value;
+ }
+ }
+ protected bool overridesBaseClassMemberSpecifiedExplicitly;
+ protected bool overridesBaseClassMember;
+ /// <summary>Indicates if this is a virtual method of a subclass that intentionally overrides a method of a base class. Corresponds to the "override" modifier in C#.</summary>
+ public virtual bool OverridesBaseClassMember
+ {
+ get
+ {
+ if (this.overridesBaseClassMemberSpecifiedExplicitly)
+ return this.overridesBaseClassMember;
+ else
+ return this.OverriddenMember != null;
+ }
+ set
+ {
+ this.overridesBaseClassMember = value;
+ this.overridesBaseClassMemberSpecifiedExplicitly = true;
+ }
+ }
+ /// <summary>
+ /// Gets the first attribute of the given type in the attribute list of this member. Returns null if none found.
+ /// This should not be called until the AST containing this member has been processed to replace symbolic references
+ /// to members with references to the actual members.
+ /// </summary>
+ public virtual AttributeNode GetAttribute(TypeNode attributeType)
+ {
+ if (attributeType == null) return null;
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != attributeType) continue;
+ return attr;
+ }
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != attributeType) continue;
+ return attr;
+ }
+ return null;
+ }
+ public virtual AttributeList GetFilteredAttributes(TypeNode attributeType)
+ {
+ if (attributeType == null) return this.Attributes;
+ AttributeList attributes = this.Attributes;
+ AttributeList filtered = new AttributeList();
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember != null && mb.BoundMember.DeclaringType == attributeType) continue;
+ filtered.Add(attr);
+ continue;
+ }
+ Literal lit = attr.Constructor as Literal;
+ if (lit != null && (lit.Value as TypeNode) == attributeType) continue;
+ filtered.Add(attr);
+ }
+ return filtered;
+ }
+#if ExtendedRuntime
+ /// <summary>
+ /// If this is true, the name of the member is meaningless and the member is intended as an "invisible" container for other members.
+ /// The value of this property is controlled by the presence or absence of the Anonymous attribute.
+ /// </summary>
+ public bool IsAnonymous{
+ get{
+ switch (this.Anonymity){
+ case Anonymity.None:
+ case Anonymity.Unknown:
+ return false;
+ default:
+ return true;
+ }
+ }
+ }
+ /// <summary>
+ /// Exposes the value of the Anonymous attribute. The value is Anonimity.None if no attribute is present.
+ /// </summary>
+ public Anonymity Anonymity{
+ get{
+ if (this.anonymity == Anonymity.Unknown){
+ AttributeNode attr = this.GetAttribute(SystemTypes.AnonymousAttribute);
+ if (attr == null)
+ this.anonymity = Anonymity.None;
+ else{
+ this.anonymity = Anonymity.Structural; // default
+ if (attr.Expressions != null){
+ for (int i = 0, n = attr.Expressions.Count; i < n; i++){
+ NamedArgument na = attr.Expressions[i] as NamedArgument;
+ if (na == null || na.Name != null) continue;
+ if (na.Name.UniqueIdKey == StandardIds.Anonymity.UniqueIdKey){
+ Literal lit = na.Value as Literal;
+ if (lit == null) continue;
+ this.anonymity = (Anonymity)lit.Value;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return this.anonymity;
+ }
+ }
+ CciMemberKind cciKind;
+ public CciMemberKind CciKind{
+ get{
+ if (cciKind == CciMemberKind.Unknown){
+ AttributeNode a = GetAttribute(SystemTypes.CciMemberKindAttribute);
+ if (a == null)
+ cciKind = CciMemberKind.Regular;
+ else
+ cciKind = (CciMemberKind) ((Literal) a.Expressions[0]).Value;
+ }
+ return cciKind;
+ }
+ set{
+ this.cciKind = value;
+ }
+ }
+#endif
+ /// <summary>
+ /// The concatenation of the FullName of the containing member and the name of this member.
+ /// Separated with a '.' character if the containing member is a namespace and a '+' character if the containing member is a Type.
+ /// Includes the parameter type full names when this member is a method or a property. Also includes (generic) template arguments.
+ /// </summary>
+ public abstract string/*!*/ FullName { get; }
+ /// <summary>True if all references to this member must be from the assembly containing the definition of this member. </summary>
+ public abstract bool IsAssembly { get; }
+ /// <summary>
+ /// True if access to this member is controlled by the compiler and not the runtime. Cannot be accessed from other assemblies since these
+ /// are not necessarily controlled by the same compiler.
+ /// </summary>
+ public abstract bool IsCompilerControlled { get; }
+ /// <summary>True if this member can only be accessed from subclasses of the class declaring this member.</summary>
+ public abstract bool IsFamily { get; }
+ /// <summary>True if this member can only be accessed from subclasses of the class declaring this member, provided that these subclasses are also
+ /// contained in the assembly containing this member.</summary>
+ public abstract bool IsFamilyAndAssembly { get; }
+ /// <summary>True if all references to this member must either be from the assembly containing the definition of this member,
+ /// or from a subclass of the class declaring this member.</summary>
+ public abstract bool IsFamilyOrAssembly { get; }
+ /// <summary>True if all references to this member must be from members of the type declaring this member./// </summary>
+ public abstract bool IsPrivate { get; }
+ /// <summary>True if the member can be accessed from anywhere./// </summary>
+ public abstract bool IsPublic { get; }
+ /// <summary>True if the name of this member conforms to a naming pattern with special meaning. For example the name of a property getter.</summary>
+ public abstract bool IsSpecialName { get; }
+ /// <summary>True if this member always has the same value or behavior for all instances the declaring type.</summary>
+ public abstract bool IsStatic { get; }
+ /// <summary>True if another assembly can contain a reference to this member.</summary>
+ public abstract bool IsVisibleOutsideAssembly { get; }
+ /// <summary>A cached reference to the first Obsolete attribute of this member. Null if no such attribute exsits.</summary>
+ public ObsoleteAttribute ObsoleteAttribute
+ {
+ get
+ {
+ if (this.notObsolete) return null;
+ if (this.obsoleteAttribute == null)
+ {
+ AttributeNode attr = this.GetAttribute(SystemTypes.ObsoleteAttribute);
+ if (attr != null)
+ {
+ ExpressionList args = attr.Expressions;
+ int numArgs = args == null ? 0 : args.Count;
+ Literal lit0 = numArgs > 0 ? args[0] as Literal : null;
+ Literal lit1 = numArgs > 1 ? args[1] as Literal : null;
+ string message = lit0 != null ? lit0.Value as string : null;
+ object isError = lit1 != null ? lit1.Value : null;
+ if (isError is bool)
+ return this.obsoleteAttribute = new ObsoleteAttribute(message, (bool)isError);
+ else
+ return this.obsoleteAttribute = new ObsoleteAttribute(message);
+ }
+ this.notObsolete = true;
+ }
+ return this.obsoleteAttribute;
+ }
+ set
+ {
+ this.obsoleteAttribute = value;
+ this.notObsolete = false;
+ }
+ }
+#if !MinimalReader
+ /// <summary>The source code, if any, corresponding to the value in Documentation.</summary>
+ public Node DocumentationNode;
+#endif
+#if !NoXml
+ protected XmlNode documentation;
+ /// <summary>The body of an XML element containing a description of this member. Used to associated documentation (such as this comment) with members.
+ /// The fragment usually conforms to the structure defined in the C# standard.</summary>
+ public virtual XmlNode Documentation
+ {
+ get
+ {
+ XmlNode documentation = this.documentation;
+ if (documentation != null) return documentation;
+ TypeNode t = this.DeclaringType;
+ if (t == null) t = this as TypeNode;
+ Module m = t == null ? null : t.DeclaringModule;
+ TrivialHashtable cache = m == null ? null : m.GetMemberDocumentationCache();
+ if (cache == null) return null;
+ return this.documentation = (XmlNode)cache[this.DocumentationId.UniqueIdKey];
+ }
+ set
+ {
+ this.documentation = value;
+ }
+ }
+ protected Identifier documentationId;
+ protected virtual Identifier GetDocumentationId()
+ {
+ return Identifier.Empty;
+ }
+ /// <summary>
+ /// The value of the name attribute of the XML element whose body is the XML fragment returned by Documentation.
+ /// </summary>
+ public Identifier DocumentationId
+ {
+ get
+ {
+ Identifier documentationId = this.documentationId;
+ if (documentationId != null) return documentationId;
+ return this.DocumentationId = this.GetDocumentationId();
+ }
+ set
+ {
+ this.documentationId = value;
+ }
+ }
+ protected string helpText;
+ /// <summary>
+ /// The value of the summary child element of the XML fragment returned by Documentation. All markup is stripped from the value.
+ /// </summary>
+ public virtual string HelpText
+ {
+ get
+ {
+ string helpText = this.helpText;
+ if (helpText != null) return helpText;
+ XmlNode documentation = this.Documentation;
+ if (documentation != null && documentation.HasChildNodes)
+ {
+ //^ assume documentation.ChildNodes != null;
+ foreach (XmlNode child in documentation.ChildNodes)
+ if (child.Name == "summary")
+ return this.helpText = this.GetHelpText(child);
+ }
+ return this.helpText = "";
+ }
+ set
+ {
+ this.helpText = value;
+ }
+ }
+ public virtual string GetParameterHelpText(string parameterName)
+ {
+ XmlNode documentation = this.Documentation;
+ if (documentation == null || documentation.ChildNodes == null) return null;
+ foreach (XmlNode cdoc in documentation.ChildNodes)
+ {
+ if (cdoc == null) continue;
+ if (cdoc.Name != "param") continue;
+ if (cdoc.Attributes == null) continue;
+ foreach (XmlAttribute attr in cdoc.Attributes)
+ {
+ if (attr == null || attr.Name != "name" || attr.Value != parameterName) continue;
+ if (!cdoc.HasChildNodes) continue;
+ return this.GetHelpText(cdoc);
+ }
+ }
+ return null;
+ }
+ private string GetHelpText(XmlNode node)
+ {
+ if (node == null) return "";
+ StringBuilder sb = new StringBuilder();
+ if (node.HasChildNodes)
+ {
+ foreach (XmlNode child in node.ChildNodes)
+ {
+ switch (child.NodeType)
+ {
+ case XmlNodeType.Element:
+ string str = this.GetHelpText(child);
+ if (str == null || str.Length == 0) continue;
+ if (sb.Length > 0 && !Char.IsPunctuation(str[0]))
+ sb.Append(' ');
+ sb.Append(str);
+ break;
+ case XmlNodeType.CDATA:
+ case XmlNodeType.Entity:
+ case XmlNodeType.Text:
+ this.AppendValue(sb, child);
+ break;
+ }
+ }
+ }
+ else if (node.Attributes != null)
+ {
+ foreach (XmlAttribute attr in node.Attributes)
+ {
+ this.AppendValue(sb, attr);
+ }
+ }
+ return sb.ToString();
+ }
+ private int filterPriority;
+ public virtual System.ComponentModel.EditorBrowsableState FilterPriority
+ {
+ get
+ {
+ if (this.filterPriority > 0) return (System.ComponentModel.EditorBrowsableState)(this.filterPriority - 1);
+ int prio = 0;
+ XmlNode documentation = this.Documentation;
+ if (documentation != null && documentation.HasChildNodes)
+ {
+ foreach (XmlNode child in documentation.ChildNodes)
+ if (child.Name == "filterpriority")
+ {
+ PlatformHelpers.TryParseInt32(child.InnerText, out prio);
+ switch (prio)
+ {
+ case 2: this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Advanced; break;
+ case 3: this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Never; break;
+ default: this.filterPriority = (int)System.ComponentModel.EditorBrowsableState.Always; break;
+ }
+ this.filterPriority++;
+ return (System.ComponentModel.EditorBrowsableState)(this.filterPriority - 1);
+ }
+ }
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ //^ assert attributes != null;
+ AttributeNode attr = attributes[i];
+ if (attr == null || attr.Type == null) continue;
+ if (attr.Expressions == null || attr.Expressions.Count < 1) continue;
+ if (attr.Type.FullName != "System.ComponentModel.EditorBrowsableAttribute") continue;
+ Literal lit = attr.Expressions[0] as Literal;
+ if (lit == null || !(lit.Value is int)) continue;
+ //^ assert lit.Value != null;
+ prio = (int)lit.Value;
+ return (System.ComponentModel.EditorBrowsableState)((this.filterPriority = prio + 1) - 1);
+ }
+ return (System.ComponentModel.EditorBrowsableState)((this.filterPriority = 1) - 1);
+ }
+ set
+ {
+ this.filterPriority = ((int)value) + 1;
+ }
+ }
+ /// <summary>
+ /// Writes out an element with tag "element", name attribute DocumentationId.ToString() and body Documentation using the provided XmlTextWriter instance.
+ /// </summary>
+ public virtual void WriteDocumentation(XmlTextWriter xwriter)
+ {
+ if (this.documentation == null || xwriter == null) return;
+ xwriter.WriteStartElement("member");
+ if (this.DocumentationId == null) return;
+ xwriter.WriteAttributeString("name", this.DocumentationId.ToString());
+ this.documentation.WriteContentTo(xwriter);
+ xwriter.WriteEndElement();
+ }
+ private readonly static char[]/*!*/ tags = { 'E', 'F', 'M', 'P', 'T' };
+ private void AppendValue(StringBuilder/*!*/ sb, XmlNode/*!*/ node)
+ {
+ string str = node.Value;
+ if (str != null)
+ {
+ str = str.Trim();
+ if (str.Length > 2 && str[1] == ':' && str.LastIndexOfAny(tags, 0, 1) == 0)
+ {
+ char tag = str[0];
+ str = str.Substring(2);
+ if (tag == 'T' && str.IndexOf(TargetPlatform.GenericTypeNamesMangleChar) >= 0)
+ {
+ Module mod = null;
+ if (this.DeclaringType != null)
+ mod = this.DeclaringType.DeclaringModule;
+ else if (this is TypeNode)
+ mod = ((TypeNode)this).DeclaringModule;
+ if (mod != null)
+ {
+ Identifier ns;
+ Identifier tn;
+ int i = str.LastIndexOf('.');
+ if (i < 0 || i >= str.Length)
+ {
+ ns = Identifier.Empty;
+ tn = Identifier.For(str);
+ }
+ else
+ {
+ ns = Identifier.For(str.Substring(0, i));
+ tn = Identifier.For(str.Substring(i + 1));
+ }
+ TypeNode t = mod.GetType(ns, tn, true);
+ if (t != null) str = t.GetFullUnmangledNameWithTypeParameters();
+ }
+ }
+ }
+ if (str == null || str.Length == 0) return;
+ bool lastCharWasSpace = false;
+ if (sb.Length > 0 && !Char.IsPunctuation(str[0]) && !Char.IsWhiteSpace(str[0]))
+ {
+ sb.Append(' ');
+ lastCharWasSpace = true;
+ }
+ foreach (char ch in str)
+ {
+ if (Char.IsWhiteSpace(ch))
+ {
+ if (lastCharWasSpace) continue;
+ lastCharWasSpace = true;
+ sb.Append(' ');
+ }
+ else
+ {
+ lastCharWasSpace = false;
+ sb.Append(ch);
+ }
+ }
+ if (sb.Length > 0 && Char.IsWhiteSpace(sb[sb.Length - 1]))
+ sb.Length -= 1;
+ }
+ }
+#endif
+#if FxCop
+ internal string GetName(MemberFormat options)
+ {
+ StringBuilder name = new StringBuilder();
+ GetName(options, name);
+ return name.ToString();
+ }
+ internal virtual void GetName(MemberFormat options, StringBuilder name)
+ {
+ if (options.Type.TypeName != TypeNameFormat.None && this.DeclaringType != null)
+ {
+ this.DeclaringType.GetName(options, name);
+ name.Append('.');
+ }
+ name.Append(this.Name.Name);
+ }
+#endif
+ }
+#if !MinimalReader
+ public class TypeMemberSnippet : Member
+ {
+ public IParserFactory ParserFactory;
+
+ public TypeMemberSnippet()
+ : base(NodeType.TypeMemberSnippet)
+ {
+ }
+ public TypeMemberSnippet(IParserFactory parserFactory, SourceContext sctx)
+ : base(NodeType.TypeMemberSnippet)
+ {
+ this.ParserFactory = parserFactory;
+ this.SourceContext = sctx;
+ }
+ public override string/*!*/ FullName
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsAssembly
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsFamily
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsPrivate
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsPublic
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsSpecialName
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsStatic
+ {
+ get { throw new InvalidOperationException(); }
+ }
+ public override bool IsVisibleOutsideAssembly
+ {
+ get { throw new InvalidOperationException(); }
+ }
+
+ }
+#endif
+ /// <summary>
+ /// The common base class for all types. This type should not be extended directly.
+ /// Instead extend one of the standard subclasses such as Class, Struct or Interface, since in
+ /// the CLR a type has to be an instance of one the subclasses, and a type which does not extend
+ /// one of these types will have no equivalent in the CLR.
+ /// </summary>
+ public abstract class TypeNode : Member
+ {
+#if ExtendedRuntime
+ /// <summary>The invariants and modelfield contracts associated with this type (for now only classes, interfaces, structs).</summary>
+ public TypeContract Contract;
+#endif
+ private int classSize;
+ /// <summary>Specifies the total size in bytes of instances of types with prescribed layout.</summary>
+ public int ClassSize
+ {
+ get { return this.classSize; }
+ set { this.classSize = value; }
+ }
+ private Module declaringModule;
+ /// <summary>The module or assembly to which the compiled type belongs.</summary>
+ public Module DeclaringModule
+ {
+ get { return this.declaringModule; }
+ set { this.declaringModule = value; }
+ }
+ private TypeFlags flags;
+ public TypeFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ /// <summary>The interfaces implemented by this class or struct, or the extended by this interface.</summary>
+ public virtual InterfaceList Interfaces
+ {
+ get { return this.interfaces == null ? new InterfaceList(0) : this.interfaces; }
+ set { this.interfaces = value; }
+ }
+ protected InterfaceList interfaces;
+#if !MinimalReader
+ public InterfaceList InterfaceExpressions;
+#endif
+ private Identifier @namespace;
+ /// <summary>The namespace to which this type belongs. Null if the type is nested inside another type.</summary>
+ public Identifier Namespace
+ {
+ get { return this.@namespace; }
+ set { this.@namespace = value; }
+ }
+ private int packingSize;
+ /// <summary>Specifies the alignment of fields within types with prescribed layout.</summary>
+ public int PackingSize
+ {
+ get { return this.packingSize; }
+ set { this.packingSize = value; }
+ }
+#if !MinimalReader
+ /// <summary>If this type is the combined result of a number of partial type definitions, this lists the partial definitions.</summary>
+ public TypeNodeList IsDefinedBy;
+#endif
+ /// <summary>
+ /// True if this type is the result of a template instantiation with arguments that are themselves template parameters.
+ /// Used to model template instantiations occurring inside templates.
+ /// </summary>
+ public bool IsNotFullySpecialized;
+ public bool NewTemplateInstanceIsRecursive;
+#if !MinimalReader
+ /// <summary>
+ /// If this type is a partial definition, the value of this is the combined type resulting from all the partial definitions.
+ /// </summary>
+ public TypeNode PartiallyDefines;
+ /// <summary>
+ /// The list of extensions of this type, if it's a non-extension type.
+ /// all extensions implement the IExtendTypeNode interface (in the Sing# code base).
+ /// null = empty list
+ /// </summary>
+ private TypeNodeList extensions = null;
+ /// <summary>
+ /// Whether or not the list of extensions has been examined;
+ /// it's a bug to record a new extension after extensions have been examined.
+ /// </summary>
+ private bool extensionsExamined = false;
+ /// <summary>
+ /// Record another extension of this type.
+ /// </summary>
+ /// <param name="extension"></param>
+ public void RecordExtension(TypeNode extension)
+ {
+ Debug.Assert(!extensionsExamined, "adding an extension after they've already been examined");
+ if (this.extensions == null) this.extensions = new TypeNodeList();
+ this.extensions.Add(extension);
+ }
+ /// <summary>
+ /// The property that should be accessed by clients to get the list of extensions of this type.
+ /// </summary>
+ public TypeNodeList Extensions
+ {
+ get
+ {
+ this.extensionsExamined = true;
+ return this.extensions;
+ }
+ set
+ {
+ Debug.Assert(!extensionsExamined, "setting extensions after they've already been examined");
+ this.extensions = value;
+ }
+ }
+ /// <summary>
+ /// When duplicating a type node, we want to transfer the extensions and the extensionsExamined flag without
+ /// treating this as a "touch" that sets the examined flag. Pretty ugly, though.
+ /// </summary>
+ public TypeNodeList ExtensionsNoTouch
+ {
+ get { return this.extensions; }
+ }
+ /// <summary>
+ /// Copy a (possibly transformed) set of extensions from source to the
+ /// receiver, including whether or not the extensions have been examined.
+ /// </summary>
+ public void DuplicateExtensions(TypeNode source, TypeNodeList newExtensions)
+ {
+ if (source == null) return;
+ this.extensions = newExtensions;
+ this.extensionsExamined = source.extensionsExamined;
+ }
+ /// <summary>
+ /// If the receiver is a type extension, return the extendee, otherwise return the receiver.
+ /// [The identity function, except for dialects (e.g. Extensible Sing#) that allow
+ /// extensions and differing views of types]
+ /// </summary>
+ public virtual TypeNode/*!*/ EffectiveTypeNode
+ {
+ get
+ {
+ return this;
+ }
+ }
+ /// <summary>
+ /// Return whether t1 represents the same type as t2 (or both are null).
+ /// This copes with the cases where t1 and/or t2 may be type views and/or type extensions, as
+ /// in Extensible Sing#.
+ /// </summary>
+ public static bool operator ==(TypeNode t1, TypeNode t2)
+ {
+ return
+ (object)t1 == null ?
+ (object)t2 == null :
+ (object)t2 != null && (object)t1.EffectiveTypeNode == (object)t2.EffectiveTypeNode;
+ }
+ // modify the other operations related to equality
+ public static bool operator !=(TypeNode t1, TypeNode t2)
+ {
+ return !(t1 == t2);
+ }
+ public override bool Equals(Object other)
+ {
+ return this == (other as TypeNode);
+ }
+ public override int GetHashCode()
+ {
+ TypeNode tn = this.EffectiveTypeNode;
+ if ((object)tn == (object)this)
+ {
+ return base.GetHashCode();
+ }
+ else
+ {
+ return tn.GetHashCode();
+ }
+ }
+#endif
+ /// <summary>
+ /// A delegate that is called the first time Members is accessed, if non-null.
+ /// Provides for incremental construction of the type node.
+ /// Must not leave Members null.
+ /// </summary>
+ public TypeMemberProvider ProvideTypeMembers;
+ /// <summary>
+ /// The type of delegates that fill in the Members property of the given type.
+ /// </summary>
+ public delegate void TypeMemberProvider(TypeNode/*!*/ type, object/*!*/ handle);
+ /// <summary>
+ /// A delegate that is called the first time NestedTypes is accessed, if non-null.
+ /// </summary>
+ public NestedTypeProvider ProvideNestedTypes;
+ /// <summary>
+ /// The type of delegates that fill in the NestedTypes property of the given type.
+ /// </summary>
+ public delegate void NestedTypeProvider(TypeNode/*!*/ type, object/*!*/ handle);
+ /// <summary>
+ /// A delegate that is called the first time Attributes is accessed, if non-null.
+ /// Provides for incremental construction of the type node.
+ /// Must not leave Attributes null.
+ /// </summary>
+ public TypeAttributeProvider ProvideTypeAttributes;
+ /// <summary>
+ /// The type of delegates that fill in the Attributes property of the given type.
+ /// </summary>
+ public delegate void TypeAttributeProvider(TypeNode/*!*/ type, object/*!*/ handle);
+ /// <summary>
+ /// Opaque information passed as a parameter to the delegates in ProvideTypeMembers et al.
+ /// Typically used to associate this namespace instance with a helper object.
+ /// </summary>
+ public object ProviderHandle;
+ private TypeNodeList templateInstances;
+ /// <summary>Contains all the types instantiated from this non generic template type.</summary>
+ public TypeNodeList TemplateInstances
+ {
+ get { return this.templateInstances; }
+ set { this.templateInstances = value; }
+ }
+ internal TypeNode(NodeType nodeType)
+ : base(nodeType)
+ {
+#if ExtendedRuntime
+ this.Contract = new TypeContract(this, true);
+#endif
+ }
+ internal TypeNode(NodeType nodeType, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(nodeType)
+ {
+ this.ProvideNestedTypes = provideNestedTypes;
+ this.ProvideTypeAttributes = provideAttributes;
+ this.ProvideTypeMembers = provideMembers;
+ this.ProviderHandle = handle;
+#if !MinimalReader
+ this.isNormalized = true;
+#endif
+#if ExtendedRuntime
+ this.Contract = new TypeContract(this);
+#endif
+ }
+ internal TypeNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
+ Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members, NodeType nodeType)
+ : base(null, attributes, name, nodeType)
+ {
+ this.DeclaringModule = declaringModule;
+ this.DeclaringType = declaringType;
+ this.Flags = flags;
+ this.Interfaces = interfaces;
+ this.members = members;
+ this.Namespace = Namespace;
+#if ExtendedRuntime
+ this.Contract = new TypeContract(this, true);
+#endif
+ }
+ public override AttributeList Attributes
+ {
+ get
+ {
+ if (this.attributes == null)
+ {
+ if (this.ProvideTypeAttributes != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.attributes == null)
+ this.ProvideTypeAttributes(this, this.ProviderHandle);
+ }
+ }
+ else
+ this.attributes = new AttributeList(0);
+ }
+ return this.attributes;
+ }
+ set
+ {
+ this.attributes = value;
+ }
+ }
+ protected SecurityAttributeList securityAttributes;
+ /// <summary>Contains declarative security information associated with the type.</summary>
+ public SecurityAttributeList SecurityAttributes
+ {
+ get
+ {
+ if (this.securityAttributes != null) return this.securityAttributes;
+ if (this.attributes == null)
+ {
+ AttributeList al = this.Attributes; //Getting the type attributes also gets the security attributes, in the case of a type that was read in by the Reader
+ if (al != null) al = null;
+ if (this.securityAttributes != null) return this.securityAttributes;
+ }
+ return this.securityAttributes = new SecurityAttributeList(0);
+ }
+ set
+ {
+ this.securityAttributes = value;
+ }
+ }
+ /// <summary>The type from which this type is derived. Null in the case of interfaces and System.Object.</summary>
+ public virtual TypeNode BaseType
+ {
+ get
+ {
+ switch (this.NodeType)
+ {
+ case NodeType.ArrayType: return CoreSystemTypes.Array;
+ case NodeType.ClassParameter:
+ case NodeType.Class: return ((Class)this).BaseClass;
+ case NodeType.DelegateNode: return CoreSystemTypes.MulticastDelegate;
+ case NodeType.EnumNode: return CoreSystemTypes.Enum;
+ case NodeType.Struct:
+#if !MinimalReader
+ case NodeType.TupleType:
+ case NodeType.TypeAlias:
+ case NodeType.TypeIntersection:
+ case NodeType.TypeUnion:
+#endif
+ return CoreSystemTypes.ValueType;
+ default: return null;
+ }
+ }
+ }
+ protected internal MemberList defaultMembers;
+ /// <summary>A list of any members of this type that have the DefaultMember attribute.</summary>
+ public virtual MemberList DefaultMembers
+ {
+ get
+ {
+ int n = this.Members.Count;
+ if (n != this.memberCount)
+ {
+ this.UpdateMemberTable(n);
+ this.defaultMembers = null;
+ }
+ if (this.defaultMembers == null)
+ {
+ AttributeList attrs = this.Attributes;
+ Identifier defMemName = null;
+ for (int j = 0, m = attrs == null ? 0 : attrs.Count; j < m; j++)
+ {
+ //^ assert attrs != null;
+ AttributeNode attr = attrs[j];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null && mb.BoundMember != null && mb.BoundMember.DeclaringType == SystemTypes.DefaultMemberAttribute)
+ {
+ if (attr.Expressions != null && attr.Expressions.Count > 0)
+ {
+ Literal lit = attr.Expressions[0] as Literal;
+ if (lit != null && lit.Value is string)
+ defMemName = Identifier.For((string)lit.Value);
+ }
+ break;
+ }
+ Literal litc = attr.Constructor as Literal;
+ if (litc != null && (litc.Value as TypeNode) == SystemTypes.DefaultMemberAttribute)
+ {
+ if (attr.Expressions != null && attr.Expressions.Count > 0)
+ {
+ Literal lit = attr.Expressions[0] as Literal;
+ if (lit != null && lit.Value is string)
+ defMemName = Identifier.For((string)lit.Value);
+ }
+ break;
+ }
+ }
+ if (defMemName != null)
+ this.defaultMembers = this.GetMembersNamed(defMemName);
+ else
+ this.defaultMembers = new MemberList(0);
+ }
+ return this.defaultMembers;
+ }
+ set
+ {
+ this.defaultMembers = value;
+ }
+ }
+ protected string fullName;
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.fullName != null) return this.fullName;
+ if (this.DeclaringType != null)
+ return this.fullName = this.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.fullName = this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Name != null)
+ return this.fullName = this.Name.ToString();
+ else
+ return this.fullName = "";
+ }
+ }
+#if !MinimalReader
+ // the same as FullName, except for dialects like Sing# with type extensions where names of
+ // type extensions may get mangled; in that case, this reports the name of the effective type node.
+ public virtual string FullNameDuringParsing
+ {
+ get { return this.FullName; }
+ }
+#endif
+ public virtual string GetFullUnmangledNameWithoutTypeParameters()
+ {
+ if (this.DeclaringType != null)
+ return this.DeclaringType.GetFullUnmangledNameWithoutTypeParameters() + "+" + this.GetUnmangledNameWithoutTypeParameters();
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.Namespace.ToString() + "." + this.GetUnmangledNameWithoutTypeParameters();
+ else
+ return this.GetUnmangledNameWithoutTypeParameters();
+ }
+ public virtual string GetFullUnmangledNameWithTypeParameters()
+ {
+ if (this.DeclaringType != null)
+ return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "+" + this.GetUnmangledNameWithTypeParameters(true);
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.Namespace.ToString() + "." + this.GetUnmangledNameWithTypeParameters(true);
+ else
+ return this.GetUnmangledNameWithTypeParameters(true);
+ }
+ public virtual string GetUnmangledNameWithTypeParameters()
+ {
+ return this.GetUnmangledNameWithTypeParameters(false);
+ }
+ private string GetUnmangledNameWithTypeParameters(bool fullNamesForTypeParameters)
+ {
+ StringBuilder sb = new StringBuilder(this.GetUnmangledNameWithoutTypeParameters());
+ TypeNodeList templateParameters = this.TemplateParameters;
+ if (this.Template != null) templateParameters = this.TemplateArguments;
+ for (int i = 0, n = templateParameters == null ? 0 : templateParameters.Count; i < n; i++)
+ {
+ //^ assert templateParameters != null;
+ TypeNode tpar = templateParameters[i];
+ if (tpar == null) continue;
+ if (i == 0)
+ sb.Append('<');
+ else
+ sb.Append(',');
+ if (tpar.Name != null)
+ if (fullNamesForTypeParameters)
+ sb.Append(tpar.GetFullUnmangledNameWithTypeParameters());
+ else
+ sb.Append(tpar.GetUnmangledNameWithTypeParameters());
+ if (i == n - 1)
+ sb.Append('>');
+ }
+ return sb.ToString();
+ }
+ protected static readonly char[]/*!*/ MangleChars = new char[] { '!', '>' };
+ public virtual string/*!*/ GetUnmangledNameWithoutTypeParameters()
+ {
+ TypeNode.MangleChars[0] = TargetPlatform.GenericTypeNamesMangleChar;
+ if (this.Template != null) return this.Template.GetUnmangledNameWithoutTypeParameters();
+ if (this.Name == null) return "";
+ string name = this.Name.ToString();
+ if (this.TemplateParameters != null && this.TemplateParameters.Count > 0)
+ {
+ int lastMangle = name.LastIndexOfAny(TypeNode.MangleChars);
+ if (lastMangle >= 0)
+ {
+ if (name[lastMangle] == '>') lastMangle++;
+ return name.Substring(0, lastMangle);
+ }
+ }
+ return name;
+ }
+
+#if !MinimalReader
+ public virtual string GetSerializedTypeName()
+ {
+ bool isAssemblyQualified = true;
+ return this.GetSerializedTypeName(this, ref isAssemblyQualified);
+ }
+ string GetSerializedTypeName(TypeNode/*!*/ type, ref bool isAssemblyQualified)
+ {
+ if (type == null) return null;
+ StringBuilder sb = new StringBuilder();
+ TypeModifier tMod = type as TypeModifier;
+ if (tMod != null)
+ type = tMod.ModifiedType;
+ ArrayType arrType = type as ArrayType;
+ if (arrType != null)
+ {
+ type = arrType.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, arrType.ElementType, ref isAssemQual);
+ if (arrType.IsSzArray())
+ sb.Append("[]");
+ else
+ {
+ sb.Append('[');
+ if (arrType.Rank == 1) sb.Append('*');
+ for (int i = 1; i < arrType.Rank; i++) sb.Append(',');
+ sb.Append(']');
+ }
+ goto done;
+ }
+ Pointer pointer = type as Pointer;
+ if (pointer != null)
+ {
+ type = pointer.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, pointer.ElementType, ref isAssemQual);
+ sb.Append('*');
+ goto done;
+ }
+ Reference reference = type as Reference;
+ if (reference != null)
+ {
+ type = reference.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, reference.ElementType, ref isAssemQual);
+ sb.Append('&');
+ goto done;
+ }
+ if (type.Template == null)
+ sb.Append(type.FullName);
+ else
+ {
+ sb.Append(type.Template.FullName);
+ sb.Append('[');
+ for (int i = 0, n = type.TemplateArguments == null ? 0 : type.TemplateArguments.Count; i < n; i++)
+ {
+ //^ assert type.TemplateArguments != null;
+ bool isAssemQual = true;
+ this.AppendSerializedTypeName(sb, type.TemplateArguments[i], ref isAssemQual);
+ if (i < n - 1) sb.Append(',');
+ }
+ sb.Append(']');
+ }
+ done:
+ if (isAssemblyQualified)
+ this.AppendAssemblyQualifierIfNecessary(sb, type, out isAssemblyQualified);
+ return sb.ToString();
+ }
+ void AppendAssemblyQualifierIfNecessary(StringBuilder/*!*/ sb, TypeNode type, out bool isAssemQualified)
+ {
+ isAssemQualified = false;
+ if (type == null) return;
+ AssemblyNode referencedAssembly = type.DeclaringModule as AssemblyNode;
+ if (referencedAssembly != null)
+ {
+ sb.Append(", ");
+ sb.Append(referencedAssembly.StrongName);
+ isAssemQualified = true;
+ }
+ }
+ void AppendSerializedTypeName(StringBuilder/*!*/ sb, TypeNode type, ref bool isAssemQualified)
+ {
+ if (type == null) return;
+ string argTypeName = this.GetSerializedTypeName(type, ref isAssemQualified);
+ if (isAssemQualified) sb.Append('[');
+ sb.Append(argTypeName);
+ if (isAssemQualified) sb.Append(']');
+ }
+#endif
+
+ /// <summary>
+ /// Return the name the constructor should have in this type node. By default, it's
+ /// the same as the name of the enclosing type node, but it can be different in e.g.
+ /// extensions in Extensible Sing#
+ /// </summary>
+ public virtual Identifier ConstructorName
+ {
+ get
+ {
+ if (this.constructorName == null)
+ {
+ Identifier id = this.Name;
+ if (this.IsNormalized && this.IsGeneric)
+ id = Identifier.For(this.GetUnmangledNameWithoutTypeParameters());
+ this.constructorName = id;
+ }
+ return this.constructorName;
+ }
+ }
+ private Identifier constructorName;
+
+
+ /// <summary>True if the type is an abstract class or an interface.</summary>
+ public virtual bool IsAbstract
+ {
+ get
+ {
+ return (this.Flags & TypeFlags.Abstract) != 0;
+ }
+ }
+ public override bool IsAssembly
+ {
+ get
+ {
+ TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
+ return visibility == TypeFlags.NotPublic || visibility == TypeFlags.NestedAssembly;
+ }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { return false; }
+ }
+ public override bool IsFamily
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamily; }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamANDAssem; }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamORAssem; }
+ }
+ protected bool isGeneric;
+ /// <summary>True if this type is a template conforming to the rules of a generic type in the CLR.</summary>
+ public virtual bool IsGeneric
+ {
+ get
+ {
+ return this.isGeneric;
+ }
+ set
+ {
+ this.isGeneric = value;
+ }
+ }
+#if ExtendedRuntime
+ public static bool IsImmutable(TypeNode type) {
+ type = TypeNode.StripModifiers(type);
+ if (type == null) return false;
+ if (type.TypeCode != TypeCode.Object) return true;
+ if (type.GetAttribute(SystemTypes.ImmutableAttribute) != null) return true;
+ if (type.IsValueType && type.DeclaringModule == CoreSystemTypes.SystemAssembly) return true; //hack.
+ return false;
+ }
+#endif
+ public virtual bool IsNestedAssembly
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedAssembly; }
+ }
+ public virtual bool IsNestedFamily
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamily; }
+ }
+ public virtual bool IsNestedFamilyAndAssembly
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamANDAssem; }
+ }
+ public virtual bool IsNestedInternal
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedFamORAssem; }
+ }
+ public virtual bool IsNestedIn(TypeNode type)
+ {
+ for (TypeNode decType = this.DeclaringType; decType != null; decType = decType.DeclaringType)
+ {
+ if (decType == type) return true;
+ }
+ return false;
+ }
+ public virtual bool IsNestedPublic
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedPublic; }
+ }
+ public virtual bool IsNonPublic
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NotPublic; }
+ }
+#if !MinimalReader
+ protected bool isNormalized;
+ /// <summary>
+ /// True if the type node is in "normal" form. A node is in "normal" form if it is effectively a node in an AST formed directly
+ /// from CLR module or assembly. Such a node can be written out as compiled code to an assembly or module without further processing.
+ /// </summary>
+ public virtual bool IsNormalized
+ {
+ get
+ {
+ if (this.isNormalized) return true;
+ if (this.DeclaringModule == null) return false;
+ return this.isNormalized = this.DeclaringModule.IsNormalized;
+ }
+ set
+ {
+ this.isNormalized = value;
+ }
+ }
+#endif
+ public override bool IsPrivate
+ {
+ get { return (this.Flags & TypeFlags.VisibilityMask) == TypeFlags.NestedPrivate; }
+ }
+ /// <summary>True if values of this type can be compared directly in CLR IL instructions.</summary>
+ public virtual bool IsPrimitiveComparable
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.Boolean:
+ case ElementType.Char:
+ case ElementType.Int8:
+ case ElementType.Int16:
+ case ElementType.Int32:
+ case ElementType.Int64:
+ case ElementType.IntPtr:
+ case ElementType.UInt8:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UIntPtr:
+ case ElementType.Single:
+ case ElementType.Double:
+ return true;
+ default:
+ return !(this is Struct) || this is EnumNode || this is Pointer;
+ }
+ }
+ }
+ /// <summary>True if values of this type are integers that can be processed by CLR IL instructions.</summary>
+ public virtual bool IsPrimitiveInteger
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.Int8:
+ case ElementType.Int16:
+ case ElementType.Int32:
+ case ElementType.Int64:
+ case ElementType.IntPtr:
+ case ElementType.UInt8:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UIntPtr:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ /// <summary>True if values of this type are integers or floating point numbers that can be processed by CLR IL instructions.</summary>
+ public virtual bool IsPrimitiveNumeric
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.Int8:
+ case ElementType.Int16:
+ case ElementType.Int32:
+ case ElementType.Int64:
+ case ElementType.IntPtr:
+ case ElementType.UInt8:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UIntPtr:
+ case ElementType.Single:
+ case ElementType.Double:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ /// <summary>True if values of this type are unsigned integers that can be processed by CLR IL instructions.</summary>
+ public virtual bool IsPrimitiveUnsignedInteger
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.UInt8:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UIntPtr:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ public override bool IsPublic
+ {
+ get
+ {
+ TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
+ return visibility == TypeFlags.Public || visibility == TypeFlags.NestedPublic;
+ }
+ }
+ /// <summary>True if values of this type can be processed by CLR IL instructions.</summary>
+ public virtual bool IsPrimitive
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.Boolean:
+ case ElementType.Char:
+ case ElementType.Double:
+ case ElementType.Int16:
+ case ElementType.Int32:
+ case ElementType.Int64:
+ case ElementType.Int8:
+ case ElementType.IntPtr:
+ case ElementType.Single:
+ case ElementType.String:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UInt8:
+ case ElementType.UIntPtr:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ /// <summary>True if the type cannot be derived from.</summary>
+ public virtual bool IsSealed
+ {
+ get
+ {
+ return (this.Flags & TypeFlags.Sealed) != 0;
+ }
+ }
+ public override bool IsSpecialName
+ {
+ get { return (this.Flags & TypeFlags.SpecialName) != 0; }
+ }
+ public override bool IsStatic
+ {
+ get { return true; }
+ }
+ /// <summary>True if the identity of the type depends on its structure rather than its name.
+ /// Arrays, pointers and generic type instances are examples of such types.</summary>
+ public virtual bool IsStructural
+ {
+ get
+ {
+ return this.Template != null;
+ }
+ }
+ /// <summary>True if the type serves as a parameter to a type template.</summary>
+ public virtual bool IsTemplateParameter
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ /// <summary>True if the type is a value type containing only fields of unmanaged types.</summary>
+ public virtual bool IsUnmanaged
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ /// <summary>A list of the types that contribute to the structure of a structural type.</summary>
+ public virtual TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.TemplateArguments;
+ if (result != null && result.Count > 0) return result;
+ return this.TemplateParameters;
+ }
+ }
+ /// <summary>True if values of this type are unsigned integers that can be processed by CLR IL instructions.</summary>
+ public virtual bool IsUnsignedPrimitiveNumeric
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.UInt8:
+ case ElementType.UInt16:
+ case ElementType.UInt32:
+ case ElementType.UInt64:
+ case ElementType.UIntPtr:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ /// <summary>True if instances of this type have no identity other than their value and are copied upon assignment.</summary>
+ public virtual bool IsValueType
+ {
+ get
+ {
+ switch (this.NodeType)
+ {
+ case NodeType.EnumNode:
+#if !MinimalReader
+ case NodeType.ConstrainedType:
+ case NodeType.TupleType:
+ case NodeType.TypeAlias:
+ case NodeType.TypeIntersection:
+ case NodeType.TypeUnion: return true;
+#endif
+ case NodeType.Struct: return true;
+ default: return false;
+ }
+ }
+ }
+#if ExtendedRuntime
+ /// <summary>
+ /// Returns true if the type is definitely a reference type.
+ /// </summary>
+ public virtual bool IsReferenceType {
+ get {
+ switch (this.NodeType) {
+ case NodeType.Class:
+ case NodeType.Interface:
+ case NodeType.Pointer:
+ case NodeType.ArrayType:
+ case NodeType.DelegateNode:
+ return this != SystemTypes.ValueType && this != SystemTypes.Enum;
+ default:
+ return false;
+ }
+ }
+ }
+#endif
+ /// <summary>
+ /// True if underlying type (modulo type modifiers) is a pointer type (Pointer)
+ /// </summary>
+ public virtual bool IsPointerType
+ {
+ get { return false; }
+ }
+ public override bool IsVisibleOutsideAssembly
+ {
+ get
+ {
+ if (this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly) return false;
+ switch (this.Flags & TypeFlags.VisibilityMask)
+ {
+ case TypeFlags.Public:
+ case TypeFlags.NestedPublic:
+ return true;
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedFamORAssem:
+ return this.DeclaringType != null && !this.DeclaringType.IsSealed;
+ default:
+ return false;
+ }
+ }
+ }
+ // This field stores those members declared syntactically within
+ // this type node. (Under Extended Sing#, additional members can
+ // be logically part of a type node but declared in a separate
+ // syntactic type node.)
+ protected internal MemberList members;
+ protected volatile internal bool membersBeingPopulated;
+ /// <summary>
+ /// The list of members contained inside this type, by default ignoring any extensions of this type.
+ /// (Subclasses in the Extensible Sing# dialect override this to include members of visible extensions.)
+ /// If the value of members is null and the value of ProvideTypeMembers is not null, the
+ /// TypeMemberProvider delegate is called to fill in the value of this property.
+ /// </summary>
+ public virtual MemberList Members
+ {
+ get
+ {
+ if (this.members == null || this.membersBeingPopulated)
+ if (this.ProvideTypeMembers != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.members == null)
+ {
+ this.membersBeingPopulated = true;
+ this.ProvideTypeMembers(this, this.ProviderHandle);
+ this.membersBeingPopulated = false;
+#if ExtendedRuntime
+ this.ApplyOutOfBandContracts();
+#endif
+ }
+ }
+ }
+ else
+ this.members = new MemberList();
+ return this.members;
+ }
+ set
+ {
+ this.members = value;
+ this.memberCount = 0;
+ this.memberTable = null;
+ this.constructors = null;
+ this.defaultMembers = null;
+#if !MinimalReader
+ this.explicitCoercionFromTable = null;
+ this.explicitCoercionMethods = null;
+ this.explicitCoercionToTable = null;
+ this.implicitCoercionFromTable = null;
+ this.implicitCoercionMethods = null;
+ this.implicitCoercionToTable = null;
+ this.opFalse = null;
+ this.opTrue = null;
+#endif
+ }
+ }
+#if ExtendedRuntime
+ protected internal virtual void ApplyOutOfBandContracts(){
+ if (this.members == null) return;
+ AssemblyNode declaringAssembly = this.DeclaringModule as AssemblyNode;
+ if (declaringAssembly == null || declaringAssembly.ContractAssembly == null) return;
+ TypeNode contractType = declaringAssembly.ContractAssembly.GetType(this.Namespace, this.Name);
+ if (contractType == null) return;
+
+ // Copy the type-level contract attributes over to the shadowed type, namely "this".
+ int contractsNamespaceKey = SystemTypes.NonNullType.Namespace.UniqueIdKey;
+ foreach (AttributeNode attr in contractType.Attributes) {
+ if (attr.Type.Namespace != null && attr.Type.Namespace.UniqueIdKey == contractsNamespaceKey)
+ this.Attributes.Add(attr);
+ }
+
+ if (this.BaseType != null) { MemberList junk = this.BaseType.Members; if (junk != null) junk = null; }
+ Hashtable contractByFullName = new Hashtable();
+ MemberList contractMembers = contractType.Members;
+ for (int i = 0, n = contractMembers == null ? 0 : contractMembers.Count; i < n; i++){
+ //^ assert contractMembers != null;
+ Field f = contractMembers[i] as Field;
+ if (f != null) {
+ contractByFullName[f.FullName] = f;
+ continue;
+ }
+ Method m = contractMembers[i] as Method;
+ if (m == null ) continue;
+ string methName = this.FullStrippedName(m);
+ contractByFullName[methName] = m;
+ }
+ for (int i = 0, n = members.Count; i < n; i++){
+ Field codeField = members[i] as Field;
+ if (codeField != null) {
+ Field contractField = contractByFullName[codeField.FullName] as Field;
+ if (contractField != null && contractField.Type != null && contractField.Type != codeField.Type) {
+ OptionalModifier optFieldType = contractField.Type as OptionalModifier;
+ if (optFieldType != null && codeField.Type != null) {
+ codeField.Type = OptionalModifier.For(optFieldType.Modifier, codeField.Type);
+ codeField.HasOutOfBandContract = true;
+ }
+ }
+ continue;
+ }
+ Method codeMethod = members[i] as Method;
+ if (codeMethod == null) continue;
+ // we include the return type since some conversion operators result
+ // in overloaded methods whose signatures differ only in return type
+ string methName = this.FullStrippedName(codeMethod);
+ Method contractMethod = contractByFullName[methName] as Method;
+ if (contractMethod != null) {
+ this.CopyContractToMethod(contractMethod, codeMethod);
+ if (codeMethod.OverridesBaseClassMember) {
+ Method overridden = this.FindNearestOverriddenMethod(contractMethod);
+ if (overridden != null)
+ this.CopyContractToMethod(overridden, codeMethod);
+ }
+ } else {
+ // Maybe there isn't a shadow method declared in contractType, but
+ // there still might be out-of-band contracts on an interface method
+ // that the codeMethod implements.
+ if (codeMethod.ImplementedInterfaceMethods != null && codeMethod.ImplementedInterfaceMethods.Count > 0) {
+ foreach (Method m in codeMethod.ImplementedInterfaceMethods) {
+ this.CopyContractToMethod(m, codeMethod);
+ }
+ } else if (codeMethod.ImplicitlyImplementedInterfaceMethods != null) {
+ foreach (Method m in codeMethod.ImplicitlyImplementedInterfaceMethods) {
+ this.CopyContractToMethod(m, codeMethod);
+ }
+ }
+ }
+ }
+ }
+ protected virtual string/*!*/ FullStrippedName(Method/*!*/ m) {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(m.DeclaringType.GetFullUnmangledNameWithTypeParameters());
+ sb.Append('.');
+ if (m.NodeType == NodeType.InstanceInitializer)
+ sb.Append("#ctor");
+ else if (m.Name != null)
+ sb.Append(m.Name.ToString());
+ ParameterList parameters = m.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++){
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ TypeNode parType = TypeNode.DeepStripModifiers(par.Type);
+ Reference rt = parType as Reference;
+ if (rt != null && rt.ElementType != null)
+ parType = TypeNode.DeepStripModifiers(rt.ElementType).GetReferenceType();
+ //^ assert parType != null;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ sb.Append(parType.GetFullUnmangledNameWithTypeParameters());
+ if (i == n-1)
+ sb.Append(')');
+ }
+ if (m.ReturnType != null){
+ TypeNode retType = TypeNode.DeepStripModifiers(m.ReturnType);
+ //^ assert retType != null;
+ sb.Append(retType.GetFullUnmangledNameWithTypeParameters());
+ }
+ return sb.ToString();
+ }
+ protected virtual void CopyContractToMethod(Method/*!*/ contractMethod, Method/*!*/ codeMethod) {
+ codeMethod.HasOutOfBandContract = true;
+ if (codeMethod.Contract == null)
+ codeMethod.Contract = new MethodContract(codeMethod);
+ // setting them to null forces deserialization upon next access to the property
+ // NB: This means that out-of-band contracts can be applied *only* to code that
+ // does *not* have any contracts since this will wipe them out!!
+ codeMethod.Contract.Ensures = null;
+ codeMethod.Contract.Modifies = null;
+ codeMethod.Contract.Requires = null;
+
+ int contractsNamespaceKey = SystemTypes.NonNullType.Namespace.UniqueIdKey;
+ // Copy the method-level contract attributes over to the shadowed method.
+ for (int a = 0; a < contractMethod.Attributes.Count; a++){
+ AttributeNode attr = contractMethod.Attributes[a];
+ if (attr.Type.Namespace != null && attr.Type.Namespace.UniqueIdKey == contractsNamespaceKey)
+ codeMethod.Attributes.Add(attr);
+ }
+
+ // Copy the parameter-level contract attributes and type over to the shadowed method's parameters.
+ ParameterList contractParameters = contractMethod.Parameters;
+ ParameterList codeParameters = codeMethod.Parameters;
+ if (contractParameters != null && codeParameters != null && contractParameters.Count <= codeParameters.Count) {
+ for (int i = 0, n = contractParameters.Count; i < n; i++) {
+ Parameter contractParameter = contractParameters[i];
+ Parameter codeParameter = codeParameters[i];
+ if (contractParameter == null || codeParameter == null) continue;
+ for (int a = 0, m = contractParameter.Attributes == null ? 0 : contractParameter.Attributes.Count; a < m; a++){
+ //^ assert contractParameter.Attributes != null;
+ AttributeNode attr = contractParameter.Attributes[a];
+ if (attr == null || attr.Type == null) continue;
+ if (attr.Type.Namespace != null && attr.Type.Namespace.UniqueIdKey == contractsNamespaceKey){
+ if (codeParameter.Attributes == null) codeParameter.Attributes = new AttributeList();
+ codeParameter.Attributes.Add(attr);
+ }
+ }
+ if (contractParameter.Type != codeParameter.Type)
+ codeParameter.Type = this.CopyModifier(contractParameter.Type, codeParameter.Type);
+ }
+ }
+ if (contractMethod.ReturnType != codeMethod.ReturnType)
+ codeMethod.ReturnType = this.CopyModifier(contractMethod.ReturnType, codeMethod.ReturnType);
+ codeMethod.fullName = null;
+ }
+ private TypeNode CopyModifier(TypeNode contractType, TypeNode codeType) {
+ if (contractType == null) return codeType;
+ Reference rcType = contractType as Reference;
+ if (rcType != null) {
+ contractType = rcType.ElementType;
+ if (contractType == null) return codeType;
+ Reference rcodeType = codeType as Reference;
+ if (rcodeType == null || rcodeType.ElementType == null) return codeType;
+ TypeNode t = CopyModifier(contractType, rcodeType.ElementType);
+ return t.GetReferenceType();
+ }
+ ArrayType acType = contractType as ArrayType;
+ if (acType != null) {
+ contractType = acType.ElementType;
+ if (contractType == null) return codeType;
+ ArrayType acodeType = codeType as ArrayType;
+ if (acodeType == null || acodeType.ElementType == null) return codeType;
+ TypeNode t = CopyModifier(contractType, acodeType.ElementType);
+ return t.GetArrayType(1);
+ }
+ OptionalModifier optModType = contractType as OptionalModifier;
+ if (optModType != null && optModType.Modifier != null) {
+ TypeNode t = CopyModifier(optModType.ModifiedType, codeType);
+ codeType = OptionalModifier.For(optModType.Modifier, t);
+ }
+ if (contractType.Template != null && codeType.Template != null && contractType.TemplateArguments != null && codeType.TemplateArguments != null) {
+ TypeNodeList args = contractType.TemplateArguments.Clone();
+ TypeNodeList codeArgs = codeType.TemplateArguments;
+ for (int i = 0, n = args.Count, m = codeArgs.Count; i < n && i < m; i++) {
+ TypeNode argType = args[i];
+ TypeNode codeArgType = codeArgs[i];
+ if (argType != codeArgType)
+ args[i] = this.CopyModifier(argType, codeArgType);
+ }
+ return codeType.Template.GetTemplateInstance(codeType, args);
+ }
+ return codeType;
+ }
+ public virtual Method FindNearestOverriddenMethod (Method method){
+ if (method == null) return null;
+ int numParams = method.Parameters == null ? 0 : method.Parameters.Count;
+ TypeNode[] paramTypes = new TypeNode[numParams];
+ for (int i=0; i<numParams; i++) paramTypes[i] = method.Parameters[i].Type;
+ for (TypeNode scan = method.DeclaringType.BaseType; scan != null; scan = scan.BaseType){
+ Method overridden = scan.GetMethod(method.Name, paramTypes);
+ if (overridden != null) return overridden;
+ }
+ return null;
+ }
+#endif
+ protected TypeNode template;
+ /// <summary>The (generic) type template from which this type was instantiated. Null if this is not a (generic) type template instance.</summary>
+ public virtual TypeNode Template
+ {
+ get
+ {
+ TypeNode result = this.template;
+ if (result == null)
+ {
+ if (this.isGeneric || TargetPlatform.GenericTypeNamesMangleChar != '_') return null;
+ AttributeList attributes = this.Attributes;
+ lock (this)
+ {
+ if (this.template != null)
+ {
+ if (this.template == TypeNode.NotSpecified)
+ return null;
+ return this.template;
+ }
+#if ExtendedRuntime
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++) {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null || mb.BoundMember == null || mb.BoundMember.DeclaringType != SystemTypes.TemplateInstanceAttribute) continue;
+ ExpressionList exprs = attr.Expressions;
+ if (exprs == null || exprs.Count != 2) continue;
+ Literal lit = exprs[0] as Literal;
+ if (lit == null) continue;
+ TypeNode templ = lit.Value as TypeNode;
+ if (templ != null) {
+ lit = exprs[1] as Literal;
+ if (lit == null) continue;
+ object[] types = lit.Value as object[];
+ if (types == null) continue;
+ int m = types == null ? 0 : types.Length;
+ TypeNodeList templateArguments = new TypeNodeList(m);
+ for (int j = 0; j < m; j++) {
+ TypeNode t = types[j] as TypeNode;
+ if (t == null) continue;
+ templateArguments.Add(t);
+ }
+ this.TemplateArguments = templateArguments;
+ return this.template = templ;
+ }
+ }
+#endif
+ if (result == null)
+ this.template = TypeNode.NotSpecified;
+ }
+ }
+ else if (result == TypeNode.NotSpecified)
+ return null;
+ return result;
+ }
+ set
+ {
+ this.template = value;
+ }
+ }
+#if !MinimalReader
+ public TypeNode TemplateExpression;
+#endif
+ protected TypeNodeList templateArguments;
+ /// <summary>The arguments used when this (generic) type template instance was instantiated.</summary>
+ public virtual TypeNodeList TemplateArguments
+ {
+ get
+ {
+ if (this.template == null)
+ {
+ TypeNode templ = this.Template; //Will fill in the arguments
+ if (templ != null) templ = null;
+ }
+ return this.templateArguments;
+ }
+ set
+ {
+ this.templateArguments = value;
+ }
+ }
+#if !MinimalReader
+ public TypeNodeList TemplateArgumentExpressions;
+#endif
+ internal TypeNodeList consolidatedTemplateArguments;
+ public virtual TypeNodeList ConsolidatedTemplateArguments
+ {
+ get
+ {
+ if (this.consolidatedTemplateArguments == null)
+ this.consolidatedTemplateArguments = this.GetConsolidatedTemplateArguments();
+ return this.consolidatedTemplateArguments;
+ }
+ set
+ {
+ this.consolidatedTemplateArguments = value;
+ }
+ }
+ private void AddTemplateParametersFromAttributeEncoding(TypeNodeList result)
+ {
+#if ExtendedRuntime
+ if (result.Count == 0) {
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++) {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null || mb.BoundMember == null || mb.BoundMember.DeclaringType != SystemTypes.TemplateAttribute) continue;
+ ExpressionList exprs = attr.Expressions;
+ if (exprs == null || exprs.Count != 1) continue;
+ Literal lit = exprs[0] as Literal;
+ if (lit == null) continue;
+ object[] types = lit.Value as object[];
+ if (types == null) continue;
+ for (int j = 0, m = types == null ? 0 : types.Length; j < m; j++) {
+ TypeNode t = types[j] as TypeNode;
+ if (t == null) continue;
+ if (t.NodeType == NodeType.TypeParameter || t.NodeType == NodeType.ClassParameter)
+ result.Add(t);
+ }
+ attributes[i] = null;
+ }
+ }
+#endif
+ }
+ internal TypeNodeList templateParameters;
+ /// <summary>The type parameters of this type. Null if this type is not a (generic) type template.</summary>
+ public virtual TypeNodeList TemplateParameters
+ {
+ get
+ {
+ TypeNodeList result = this.templateParameters;
+ if (result == null)
+ {
+ if (this.isGeneric || TargetPlatform.GenericTypeNamesMangleChar != '_') return null; //Can happen when this is nested in a generic type
+ TypeNodeList nestedTypes = this.NestedTypes;
+ lock (this)
+ {
+ if ((result = this.templateParameters) != null) return result.Count == 0 ? null : result;
+ result = new TypeNodeList();
+ for (int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++)
+ {
+ TypeNode nt = nestedTypes[i];
+ if (nt == null) continue;
+ if (nt is MethodTypeParameter) continue;
+ if (nt.NodeType == NodeType.TypeParameter || nt.NodeType == NodeType.ClassParameter)
+ result.Add(nt);
+ }
+ this.AddTemplateParametersFromAttributeEncoding(result);
+ this.TemplateParameters = result;
+ }
+ }
+ if (result.Count == 0) return null;
+ return result;
+ }
+ set
+ {
+ if (value == null)
+ {
+ if (this.templateParameters == null) return;
+ if (this.templateParameters.Count > 0)
+ value = new TypeNodeList(0);
+ }
+ this.templateParameters = value;
+ }
+ }
+ protected internal TypeNodeList consolidatedTemplateParameters;
+ public virtual TypeNodeList ConsolidatedTemplateParameters
+ {
+ get
+ {
+ if (this.consolidatedTemplateParameters == null)
+ this.consolidatedTemplateParameters = this.GetConsolidatedTemplateParameters();
+ return this.consolidatedTemplateParameters;
+ }
+ set
+ {
+ this.consolidatedTemplateParameters = value;
+ }
+ }
+ internal ElementType typeCode = ElementType.Class;
+ /// <summary>The System.TypeCode value that Convert.GetTypeCode will return pass an instance of this type as parameter.</summary>
+ public virtual System.TypeCode TypeCode
+ {
+ get
+ {
+ switch (this.typeCode)
+ {
+ case ElementType.Boolean: return System.TypeCode.Boolean;
+ case ElementType.Char: return System.TypeCode.Char;
+ case ElementType.Double: return System.TypeCode.Double;
+ case ElementType.Int16: return System.TypeCode.Int16;
+ case ElementType.Int32: return System.TypeCode.Int32;
+ case ElementType.Int64: return System.TypeCode.Int64;
+ case ElementType.Int8: return System.TypeCode.SByte;
+ case ElementType.Single: return System.TypeCode.Single;
+ case ElementType.UInt16: return System.TypeCode.UInt16;
+ case ElementType.UInt32: return System.TypeCode.UInt32;
+ case ElementType.UInt64: return System.TypeCode.UInt64;
+ case ElementType.UInt8: return System.TypeCode.Byte;
+ case ElementType.Void: return System.TypeCode.Empty;
+ default:
+ if (this == CoreSystemTypes.String) return System.TypeCode.String;
+#if !MinimalReader
+ if (this == CoreSystemTypes.Decimal) return System.TypeCode.Decimal;
+ if (this == CoreSystemTypes.DateTime) return System.TypeCode.DateTime;
+ if (this == CoreSystemTypes.DBNull) return System.TypeCode.DBNull;
+#endif
+ return System.TypeCode.Object;
+ }
+ }
+ }
+ private readonly static TypeNode NotSpecified = new Class();
+#if !FxCop
+ protected
+#endif
+ internal TrivialHashtableUsingWeakReferences structurallyEquivalentMethod;
+#if !MinimalReader
+ /// <summary>
+ /// Returns the methods of an abstract type that have been left unimplemented. Includes methods inherited from
+ /// base classes and interfaces, and methods from any (known) extensions.
+ /// </summary>
+ /// <param name="result">A method list to which the abstract methods must be appended.</param>
+ public virtual void GetAbstractMethods(MethodList/*!*/ result)
+ {
+ if (!this.IsAbstract) return;
+ //For each interface, get abstract methods and keep those that are not implemented by this class or a base class
+ InterfaceList interfaces = this.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ MemberList imembers = iface.Members;
+ for (int j = 0, m = imembers == null ? 0 : imembers.Count; j < m; j++)
+ {
+ Method meth = imembers[j] as Method;
+ if (meth == null) continue;
+ if (this.ImplementsExplicitly(meth)) continue;
+ if (this.ImplementsMethod(meth, true)) continue;
+ result.Add(meth);
+ }
+ }
+ }
+#endif
+ protected internal TrivialHashtable szArrayTypes;
+ /// <summary>
+ /// Returns a type representing an array whose elements are of this type. Will always return the same instance for the same rank.
+ /// </summary>
+ /// <param name="rank">The number of dimensions of the array.</param>
+ public virtual ArrayType/*!*/ GetArrayType(int rank)
+ {
+ return this.GetArrayType(rank, false);
+ }
+ public virtual ArrayType/*!*/ GetArrayType(int rank, bool lowerBoundIsUnknown)
+ {
+ if (rank > 1 || lowerBoundIsUnknown) return this.GetArrayType(rank, 0, 0, new int[0], new int[0]);
+ if (this.szArrayTypes == null) this.szArrayTypes = new TrivialHashtable();
+ ArrayType result = (ArrayType)this.szArrayTypes[rank];
+ if (result != null) return result;
+ lock (this)
+ {
+ result = (ArrayType)this.szArrayTypes[rank];
+ if (result != null) return result;
+ this.szArrayTypes[rank] = result = new ArrayType(this, 1);
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= this.Flags & TypeFlags.VisibilityMask;
+ return result;
+ }
+ }
+ protected internal TrivialHashtable arrayTypes;
+ /// <summary>
+ /// Returns a type representing an array whose elements are of this type. Will always return the same instance for the same rank, sizes and bounds.
+ /// </summary>
+ /// <param name="rank">The number of dimensions of the array.</param>
+ /// <param name="sizes">The size of each dimension.</param>
+ /// <param name="loBounds">The lower bound for indices. Defaults to zero.</param>
+ public virtual ArrayType/*!*/ GetArrayType(int rank, int[] sizes, int[] loBounds)
+ {
+ return this.GetArrayType(rank, sizes == null ? 0 : sizes.Length, loBounds == null ? 0 : loBounds.Length, sizes == null ? new int[0] : sizes, loBounds == null ? new int[0] : loBounds);
+ }
+ internal ArrayType/*!*/ GetArrayType(int rank, int numSizes, int numLoBounds, int[]/*!*/ sizes, int[]/*!*/ loBounds)
+ {
+ if (this.arrayTypes == null) this.arrayTypes = new TrivialHashtable();
+ StringBuilder sb = new StringBuilder(rank * 5);
+ for (int i = 0; i < rank; i++)
+ {
+ if (i < numLoBounds) sb.Append(loBounds[i]); else sb.Append('0');
+ if (i < numSizes) { sb.Append(':'); sb.Append(sizes[i]); }
+ sb.Append(',');
+ }
+ Identifier id = Identifier.For(sb.ToString());
+ ArrayType result = (ArrayType)this.arrayTypes[id.UniqueIdKey];
+ if (result != null) return result;
+ lock (this)
+ {
+ result = (ArrayType)this.arrayTypes[id.UniqueIdKey];
+ if (result != null) return result;
+ if (loBounds == null) loBounds = new int[0];
+ this.arrayTypes[id.UniqueIdKey] = result = new ArrayType(this, rank, sizes, loBounds);
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= this.Flags & TypeFlags.VisibilityMask;
+ return result;
+ }
+ }
+ protected internal MemberList constructors;
+ public virtual MemberList GetConstructors()
+ {
+ if (this.Members.Count != this.memberCount) this.constructors = null;
+ if (this.constructors != null) return this.constructors;
+ lock (this)
+ {
+ if (this.constructors != null) return this.constructors;
+ return this.constructors = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.Ctor), MethodFlags.RTSpecialName);
+ }
+ }
+ /// <summary>
+ /// Returns the constructor with the specified parameter types. Returns null if this type has no such constructor.
+ /// </summary>
+ public virtual InstanceInitializer GetConstructor(params TypeNode[] types)
+ {
+ return (InstanceInitializer)GetMethod(this.GetConstructors(), types);
+ }
+#if !NoXml
+ protected override Identifier GetDocumentationId()
+ {
+ if (this.DeclaringType == null)
+ return Identifier.For("T:" + this.FullName);
+ else
+ return Identifier.For(this.DeclaringType.DocumentationId + "." + this.Name);
+ }
+ internal virtual void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (this.DeclaringType != null)
+ {
+ this.DeclaringType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('.');
+ sb.Append(this.GetUnmangledNameWithoutTypeParameters());
+ }
+ else
+ sb.Append(this.GetFullUnmangledNameWithoutTypeParameters());
+ TypeNodeList templateArguments = this.TemplateArguments;
+ int n = templateArguments == null ? 0 : templateArguments.Count;
+ if (n == 0) return;
+ sb.Append('{');
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert templateArguments != null;
+ TypeNode templArg = templateArguments[i];
+ if (templArg == null) continue;
+ templArg.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ if (i < n - 1) sb.Append(',');
+ }
+ sb.Append('}');
+ }
+#endif
+ internal TrivialHashtable modifierTable;
+ internal TypeNode/*!*/ GetModified(TypeNode/*!*/ modifierType, bool optionalModifier)
+ {
+ if (this.modifierTable == null) this.modifierTable = new TrivialHashtable();
+ TypeNode result = (TypeNode)this.modifierTable[modifierType.UniqueKey];
+ if (result != null) return result;
+ result = optionalModifier ? (TypeNode)new OptionalModifier(modifierType, this) : (TypeNode)new RequiredModifier(modifierType, this);
+ this.modifierTable[modifierType.UniqueKey] = result;
+ return result;
+ }
+ public virtual TypeNode/*!*/ GetGenericTemplateInstance(Module/*!*/ module, TypeNodeList/*!*/ consolidatedArguments)
+ {
+ if (this.DeclaringType == null)
+ return this.GetTemplateInstance(module, null, null, consolidatedArguments);
+ TypeNodeList myArgs = this.GetOwnTemplateArguments(consolidatedArguments);
+ if (myArgs == consolidatedArguments)
+ return this.GetTemplateInstance(module, null, this.DeclaringType, consolidatedArguments);
+ int n = consolidatedArguments.Count;
+ int m = myArgs == null ? 0 : myArgs.Count;
+ int k = n - m;
+ Debug.Assert(k > 0);
+ TypeNodeList parentArgs = new TypeNodeList(k);
+ for (int i = 0; i < k; i++) parentArgs.Add(consolidatedArguments[i]);
+ TypeNode declaringType = this.DeclaringType.GetGenericTemplateInstance(module, parentArgs);
+ TypeNode nestedType = declaringType.GetNestedType(this.Name);
+ if (nestedType == null) { Debug.Fail("template declaring type dummy instance does not have a nested type corresponding to template"); nestedType = this; }
+ if (m == 0) { Debug.Assert(nestedType.template != null); return nestedType; }
+ return nestedType.GetTemplateInstance(module, null, declaringType, myArgs);
+ }
+ public virtual TypeNode/*!*/ GetTemplateInstance(Module module, params TypeNode[] typeArguments)
+ {
+ return this.GetTemplateInstance(module, null, null, new TypeNodeList(typeArguments));
+ }
+ protected virtual void TryToFindExistingInstance(Module/*!*/ module, TypeNode declaringType, TypeNodeList/*!*/ templateArguments, Identifier/*!*/ mangledName,
+ Identifier/*!*/ uniqueMangledName, out TypeNode result, out Identifier unusedMangledName)
+ {
+ unusedMangledName = null;
+ string mangledNameString = mangledName.Name;
+ int n = templateArguments.Count;
+ int tiCount = 0;
+ bool lookInReferencedAssemblies = TargetPlatform.GenericTypeNamesMangleChar != '`'; //REVIEW: huh? why not use IsGeneric?
+ result = module.GetStructurallyEquivalentType(this.Namespace == null ? Identifier.Empty : this.Namespace, mangledName, uniqueMangledName, lookInReferencedAssemblies);
+ if (this.IsGeneric)
+ {
+ if (result == null) unusedMangledName = mangledName;
+ return;
+ }
+ while (result != null)
+ {
+ //Mangled name is the same. But mangling is not unique (types are not qualified with assemblies), so check for equality.
+ if (this == result.Template && (declaringType == result.DeclaringType || !this.IsGeneric))
+ {
+ bool goodMatch = (result.TemplateArguments != null || n == 0) && result.TemplateArguments.Count == n;
+ for (int i = 0; goodMatch && i < n; i++)
+ goodMatch = templateArguments[i] == result.TemplateArguments[i];
+ if (goodMatch) return;
+ }
+ //Mangle some more
+ mangledName = new Identifier(mangledNameString + (++tiCount).ToString());
+ result = module.GetStructurallyEquivalentType(this.Namespace == null ? Identifier.Empty : this.Namespace, mangledName, null, lookInReferencedAssemblies);
+ }
+ if (result == null) unusedMangledName = mangledName;
+ }
+ public virtual Identifier/*!*/ GetMangledTemplateInstanceName(TypeNodeList/*!*/ templateArguments, out Identifier/*!*/ uniqueMangledName, out bool notFullySpecialized)
+ {
+ StringBuilder mangledNameBuilder = new StringBuilder(this.Name.ToString());
+ StringBuilder uniqueMangledNameBuilder = new StringBuilder(this.Name.ToString());
+ uniqueMangledNameBuilder.Append(this.UniqueKey);
+ notFullySpecialized = false;
+ for (int i = 0, n = templateArguments.Count; i < n; i++)
+ {
+ if (i == 0) { mangledNameBuilder.Append('<'); uniqueMangledNameBuilder.Append('<'); }
+ TypeNode t = templateArguments[i];
+ if (t == null || t.Name == null) continue;
+ if (TypeIsNotFullySpecialized(t)) notFullySpecialized = true;
+ mangledNameBuilder.Append(t.FullName);
+ uniqueMangledNameBuilder.Append(t.FullName);
+ uniqueMangledNameBuilder.Append(t.UniqueKey);
+ if (i < n - 1)
+ {
+ mangledNameBuilder.Append(',');
+ uniqueMangledNameBuilder.Append(',');
+ }
+ else
+ {
+ mangledNameBuilder.Append('>');
+ uniqueMangledNameBuilder.Append('>');
+ }
+ }
+ uniqueMangledName = Identifier.For(uniqueMangledNameBuilder.ToString());
+ return Identifier.For(mangledNameBuilder.ToString());
+ }
+ private static bool TypeIsNotFullySpecialized(TypeNode t)
+ {
+ TypeNode tt = TypeNode.StripModifiers(t);
+ //^ assert tt != null;
+ if (tt is TypeParameter || tt is ClassParameter || tt.IsNotFullySpecialized)
+ return true;
+ for (int j = 0, m = tt.StructuralElementTypes == null ? 0 : tt.StructuralElementTypes.Count; j < m; j++)
+ {
+ TypeNode et = tt.StructuralElementTypes[j];
+ if (et == null) continue;
+ if (TypeIsNotFullySpecialized(et)) return true;
+ }
+ return false;
+ }
+ /// <summary>
+ /// Gets an instance for the given template arguments of this (generic) template type.
+ /// </summary>
+ /// <param name="referringType">The type in which the reference to the template instance occurs. If the template is not
+ /// generic, the instance becomes a nested type of the referring type so that it has the same access privileges as the
+ /// code referrring to the instance.</param>
+ /// <param name="templateArguments">The template arguments.</param>
+ /// <returns>An instance of the template. Always the same instance for the same arguments.</returns>
+ public virtual TypeNode/*!*/ GetTemplateInstance(TypeNode referringType, params TypeNode[] templateArguments)
+ {
+ return this.GetTemplateInstance(referringType, new TypeNodeList(templateArguments));
+ }
+ /// <summary>
+ /// Gets an instance for the given template arguments of this (generic) template type.
+ /// </summary>
+ /// <param name="referringType">The type in which the reference to the template instance occurs. If the template is not
+ /// generic, the instance becomes a nested type of the referring type so that it has the same access privileges as the
+ /// code referrring to the instance.</param>
+ /// <param name="templateArguments">The template arguments.</param>
+ /// <returns>An instance of the template. Always the same instance for the same arguments.</returns>
+ public virtual TypeNode/*!*/ GetTemplateInstance(TypeNode referringType, TypeNodeList templateArguments)
+ {
+ if (referringType == null) return this;
+ Module module = referringType.DeclaringModule;
+ return this.GetTemplateInstance(module, referringType, this.DeclaringType, templateArguments);
+ }
+ class CachingModuleForGenericsInstances : Module
+ {
+ public override TypeNode GetStructurallyEquivalentType(Identifier ns, Identifier/*!*/ id, Identifier uniqueMangledName, bool lookInReferencedAssemblies)
+ {
+ if (uniqueMangledName == null) return null;
+ return (TypeNode)this.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey];
+ }
+ }
+ protected static Module/*!*/ cachingModuleForGenericInstances = new CachingModuleForGenericsInstances();
+ public virtual TypeNode/*!*/ GetTemplateInstance(Module module, TypeNode referringType, TypeNode declaringType, TypeNodeList templateArguments)
+ {
+ TypeNodeList templateParameters = this.TemplateParameters;
+ if (module == null || templateArguments == null || (declaringType == null && (templateParameters == null || templateParameters.Count == 0)))
+ return this;
+ if (this.IsGeneric)
+ {
+ referringType = null;
+ module = TypeNode.cachingModuleForGenericInstances;
+ }
+ bool notFullySpecialized;
+ Identifier/*!*/ uniqueMangledName;
+ Identifier mangledName = this.GetMangledTemplateInstanceName(templateArguments, out uniqueMangledName, out notFullySpecialized);
+ TypeNode result;
+ Identifier dummyId;
+ this.TryToFindExistingInstance(module, declaringType, templateArguments, mangledName, uniqueMangledName, out result, out dummyId);
+ if (result != null) return result;
+ if (this.NewTemplateInstanceIsRecursive) return this; //An instance of this template is trying to instantiate the template again
+ lock (Module.GlobalLock)
+ {
+ Identifier unusedMangledName;
+ this.TryToFindExistingInstance(module, declaringType, templateArguments, mangledName, uniqueMangledName, out result, out unusedMangledName);
+ if (result != null) return result;
+ //^ assume unusedMangledName != null;
+ TypeNodeList consolidatedTemplateArguments =
+ declaringType == null ? templateArguments : declaringType.GetConsolidatedTemplateArguments(templateArguments);
+ Duplicator duplicator = new Duplicator(module, referringType);
+ duplicator.RecordOriginalAsTemplate = true;
+ duplicator.SkipBodies = true;
+ duplicator.TypesToBeDuplicated[this.UniqueKey] = this;
+ result = duplicator.VisitTypeNode(this, unusedMangledName, consolidatedTemplateArguments, this.Template == null ? this : this.Template, true);
+ //^ assume result != null;
+ if (module == this.DeclaringModule)
+ {
+ if (this.TemplateInstances == null) this.TemplateInstances = new TypeNodeList();
+ this.TemplateInstances.Add(result);
+ }
+ result.Name = unusedMangledName;
+ result.Name.SourceContext = this.Name.SourceContext;
+ result.fullName = null;
+ if (this.IsGeneric) result.DeclaringModule = this.DeclaringModule;
+ result.DeclaringType = this.IsGeneric || referringType == null ? declaringType : referringType;
+ result.Template = this;
+ result.templateParameters = new TypeNodeList(0);
+ result.consolidatedTemplateParameters = new TypeNodeList(0);
+ result.templateArguments = templateArguments;
+ result.consolidatedTemplateArguments = consolidatedTemplateArguments;
+ result.IsNotFullySpecialized = notFullySpecialized || (declaringType != null && declaringType.IsNotFullySpecialized);
+ module.StructurallyEquivalentType[unusedMangledName.UniqueIdKey] = result;
+ module.StructurallyEquivalentType[uniqueMangledName.UniqueIdKey] = result;
+ Specializer specializer = new Specializer(module, this.ConsolidatedTemplateParameters, consolidatedTemplateArguments);
+ specializer.VisitTypeNode(result);
+ TypeFlags visibility = this.Flags & TypeFlags.VisibilityMask;
+ for (int i = 0, m = templateArguments.Count; i < m; i++)
+ {
+ TypeNode t = templateArguments[i];
+ if (t == null) continue;
+ if (t is TypeParameter || t is ClassParameter || t.IsNotFullySpecialized) continue;
+ visibility = TypeNode.GetVisibilityIntersection(visibility, t.Flags & TypeFlags.VisibilityMask);
+ }
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= visibility;
+ if (this.IsGeneric) return result;
+#if ExtendedRuntime
+ //Arrange for template instance to be emitted to module and to be recognized as a template instance when imported from module.
+ if (referringType == null){
+ if (visibility == TypeFlags.NestedPublic)
+ visibility = TypeFlags.Public;
+ else if (visibility != TypeFlags.Public)
+ visibility = TypeFlags.NotPublic;
+ module.Types.Add(result);
+ }else{
+ switch (visibility){
+ case TypeFlags.NestedFamANDAssem:
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedPrivate:
+ if (result != referringType && this != referringType)
+ referringType.Members.Add(result);
+ else{
+ if (declaringType == null)
+ visibility = TypeFlags.NotPublic;
+ goto default;
+ }
+ break;
+ case TypeFlags.NestedAssembly:
+ if (declaringType == null)
+ visibility = TypeFlags.NotPublic;
+ goto default;
+ case TypeFlags.NestedPublic:
+ if (declaringType == null)
+ visibility = TypeFlags.Public;
+ goto default;
+ default:
+ if (declaringType == null){
+ result.DeclaringType = null;
+ module.Types.Add(result);
+ }else{
+ result.DeclaringType = declaringType;
+ declaringType.Members.Add(result);
+ }
+ break;
+ }
+ }
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= visibility;
+ AttributeList attrs = result.Attributes;
+ if (attrs == null) attrs = result.Attributes = new AttributeList(1);
+ TypeNode typeArray = CoreSystemTypes.Type.GetArrayType(1);
+ if (TypeNode.templateInstanceAttribute == null) {
+ InstanceInitializer constr = SystemTypes.TemplateInstanceAttribute.GetConstructor(CoreSystemTypes.Type, typeArray);
+ if (constr == null) { Debug.Fail(""); return result; }
+ TypeNode.templateInstanceAttribute = new MemberBinding(null, constr);
+ }
+ int n = templateArguments.Count;
+ TypeNode[] tArgs = new TypeNode[n];
+ for (int i = 0; i < n; i++) tArgs[i] = templateArguments[i];
+ AttributeNode attr = new AttributeNode(TypeNode.templateInstanceAttribute,
+ new ExpressionList(new Literal(this, CoreSystemTypes.Type), new Literal(tArgs, typeArray)));
+ attr.Target = AttributeTargets.Delegate|AttributeTargets.Class|AttributeTargets.Enum|AttributeTargets.Interface|AttributeTargets.Struct;
+ if (attrs.Count > 0 && attrs[0] == null)
+ attrs[0] = attr;
+ else
+ attrs.Add(attr);
+#endif
+ return result;
+ }
+ }
+ protected virtual TypeNodeList GetConsolidatedTemplateArguments()
+ {
+ TypeNodeList typeArgs = this.TemplateArguments;
+ if (this.DeclaringType == null) return typeArgs;
+ TypeNodeList result = this.DeclaringType.ConsolidatedTemplateArguments;
+ if (result == null)
+ {
+ if (this.DeclaringType.IsGeneric && this.DeclaringType.Template == null)
+ result = this.DeclaringType.ConsolidatedTemplateParameters;
+ if (result == null)
+ return typeArgs;
+ }
+ int n = typeArgs == null ? 0 : typeArgs.Count;
+ if (n == 0) return result;
+ result = result.Clone();
+ for (int i = 0; i < n; i++) result.Add(typeArgs[i]);
+ return result;
+ }
+ protected virtual TypeNodeList GetConsolidatedTemplateArguments(TypeNodeList typeArgs)
+ {
+ TypeNodeList result = this.ConsolidatedTemplateArguments;
+ if (result == null || result.Count == 0)
+ {
+ if (this.IsGeneric && this.Template == null)
+ result = this.ConsolidatedTemplateParameters;
+ else
+ return typeArgs;
+ }
+ int n = typeArgs == null ? 0 : typeArgs.Count;
+ if (n == 0) return result;
+ //^ assert typeArgs != null;
+ result = result.Clone();
+ for (int i = 0; i < n; i++) result.Add(typeArgs[i]);
+ return result;
+ }
+ protected virtual TypeNodeList GetConsolidatedTemplateParameters()
+ {
+ TypeNodeList typeParams = this.TemplateParameters;
+ TypeNode declaringType = this.DeclaringType;
+ if (declaringType == null) return typeParams;
+ while (declaringType.Template != null) declaringType = declaringType.Template;
+ TypeNodeList result = declaringType.ConsolidatedTemplateParameters;
+ if (result == null) return typeParams;
+ int n = typeParams == null ? 0 : typeParams.Count;
+ if (n == 0) return result;
+ result = result.Clone();
+ for (int i = 0; i < n; i++) result.Add(typeParams[i]);
+ return result;
+ }
+ protected virtual TypeNodeList GetOwnTemplateArguments(TypeNodeList consolidatedTemplateArguments)
+ {
+ int n = this.TemplateParameters == null ? 0 : this.TemplateParameters.Count;
+ int m = consolidatedTemplateArguments == null ? 0 : consolidatedTemplateArguments.Count;
+ int k = m - n;
+ if (k <= 0) return consolidatedTemplateArguments;
+ TypeNodeList result = new TypeNodeList(n);
+ if (consolidatedTemplateArguments != null)
+ for (int i = 0; i < n; i++)
+ result.Add(consolidatedTemplateArguments[i + k]);
+ return result;
+ }
+#if ExtendedRuntime
+ private static MemberBinding templateInstanceAttribute = null;
+#endif
+ protected internal Pointer pointerType;
+ public virtual Pointer/*!*/ GetPointerType()
+ {
+ Pointer result = this.pointerType;
+ if (result == null)
+ {
+ lock (this)
+ {
+ if (this.pointerType != null) return this.pointerType;
+ result = this.pointerType = new Pointer(this);
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= this.Flags & TypeFlags.VisibilityMask;
+ result.DeclaringModule = this.DeclaringModule;
+ }
+ }
+ return result;
+ }
+ protected internal Reference referenceType;
+ public virtual Reference/*!*/ GetReferenceType()
+ {
+ Reference result = this.referenceType;
+ if (result == null)
+ {
+ lock (this)
+ {
+ if (this.referenceType != null) return this.referenceType;
+ result = this.referenceType = new Reference(this);
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= this.Flags & TypeFlags.VisibilityMask;
+ result.DeclaringModule = this.DeclaringModule;
+ }
+ }
+ return result;
+ }
+ //^ [Microsoft.Contracts.SpecPublic]
+ protected internal TrivialHashtable memberTable;
+ protected internal int memberCount;
+ /// <summary>
+ /// Returns a list of all the members declared directly by this type with the specified name.
+ /// Returns an empty list if this type has no such members.
+ /// </summary>
+ public virtual MemberList/*!*/ GetMembersNamed(Identifier name)
+ {
+ if (name == null) return new MemberList(0);
+ MemberList members = this.Members;
+ int n = members == null ? 0 : members.Count;
+ if (n != this.memberCount || this.memberTable == null) this.UpdateMemberTable(n);
+ //^ assert this.memberTable != null;
+ MemberList result = (MemberList)this.memberTable[name.UniqueIdKey];
+ if (result == null)
+ {
+ lock (this)
+ {
+ result = (MemberList)this.memberTable[name.UniqueIdKey];
+ if (result != null) return result;
+ this.memberTable[name.UniqueIdKey] = (result = new MemberList());
+ }
+ }
+ return result;
+ }
+ /// <summary>
+ /// Returns the first event declared by this type with the specified name.
+ /// Returns null if this type has no such event.
+ /// </summary>
+ public virtual Event GetEvent(Identifier name)
+ {
+ MemberList members = this.GetMembersNamed(name);
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Event ev = members[i] as Event;
+ if (ev != null) return ev;
+ }
+ return null;
+ }
+ /// <summary>
+ /// Returns the first field declared by this type with the specified name. Returns null if this type has no such field.
+ /// </summary>
+ public virtual Field GetField(Identifier name)
+ {
+ MemberList members = this.GetMembersNamed(name);
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Field field = members[i] as Field;
+ if (field != null) return field;
+ }
+ return null;
+ }
+ /// <summary>
+ /// Returns the first method declared by this type with the specified name and parameter types. Returns null if this type has no such method.
+ /// </summary>
+ /// <returns></returns>
+ public virtual Method GetMethod(Identifier name, params TypeNode[] types)
+ {
+ return GetMethod(this.GetMembersNamed(name), types);
+ }
+ private static Method GetMethod(MemberList members, params TypeNode[] types)
+ {
+ if (members == null) return null;
+ int m = types == null ? 0 : types.Length;
+ TypeNodeList typeNodes = m == 0 ? null : new TypeNodeList(types);
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method meth = members[i] as Method;
+ if (meth == null) continue;
+ if (meth.ParameterTypesMatchStructurally(typeNodes)) return meth;
+ }
+ return null;
+ }
+ public Method GetMatchingMethod(Method method)
+ {
+ if (method == null || method.Name == null) return null;
+ MemberList members = this.GetMembersNamed(method.Name);
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ {
+ Method m = members[i] as Method;
+ if (m == null) continue;
+ if (m.ParametersMatchStructurally(method.Parameters)) return m;
+ }
+ return null;
+ }
+ /// <summary>
+ /// Returns the first nested type declared by this type with the specified name. Returns null if this type has no such nested type.
+ /// </summary>
+ public virtual TypeNode GetNestedType(Identifier name)
+ {
+ if (name == null) return null;
+ if (this.members != null)
+ {
+ MemberList members = this.GetMembersNamed(name);
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ TypeNode type = members[i] as TypeNode;
+ if (type != null) return type;
+ }
+ return null;
+ }
+ TypeNodeList nestedTypes = this.NestedTypes;
+ for (int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++)
+ {
+ TypeNode type = nestedTypes[i];
+ if (type != null && type.Name.UniqueIdKey == name.UniqueIdKey) return type;
+ }
+ return null;
+ }
+ protected internal TypeNodeList nestedTypes;
+ public virtual TypeNodeList NestedTypes
+ {
+ get
+ {
+ if (this.nestedTypes != null && (this.members == null || this.members.Count == this.memberCount))
+ return this.nestedTypes;
+ if (this.ProvideNestedTypes != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ this.ProvideNestedTypes(this, this.ProviderHandle);
+ }
+ }
+ else
+ {
+ MemberList members = this.Members;
+ TypeNodeList nestedTypes = new TypeNodeList();
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ {
+ TypeNode nt = members[i] as TypeNode;
+ if (nt == null) continue;
+ nestedTypes.Add(nt);
+ }
+ this.nestedTypes = nestedTypes;
+ }
+ return this.nestedTypes;
+ }
+ set
+ {
+ this.nestedTypes = value;
+ }
+ }
+ /// <summary>
+ /// Returns the first property declared by this type with the specified name and parameter types. Returns null if this type has no such property.
+ /// </summary>
+ public virtual Property GetProperty(Identifier name, params TypeNode[] types)
+ {
+ return GetProperty(this.GetMembersNamed(name), types);
+ }
+ private static Property GetProperty(MemberList members, params TypeNode[] types)
+ {
+ if (members == null) return null;
+ int m = types == null ? 0 : types.Length;
+ TypeNodeList typeNodes = m == 0 ? null : new TypeNodeList(types);
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Property prop = members[i] as Property;
+ if (prop == null) continue;
+ if (prop.ParameterTypesMatch(typeNodes)) return prop;
+ }
+ return null;
+ }
+#if !MinimalReader
+ protected internal MemberList explicitCoercionMethods;
+ public virtual MemberList ExplicitCoercionMethods
+ {
+ get
+ {
+ if (this.Members.Count != this.memberCount) this.explicitCoercionMethods = null;
+ if (this.explicitCoercionMethods != null) return this.explicitCoercionMethods;
+ lock (this)
+ {
+ if (this.explicitCoercionMethods != null) return this.explicitCoercionMethods;
+ return this.explicitCoercionMethods = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.opExplicit), MethodFlags.SpecialName);
+ }
+ }
+ }
+ protected internal MemberList implicitCoercionMethods;
+ public virtual MemberList ImplicitCoercionMethods
+ {
+ get
+ {
+ if (this.Members.Count != this.memberCount) this.implicitCoercionMethods = null;
+ if (this.implicitCoercionMethods != null) return this.implicitCoercionMethods;
+ lock (this)
+ {
+ if (this.implicitCoercionMethods != null) return this.implicitCoercionMethods;
+ return this.implicitCoercionMethods = TypeNode.WeedOutNonSpecialMethods(this.GetMembersNamed(StandardIds.opImplicit), MethodFlags.SpecialName);
+ }
+ }
+ }
+ protected readonly static Method MethodDoesNotExist = new Method();
+ protected internal TrivialHashtable explicitCoercionFromTable;
+ public virtual Method GetExplicitCoercionFromMethod(TypeNode sourceType)
+ {
+ if (sourceType == null) return null;
+ Method result = null;
+ if (this.explicitCoercionFromTable != null)
+ result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ lock (this)
+ {
+ if (this.explicitCoercionFromTable != null)
+ result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList coercions = this.ExplicitCoercionMethods;
+ for (int i = 0, n = coercions.Count; i < n; i++)
+ {
+ Method m = (Method)coercions[i];
+ if (sourceType == m.Parameters[0].Type) { result = m; break; }
+ }
+ if (this.explicitCoercionFromTable == null)
+ this.explicitCoercionFromTable = new TrivialHashtable();
+ if (result == null)
+ this.explicitCoercionFromTable[sourceType.UniqueKey] = TypeNode.MethodDoesNotExist;
+ else
+ this.explicitCoercionFromTable[sourceType.UniqueKey] = result;
+ return result;
+ }
+ }
+ protected internal TrivialHashtable explicitCoercionToTable;
+ public virtual Method GetExplicitCoercionToMethod(TypeNode targetType)
+ {
+ if (targetType == null) return null;
+ Method result = null;
+ if (this.explicitCoercionToTable != null)
+ result = (Method)this.explicitCoercionToTable[targetType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ lock (this)
+ {
+ if (this.explicitCoercionToTable != null)
+ result = (Method)this.explicitCoercionToTable[targetType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList coercions = this.ExplicitCoercionMethods;
+ for (int i = 0, n = coercions.Count; i < n; i++)
+ {
+ Method m = (Method)coercions[i];
+ if (m.ReturnType == targetType) { result = m; break; }
+ }
+ if (this.explicitCoercionToTable == null)
+ this.explicitCoercionToTable = new TrivialHashtable();
+ if (result == null)
+ this.explicitCoercionToTable[targetType.UniqueKey] = TypeNode.MethodDoesNotExist;
+ else
+ this.explicitCoercionToTable[targetType.UniqueKey] = result;
+ }
+ return result;
+ }
+ protected internal TrivialHashtable implicitCoercionFromTable;
+ public virtual Method GetImplicitCoercionFromMethod(TypeNode sourceType)
+ {
+ if (sourceType == null) return null;
+ Method result = null;
+ if (this.implicitCoercionFromTable != null)
+ result = (Method)this.implicitCoercionFromTable[sourceType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ lock (this)
+ {
+ if (this.implicitCoercionFromTable != null)
+ result = (Method)this.implicitCoercionFromTable[sourceType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList coercions = this.ImplicitCoercionMethods;
+ for (int i = 0, n = coercions.Count; i < n; i++)
+ {
+ Method m = (Method)coercions[i];
+ if (sourceType.IsStructurallyEquivalentTo(TypeNode.StripModifiers(m.Parameters[0].Type))) { result = m; break; }
+ }
+ if (this.implicitCoercionFromTable == null)
+ this.implicitCoercionFromTable = new TrivialHashtable();
+ if (result == null)
+ this.implicitCoercionFromTable[sourceType.UniqueKey] = TypeNode.MethodDoesNotExist;
+ else
+ this.implicitCoercionFromTable[sourceType.UniqueKey] = result;
+ return result;
+ }
+ }
+ protected internal TrivialHashtable implicitCoercionToTable;
+ public virtual Method GetImplicitCoercionToMethod(TypeNode targetType)
+ {
+ if (targetType == null) return null;
+ Method result = null;
+ if (this.implicitCoercionToTable != null)
+ result = (Method)this.implicitCoercionToTable[targetType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ lock (this)
+ {
+ if (this.implicitCoercionToTable != null)
+ result = (Method)this.implicitCoercionToTable[targetType.UniqueKey];
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList coercions = this.ImplicitCoercionMethods;
+ for (int i = 0, n = coercions.Count; i < n; i++)
+ {
+ Method m = (Method)coercions[i];
+ if (m.ReturnType == targetType) { result = m; break; }
+ }
+ if (this.implicitCoercionToTable == null)
+ this.implicitCoercionToTable = new TrivialHashtable();
+ if (result == null)
+ this.implicitCoercionToTable[targetType.UniqueKey] = TypeNode.MethodDoesNotExist;
+ else
+ this.implicitCoercionToTable[targetType.UniqueKey] = result;
+ return result;
+ }
+ }
+ protected Method opFalse;
+ public virtual Method GetOpFalse()
+ {
+ Method result = this.opFalse;
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList members = this.Members; //evaluate for side effect
+ if (members != null) members = null;
+ lock (this)
+ {
+ result = this.opFalse;
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ TypeNode t = this;
+ while (t != null)
+ {
+ MemberList opFalses = t.GetMembersNamed(StandardIds.opFalse);
+ if (opFalses != null)
+ for (int i = 0, n = opFalses.Count; i < n; i++)
+ {
+ Method opFalse = opFalses[i] as Method;
+ if (opFalse == null) continue;
+ if (!opFalse.IsSpecialName || !opFalse.IsStatic || !opFalse.IsPublic || opFalse.ReturnType != CoreSystemTypes.Boolean ||
+ opFalse.Parameters == null || opFalse.Parameters.Count != 1) continue;
+ return this.opFalse = opFalse;
+ }
+ t = t.BaseType;
+ }
+ this.opFalse = TypeNode.MethodDoesNotExist;
+ return null;
+ }
+ }
+ protected Method opTrue;
+ public virtual Method GetOpTrue()
+ {
+ Method result = this.opTrue;
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ MemberList members = this.Members; //evaluate for side effect
+ if (members != null) members = null;
+ lock (this)
+ {
+ result = this.opTrue;
+ if (result == TypeNode.MethodDoesNotExist) return null;
+ if (result != null) return result;
+ TypeNode t = this;
+ while (t != null)
+ {
+ MemberList opTrues = t.GetMembersNamed(StandardIds.opTrue);
+ if (opTrues != null)
+ for (int i = 0, n = opTrues.Count; i < n; i++)
+ {
+ Method opTrue = opTrues[i] as Method;
+ if (opTrue == null) continue;
+ if (!opTrue.IsSpecialName || !opTrue.IsStatic || !opTrue.IsPublic || opTrue.ReturnType != CoreSystemTypes.Boolean ||
+ opTrue.Parameters == null || opTrue.Parameters.Count != 1) continue;
+ return this.opTrue = opTrue;
+ }
+ t = t.BaseType;
+ }
+ this.opTrue = TypeNode.MethodDoesNotExist;
+ return null;
+ }
+ }
+#endif
+#if !NoReflection
+ private static Hashtable typeMap; //contains weak references
+ /// <summary>
+ /// Gets a TypeNode instance corresponding to the given System.Type instance.
+ /// </summary>
+ /// <param name="type">A runtime type.</param>
+ /// <returns>A TypeNode instance.</returns>
+ public static TypeNode GetTypeNode(System.Type type)
+ {
+ if (type == null) return null;
+ Hashtable typeMap = TypeNode.typeMap;
+ if (typeMap == null) TypeNode.typeMap = typeMap = Hashtable.Synchronized(new Hashtable());
+ TypeNode result = null;
+ WeakReference wr = (WeakReference)typeMap[type];
+ if (wr != null)
+ {
+ result = wr.Target as TypeNode;
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ }
+#if WHIDBEY
+ if (type.IsGenericType && !type.IsGenericTypeDefinition)
+ {
+ try
+ {
+ TypeNode template = TypeNode.GetTypeNode(type.GetGenericTypeDefinition());
+ if (template == null) return null;
+ TypeNodeList templateArguments = new TypeNodeList();
+ foreach (Type arg in type.GetGenericArguments())
+ templateArguments.Add(TypeNode.GetTypeNode(arg));
+ return template.GetGenericTemplateInstance(template.DeclaringModule, templateArguments);
+ }
+ catch
+ {
+ //TODO: log error
+ return null;
+ }
+ }
+ if (type.IsGenericParameter)
+ {
+ try
+ {
+ int parIndx = type.GenericParameterPosition;
+ System.Reflection.MethodInfo mi = type.DeclaringMethod as System.Reflection.MethodInfo;
+ if (mi != null)
+ {
+ Method m = Method.GetMethod(mi);
+ if (m == null) return null;
+ if (m.TemplateParameters != null && m.TemplateParameters.Count > parIndx)
+ return m.TemplateParameters[parIndx];
+ }
+ else
+ {
+ System.Type ti = type.DeclaringType;
+ TypeNode t = TypeNode.GetTypeNode(ti);
+ if (t == null) return null;
+ if (t.TemplateParameters != null && t.TemplateParameters.Count > parIndx)
+ return t.TemplateParameters[parIndx];
+ }
+ return null;
+ }
+ catch
+ {
+ //TODO: log error
+ return null;
+ }
+ }
+#endif
+ if (type.HasElementType)
+ {
+ TypeNode elemType = TypeNode.GetTypeNode(type.GetElementType());
+ if (elemType == null) return null;
+ if (type.IsArray)
+ result = elemType.GetArrayType(type.GetArrayRank());
+ else if (type.IsByRef)
+ result = elemType.GetReferenceType();
+ else if (type.IsPointer)
+ result = elemType.GetPointerType();
+ else
+ {
+ Debug.Assert(false);
+ result = null;
+ }
+ }
+ else if (type.DeclaringType != null)
+ {
+ TypeNode dType = TypeNode.GetTypeNode(type.DeclaringType);
+ if (dType == null) return null;
+ result = dType.GetNestedType(Identifier.For(type.Name));
+ }
+ else
+ {
+ AssemblyNode assem = AssemblyNode.GetAssembly(type.Assembly);
+ if (assem != null)
+ {
+ result = assem.GetType(Identifier.For(type.Namespace), Identifier.For(type.Name));
+ }
+ }
+ if (result == null)
+ typeMap[type] = new WeakReference(Class.DoesNotExist);
+ else
+ typeMap[type] = new WeakReference(result);
+ return result;
+ }
+ protected internal Type runtimeType;
+ /// <summary>
+ /// Gets a System.Type instance corresponding to this type. The assembly containin this type must be normalized
+ /// and must have a location on disk or must have been loaded via AssemblyNode.GetRuntimeAssembly.
+ /// </summary>
+ /// <returns>A System.Type instance. (A runtime type.)</returns>
+ public virtual Type GetRuntimeType()
+ {
+ if (this.runtimeType == null)
+ {
+ lock (this)
+ {
+ if (this.runtimeType != null) return this.runtimeType;
+#if WHIDBEY
+ if (this.IsGeneric && this.Template != null)
+ {
+ try
+ {
+ TypeNode rootTemplate = this.Template;
+ while (rootTemplate.Template != null)
+ rootTemplate = rootTemplate.Template;
+ Type genType = rootTemplate.GetRuntimeType();
+ if (genType == null) return null;
+ TypeNodeList args = this.ConsolidatedTemplateArguments;
+ Type[] arguments = new Type[args.Count];
+ for (int i = 0; i < args.Count; i++) arguments[i] = args[i].GetRuntimeType();
+ return genType.MakeGenericType(arguments);
+ }
+ catch
+ {
+ //TODO: add error to metadata import errors if type is imported
+ return null;
+ }
+ }
+#endif
+ if (this.DeclaringType != null)
+ {
+ Type dt = this.DeclaringType.GetRuntimeType();
+ if (dt != null)
+ {
+ System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
+ if (this.IsPublic) flags |= System.Reflection.BindingFlags.Public; else flags |= System.Reflection.BindingFlags.NonPublic;
+ this.runtimeType = dt.GetNestedType(this.Name.ToString(), flags);
+ }
+ }
+ else if (this.DeclaringModule != null && this.DeclaringModule.IsNormalized && this.DeclaringModule.ContainingAssembly != null)
+ {
+ System.Reflection.Assembly runtimeAssembly = this.DeclaringModule.ContainingAssembly.GetRuntimeAssembly();
+ if (runtimeAssembly != null)
+ this.runtimeType = runtimeAssembly.GetType(this.FullName, false);
+ }
+ }
+ }
+ return this.runtimeType;
+ }
+#endif
+ public static TypeFlags GetVisibilityIntersection(TypeFlags vis1, TypeFlags vis2)
+ {
+ switch (vis2)
+ {
+ case TypeFlags.Public:
+ case TypeFlags.NestedPublic:
+ return vis1;
+ case TypeFlags.NotPublic:
+ case TypeFlags.NestedAssembly:
+ switch (vis1)
+ {
+ case TypeFlags.Public:
+ return vis2;
+ case TypeFlags.NestedPublic:
+ case TypeFlags.NestedFamORAssem:
+ return TypeFlags.NestedAssembly;
+ case TypeFlags.NestedFamily:
+ return TypeFlags.NestedFamANDAssem;
+ default:
+ return vis1;
+ }
+ case TypeFlags.NestedFamANDAssem:
+ switch (vis1)
+ {
+ case TypeFlags.Public:
+ case TypeFlags.NestedPublic:
+ case TypeFlags.NestedFamORAssem:
+ case TypeFlags.NestedFamily:
+ return TypeFlags.NestedFamANDAssem;
+ default:
+ return vis1;
+ }
+ case TypeFlags.NestedFamORAssem:
+ switch (vis1)
+ {
+ case TypeFlags.Public:
+ case TypeFlags.NestedPublic:
+ return TypeFlags.NestedFamORAssem;
+ default:
+ return vis1;
+ }
+ case TypeFlags.NestedFamily:
+ switch (vis1)
+ {
+ case TypeFlags.Public:
+ case TypeFlags.NestedPublic:
+ case TypeFlags.NestedFamORAssem:
+ return TypeFlags.NestedFamily;
+ case TypeFlags.NestedAssembly:
+ return TypeFlags.NestedFamANDAssem;
+ default:
+ return vis1;
+ }
+ default:
+ return TypeFlags.NestedPrivate;
+ }
+ }
+ private TrivialHashtable explicitInterfaceImplementations;
+ public bool ImplementsExplicitly(Method method)
+ {
+ if (method == null) return false;
+ TrivialHashtable explicitInterfaceImplementations = this.explicitInterfaceImplementations;
+ if (explicitInterfaceImplementations == null)
+ {
+ MemberList members = this.Members;
+ lock (this)
+ {
+ if ((explicitInterfaceImplementations = this.explicitInterfaceImplementations) == null)
+ {
+ explicitInterfaceImplementations = this.explicitInterfaceImplementations = new TrivialHashtable();
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method m = members[i] as Method;
+ if (m == null) continue;
+ MethodList implementedInterfaceMethods = m.ImplementedInterfaceMethods;
+ if (implementedInterfaceMethods != null)
+ for (int j = 0, k = implementedInterfaceMethods.Count; j < k; j++)
+ {
+ Method im = implementedInterfaceMethods[j];
+ if (im == null) continue;
+ explicitInterfaceImplementations[im.UniqueKey] = m;
+ }
+ }
+ }
+ }
+ }
+ return explicitInterfaceImplementations[method.UniqueKey] != null;
+ }
+#if !MinimalReader
+ internal bool ImplementsMethod(Method meth, bool checkPublic)
+ {
+ return this.GetImplementingMethod(meth, checkPublic) != null;
+ }
+ public Method GetImplementingMethod(Method meth, bool checkPublic)
+ {
+ if (meth == null) return null;
+ MemberList mems = this.GetMembersNamed(meth.Name);
+ for (int j = 0, m = mems == null ? 0 : mems.Count; j < m; j++)
+ {
+ Method locM = mems[j] as Method;
+ if (locM == null || !locM.IsVirtual || (checkPublic && !locM.IsPublic)) continue;
+ if ((locM.ReturnType != meth.ReturnType && !(locM.ReturnType != null && locM.ReturnType.IsStructurallyEquivalentTo(meth.ReturnType))) ||
+ !locM.ParametersMatchStructurally(meth.Parameters)) continue;
+ return locM;
+ }
+ if (checkPublic && this.BaseType != null)
+ return this.BaseType.GetImplementingMethod(meth, true);
+ return null;
+ }
+#endif
+ /// <summary>
+ /// Returns true if the CLR CTS allows a value of this type may be assigned to a variable of the target type (possibly after boxing),
+ /// either because the target type is the same or a base type, or because the target type is an interface implemented by this type or the implementor of this type,
+ /// or because this type and the target type are zero based single dimensional arrays with assignment compatible reference element types
+ /// </summary>
+ public virtual bool IsAssignableTo(TypeNode targetType)
+ {
+ if (this == CoreSystemTypes.Void) return false;
+ if (targetType == this) return true;
+ if (this == CoreSystemTypes.Object) return false;
+ if (targetType == CoreSystemTypes.Object || this.IsStructurallyEquivalentTo(targetType) ||
+ this.BaseType != null && (this.BaseType.IsAssignableTo(targetType)))
+ return true;
+ if (this.BaseType != null && this.ConsolidatedTemplateParameters != null && this.BaseType.Template != null && this.BaseType.Template.IsAssignableTo(targetType))
+ return true; //When seeing if one template is assignable to another, be sure to strip off template instances along the inheritance chain
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces == null) return false;
+ for (int i = 0, n = interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ if (iface.IsAssignableTo(targetType)) return true;
+ if (iface.Template != null && this.ConsolidatedTemplateParameters != null && iface.Template.IsAssignableTo(targetType))
+ return true; //When seeing if one template is assignable to another, be sure to strip off template instances along the inheritance chain
+ }
+ return false;
+ }
+ /// <summary>
+ /// Returns true if this type is assignable to some instance of the given template.
+ /// </summary>
+ public virtual bool IsAssignableToInstanceOf(TypeNode targetTemplate)
+ {
+ if (this == CoreSystemTypes.Void || targetTemplate == null) return false;
+ if (targetTemplate.IsStructurallyEquivalentTo(this.Template == null ? this : this.Template) ||
+ this.BaseType != null && (this.BaseType.IsAssignableToInstanceOf(targetTemplate) ||
+ this.BaseType.Template != null && this.BaseType.Template.IsAssignableToInstanceOf(targetTemplate))) return true;
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces == null) return false;
+ for (int i = 0, n = interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ if (iface.IsAssignableToInstanceOf(targetTemplate)) return true;
+ }
+ return false;
+ }
+ /// <summary>
+ /// Returns true if this type is assignable to some instance of the given template.
+ /// </summary>
+ public virtual bool IsAssignableToInstanceOf(TypeNode targetTemplate, out TypeNodeList templateArguments)
+ {
+ templateArguments = null;
+ if (this == CoreSystemTypes.Void || targetTemplate == null) return false;
+ if (targetTemplate == this.Template)
+ {
+ templateArguments = this.TemplateArguments;
+ return true;
+ }
+ if (this != CoreSystemTypes.Object && this.BaseType != null && this.BaseType.IsAssignableToInstanceOf(targetTemplate, out templateArguments)) return true;
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces == null) return false;
+ for (int i = 0, n = interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ if (iface.IsAssignableToInstanceOf(targetTemplate, out templateArguments)) return true;
+ }
+ return false;
+ }
+ /// <summary>
+ /// Returns true if otherType is the base class of this type or if the base class of this type is derived from otherType.
+ /// </summary>
+ public virtual bool IsDerivedFrom(TypeNode otherType)
+ {
+ if (otherType == null) return false;
+ TypeNode baseType = this.BaseType;
+ while (baseType != null)
+ {
+ if (baseType == otherType) return true;
+ baseType = baseType.BaseType;
+ }
+ return false;
+ }
+#if !MinimalReader
+ // Not thread safe code...
+ bool isCheckingInheritedFrom = false;
+ public virtual bool IsInheritedFrom(TypeNode otherType)
+ {
+ if (otherType == null) return false;
+ if (this == otherType) return true;
+ bool result = false;
+ if (this.isCheckingInheritedFrom)
+ goto done;
+ this.isCheckingInheritedFrom = true;
+ if (this.Template != null)
+ {
+ result = this.Template.IsInheritedFrom(otherType);
+ goto done;
+ }
+ if (otherType.Template != null)
+ {
+ otherType = otherType.Template;
+ }
+ TypeNode baseType = this.BaseType;
+ if (baseType != null && baseType.IsInheritedFrom(otherType))
+ {
+ result = true;
+ goto done;
+ }
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces == null) goto done;
+ for (int i = 0, n = interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ if (iface.IsInheritedFrom(otherType))
+ {
+ result = true;
+ goto done;
+ }
+ }
+ done:
+ this.isCheckingInheritedFrom = false;
+ return result;
+ }
+#endif
+ public virtual bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (null == (object)type) return false;
+ if (this == type) return true;
+ if (this.Template == (object)null || type.Template == (object)null)
+ {
+ if (((object)this) == (object)type.Template || ((object)this.Template) == (object)type) return true;
+ Identifier thisName = this.Template == null ? this.Name : this.Template.Name;
+ Identifier typeName = type.Template == null ? type.Name : type.Template.Name;
+ if (thisName == null || typeName == null || thisName.UniqueIdKey != typeName.UniqueIdKey) return false;
+ if (this.NodeType != type.NodeType) return false;
+ if (this.DeclaringType == null || type.DeclaringType == null) return false;
+ }
+ if (this.TemplateArguments == null || type.TemplateArguments == null)
+ {
+ if (this.DeclaringType != null && (this.TemplateArguments == null || this.TemplateArguments.Count == 0) &&
+ (type.TemplateArguments == null || type.TemplateArguments.Count == 0))
+ return this.DeclaringType.IsStructurallyEquivalentTo(type.DeclaringType);
+ return false;
+ }
+ int n = this.TemplateArguments.Count; if (n != type.TemplateArguments.Count) return false;
+ if (this.Template != type.Template && !this.Template.IsStructurallyEquivalentTo(type.Template)) return false;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode ta1 = this.TemplateArguments[i];
+ TypeNode ta2 = type.TemplateArguments[i];
+ if (null == (object)ta1 || null == (object)ta2) return false;
+ if (ta1 == ta2) continue;
+ if (!ta1.IsStructurallyEquivalentTo(ta2)) return false;
+ }
+ if (this.DeclaringType != null)
+ return this.DeclaringType.IsStructurallyEquivalentTo(type.DeclaringType);
+ return true;
+ }
+ public virtual bool IsStructurallyEquivalentList(TypeNodeList list1, TypeNodeList list2)
+ {
+ if (list1 == null) return list2 == null;
+ if (list2 == null) return false;
+ int n = list1.Count; if (list2.Count != n) return false;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t1 = list1[i];
+ TypeNode t2 = list2[i];
+ if (null == (object)t1 || null == (object)t2) return false;
+ if (t1 == t2) continue;
+ if (!t1.IsStructurallyEquivalentTo(t2)) return false;
+ }
+ return true;
+ }
+ public static TypeNode StripModifiers(TypeNode type)
+ //^ ensures t != null ==> result != null;
+ {
+ for (TypeModifier tmod = type as TypeModifier; tmod != null; tmod = type as TypeModifier)
+ type = tmod.ModifiedType;
+ // Don't strip under pointers or refs. We only strip top-level modifiers.
+ return type;
+ }
+#if !MinimalReader
+ public static TypeNode DeepStripModifiers(TypeNode type)
+ //^ ensures type != null ==> result != null;
+ {
+ // strip off any outer type modifiers
+ for (TypeModifier tmod = type as TypeModifier; tmod != null; tmod = type as TypeModifier)
+ type = tmod.ModifiedType;
+ // For arrays and references, strip the inner type and then reconstruct the array or reference
+ ArrayType ar = type as ArrayType;
+ if (ar != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType);
+ return t.GetArrayType(1);
+ }
+ Reference rt = type as Reference;
+ if (rt != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType);
+ return t.GetReferenceType();
+ }
+ return type;
+ }
+ /// <summary>
+ /// Strip the given modifier from the type, modulo substructures that are instantiated with respect
+ /// to the given template type. In other words, travers type and templateType in parallel, stripping common
+ /// non-null modifiers, but stop when reaching a type variable in the template type.
+ /// <param name="type">Type to be stripped</param>
+ /// <param name="modifiers">Modifiers to strip off</param>
+ /// <param name="templateType">Template bounding the stripping of type. Passing null for the templateType performs a full DeepStrip</param>
+ /// </summary>
+ public static TypeNode DeepStripModifiers(TypeNode type, TypeNode templateType, params TypeNode[] modifiers)
+ {
+ if (templateType == null) return DeepStripModifiers(type, modifiers);
+ if (templateType is ITypeParameter) return type;
+ // strip off inner modifiers then outer type modifier if it matches
+ OptionalModifier optmod = type as OptionalModifier;
+ if (optmod != null)
+ {
+ OptionalModifier optmodtemplate = (OptionalModifier)templateType; // must be in sync
+ TypeNode t = TypeNode.DeepStripModifiers(optmod.ModifiedType, optmodtemplate.ModifiedType, modifiers);
+ for (int i = 0; i < modifiers.Length; ++i)
+ {
+ if (optmod.Modifier == modifiers[i])
+ {
+ // strip it
+ return t;
+ }
+ }
+ return OptionalModifier.For(optmod.Modifier, t);
+ }
+ RequiredModifier reqmod = type as RequiredModifier;
+ if (reqmod != null)
+ {
+ RequiredModifier reqmodtemplate = (RequiredModifier)templateType; // must be in sync
+ TypeNode t = TypeNode.DeepStripModifiers(reqmod.ModifiedType, reqmodtemplate.ModifiedType, modifiers);
+ for (int i = 0; i < modifiers.Length; ++i)
+ {
+ if (reqmod.Modifier == modifiers[i])
+ {
+ // strip it
+ return t;
+ }
+ }
+ return RequiredModifier.For(reqmod.Modifier, t);
+ }
+ // For arrays and references, strip the inner type and then reconstruct the array or reference
+ ArrayType ar = type as ArrayType;
+ if (ar != null)
+ {
+ ArrayType artemplate = (ArrayType)templateType;
+ TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType, artemplate.ElementType, modifiers);
+ return t.GetArrayType(1);
+ }
+ Reference rt = type as Reference;
+ if (rt != null)
+ {
+ Reference rttemplate = (Reference)templateType;
+ TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType, rttemplate.ElementType, modifiers);
+ return t.GetReferenceType();
+ }
+ // strip template arguments
+ if (type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count > 0)
+ {
+ TypeNodeList strippedArgs = new TypeNodeList(type.TemplateArguments.Count);
+ for (int i = 0; i < type.TemplateArguments.Count; i++)
+ {
+ //FIX: bug introduced by checkin 16494
+ //templateType may have type parameters in either the TemplateArguments position or the templateParameters position.
+ //This may indicate an inconsistency in the template instantiation representation elsewhere.
+ TypeNodeList templateTypeArgs = templateType.TemplateArguments != null ? templateType.TemplateArguments : templateType.TemplateParameters;
+ strippedArgs.Add(DeepStripModifiers(type.TemplateArguments[i], templateTypeArgs[i], modifiers));
+ }
+ return type.Template.GetTemplateInstance(type, strippedArgs);
+ }
+ return type;
+ }
+
+ public static TypeNode DeepStripModifiers(TypeNode type, params TypeNode[] modifiers)
+ {
+ // strip off inner modifiers then outer type modifier if it matches
+ OptionalModifier optmod = type as OptionalModifier;
+ if (optmod != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(optmod.ModifiedType, modifiers);
+ for (int i = 0; i < modifiers.Length; ++i)
+ {
+ if (optmod.Modifier == modifiers[i])
+ {
+ // strip it
+ return t;
+ }
+ }
+ return OptionalModifier.For(optmod.Modifier, t);
+ }
+ RequiredModifier reqmod = type as RequiredModifier;
+ if (reqmod != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(reqmod.ModifiedType, modifiers);
+ for (int i = 0; i < modifiers.Length; ++i)
+ {
+ if (reqmod.Modifier == modifiers[i])
+ {
+ // strip it
+ return t;
+ }
+ }
+ return RequiredModifier.For(reqmod.Modifier, t);
+ }
+ // For arrays and references, strip the inner type and then reconstruct the array or reference
+ ArrayType ar = type as ArrayType;
+ if (ar != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(ar.ElementType, modifiers);
+ return t.GetArrayType(1);
+ }
+ Reference rt = type as Reference;
+ if (rt != null)
+ {
+ TypeNode t = TypeNode.DeepStripModifiers(rt.ElementType, modifiers);
+ return t.GetReferenceType();
+ }
+ // strip template arguments
+ if (type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count > 0)
+ {
+ TypeNodeList strippedArgs = new TypeNodeList(type.TemplateArguments.Count);
+ for (int i = 0; i < type.TemplateArguments.Count; i++)
+ {
+ strippedArgs.Add(DeepStripModifiers(type.TemplateArguments[i], modifiers));
+ }
+ return type.Template.GetTemplateInstance(type, strippedArgs);
+ }
+ return type;
+ }
+#endif
+ public static bool HasModifier(TypeNode type, TypeNode modifier)
+ {
+ // Don't look under pointers or refs.
+ TypeModifier tmod = type as TypeModifier;
+ if (tmod != null)
+ {
+ if (tmod.Modifier == modifier) return true;
+ return TypeNode.HasModifier(tmod.ModifiedType, modifier);
+ }
+ return false;
+ }
+ public static TypeNode StripModifier(TypeNode type, TypeNode modifier)
+ {
+ // Don't strip under pointers or refs. We only strip top-level modifiers
+ TypeModifier tmod = type as TypeModifier;
+ if (tmod != null)
+ {
+ TypeNode et = TypeNode.StripModifier(tmod.ModifiedType, modifier);
+ //^ assert et != null;
+ if (tmod.Modifier == modifier) return et;
+ if (et == tmod.ModifiedType) return tmod;
+ if (tmod is OptionalModifier) return OptionalModifier.For(tmod.Modifier, et);
+ return RequiredModifier.For(tmod.Modifier, et);
+ }
+ return type;
+ }
+ /// <summary>
+ /// Needed whenever we change the id of an existing member
+ /// </summary>
+#if !MinimalReader
+ public
+#else
+ internal
+#endif
+ virtual void ClearMemberTable()
+ {
+ lock (this)
+ {
+ this.memberTable = null;
+ this.memberCount = 0;
+ }
+ }
+ protected virtual void UpdateMemberTable(int range)
+ //^ ensures this.memberTable != null;
+ {
+ MemberList thisMembers = this.Members;
+ lock (this)
+ {
+ if (this.memberTable == null) this.memberTable = new TrivialHashtable(32);
+ for (int i = this.memberCount; i < range; i++)
+ {
+ Member mem = thisMembers[i];
+ if (mem == null || mem.Name == null) continue;
+ MemberList members = (MemberList)this.memberTable[mem.Name.UniqueIdKey];
+ if (members == null) this.memberTable[mem.Name.UniqueIdKey] = members = new MemberList();
+ members.Add(mem);
+ }
+ this.memberCount = range;
+ this.constructors = null;
+ }
+ }
+ protected static MemberList WeedOutNonSpecialMethods(MemberList members, MethodFlags mask)
+ {
+ if (members == null) return null;
+ bool membersOK = true;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method m = members[i] as Method;
+ if (m == null || (m.Flags & mask) == 0)
+ {
+ membersOK = false; break;
+ }
+ }
+ if (membersOK) return members;
+ MemberList newMembers = new MemberList();
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method m = members[i] as Method;
+ if (m == null || (m.Flags & mask) == 0) continue;
+ newMembers.Add(m);
+ }
+ return newMembers;
+ }
+#if !NoXml
+ public override void WriteDocumentation(XmlTextWriter xwriter)
+ {
+ base.WriteDocumentation(xwriter);
+ MemberList members = this.Members;
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ {
+ Member mem = members[i];
+ if (mem == null) continue;
+ mem.WriteDocumentation(xwriter);
+ }
+ }
+#endif
+#if ExtendedRuntime
+ public TypeNode StripOptionalModifiers(out bool nonNull){
+ TypeNode t = this;
+ nonNull = false;
+ for(;;){
+ OptionalModifier m = t as OptionalModifier;
+ if (m == null)
+ break;
+ if (m.Modifier == SystemTypes.NonNullType)
+ nonNull = true;
+ t = m.ModifiedType;
+ }
+ return t;
+ }
+ public bool IsObjectReferenceType{
+ get{
+ bool nonNull;
+ TypeNode t = this.StripOptionalModifiers(out nonNull);
+ return t is Class || t is Interface || t is ArrayType || t is DelegateNode;
+ }
+ }
+#endif
+ public override string ToString()
+ {
+#if !FxCop
+ return this.GetFullUnmangledNameWithTypeParameters();
+#else
+ return base.ToString() + ":" + this.GetFullUnmangledNameWithTypeParameters();
+#endif
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ GetName(options.Type, name);
+ }
+ internal virtual void GetName(TypeFormat options, StringBuilder name)
+ {
+ if (options.TypeName != TypeNameFormat.None)
+ {
+ if (this.DeclaringType != null && options.TypeName != TypeNameFormat.InnermostNested)
+ {
+ this.DeclaringType.GetName(options, name);
+ name.Append('+');
+ }
+ else if (options.TypeName == TypeNameFormat.FullyQualified && this.Namespace.Name.Length > 0)
+ {
+ name.Append(this.Namespace.Name);
+ name.Append('.');
+ }
+ string shortName = this.Name.Name;
+ int mangleChar = shortName.IndexOf(TargetPlatform.GenericTypeNamesMangleChar);
+ if (mangleChar != -1)
+ shortName = shortName.Substring(0, mangleChar);
+ name.Append(shortName);
+ }
+ TypeNodeList templateParameters = this.TemplateParameters;
+ if (this.Template != null) templateParameters = this.TemplateArguments;
+ if (templateParameters != null)
+ {
+ if (options.ShowGenericTypeArity)
+ {
+ name.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ int parametersCount = templateParameters.Count;
+ name.Append(Convert.ToString(parametersCount, CultureInfo.InvariantCulture));
+ }
+ if (options.ShowGenericTypeParameterNames)
+ {
+ name.Append('<');
+ int parametersCount = templateParameters.Count;
+ for (int i = 0; i < parametersCount; ++i)
+ {
+ if (i > 0)
+ {
+ name.Append(',');
+ if (options.InsertSpacesBetweenTypeParameters) name.Append(' ');
+ }
+ templateParameters[i].GetName(options, name);
+ }
+ name.Append('>');
+ }
+ }
+ }
+#endif
+ }
+#if FxCop
+ public class ClassNode : TypeNode{
+#else
+ public class Class : TypeNode
+ {
+#endif
+ internal readonly static Class DoesNotExist = new Class();
+ internal readonly static Class Dummy = new Class();
+ internal Class baseClass;
+#if !MinimalReader
+ public Class BaseClassExpression;
+ public bool IsAbstractSealedContainerForStatics;
+#endif
+#if FxCop
+ public ClassNode()
+ : base(NodeType.Class){
+ }
+ public ClassNode(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.Class, provideNestedTypes, provideAttributes, provideMembers, handle){
+ }
+#else
+ public Class()
+ : base(NodeType.Class)
+ {
+ }
+ public Class(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.Class, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ }
+#endif
+#if !MinimalReader
+ public Class(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
+ Identifier Namespace, Identifier name, Class baseClass, InterfaceList interfaces, MemberList members)
+ : base(declaringModule, declaringType, attributes, flags, Namespace, name, interfaces, members, NodeType.Class)
+ {
+ this.baseClass = baseClass;
+ }
+#endif
+ /// <summary>
+ /// The class from which this class has been derived. Null if this class is System.Object.
+ /// </summary>
+ public virtual Class BaseClass
+ {
+ get
+ {
+ return baseClass;
+ }
+ set
+ {
+ baseClass = value;
+ }
+ }
+#if !MinimalReader
+ public override void GetAbstractMethods(MethodList/*!*/ result)
+ {
+ if (!this.IsAbstract) return;
+ MethodList candidates = new MethodList();
+ if (this.BaseClass != null)
+ {
+ this.BaseClass.GetAbstractMethods(candidates);
+ for (int i = 0, n = candidates.Count; i < n; i++)
+ {
+ Method meth = candidates[i];
+ if (!this.ImplementsMethod(meth, false)) result.Add(meth);
+ }
+ }
+ //Add any abstract methods declared inside this class
+ MemberList members = this.Members;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method meth = members[i] as Method;
+ if (meth == null) continue;
+ if (meth.IsAbstract) result.Add(meth);
+ }
+ //For each interface, get abstract methods and keep those that are not implemented by this class or a base class
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces != null)
+ for (int i = 0, n = interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ MemberList imembers = iface.Members;
+ if (imembers == null) continue;
+ for (int j = 0, m = imembers.Count; j < m; j++)
+ {
+ Method meth = imembers[j] as Method;
+ if (meth == null) continue;
+ if (this.ImplementsExplicitly(meth)) continue;
+ if (this.ImplementsMethod(meth, true)) continue;
+ if (this.AlreadyInList(result, meth)) continue;
+ result.Add(meth);
+ }
+ }
+ }
+ protected bool AlreadyInList(MethodList list, Method method)
+ {
+ if (list == null) return false;
+ for (int i = 0, n = list.Count; i < n; i++)
+ {
+ if (list[i] == method) return true;
+ }
+ return false;
+ }
+#endif
+#if ExtendedRuntime
+ public bool IsGuarded{
+ get{
+ Field f = this.GetField(Identifier.For("SpecSharp::frameGuard"));
+ return f != null;
+ }
+ }
+#endif
+ }
+#if !MinimalReader
+ public class ClosureClass : Class
+ {
+ public ClosureClass()
+ {
+ }
+ }
+ /// <summary>
+ /// Does not model a real type, but leverages the symbol table methods of Class. In other words, this is implementation inheritance, not an ISA relationship.
+ /// </summary>
+ //TODO: use delegation rather than inheritance to achieve this
+ public class Scope : Class
+ {
+ public Scope()
+ {
+ }
+ public Scope(Scope outerScope)
+ {
+ this.OuterScope = outerScope;
+ }
+ protected Scope outerScope;
+ public SourceContext LexicalSourceExtent;
+ public Scope OuterScope
+ {
+ get
+ {
+ if (this.outerScope == null)
+ this.outerScope = (Scope)this.baseClass;
+ return this.outerScope;
+ }
+ set
+ {
+ this.baseClass = this.outerScope = value;
+ }
+ }
+ public virtual TypeNode GetType(Identifier typeName)
+ {
+ return this.GetNestedType(typeName);
+ }
+ }
+ public class TypeScope : Scope
+ {
+ public TypeNode Type;
+ public TypeScope() { }
+ public TypeScope(Scope parentScope, TypeNode/*!*/ type)
+ {
+ this.baseClass = parentScope;
+ this.DeclaringModule = type.DeclaringModule;
+ this.Type = type;
+ if (type != null && type.PartiallyDefines != null) this.Type = type.PartiallyDefines;
+ this.templateParameters = type.TemplateParameters;
+ if (type != null)
+ this.LexicalSourceExtent = type.SourceContext;
+ }
+ public override MemberList/*!*/ GetMembersNamed(Identifier name)
+ {
+ TypeNode t = this.Type;
+ MemberList result = null;
+ while (t != null)
+ {
+ result = t.GetMembersNamed(name);
+ if (result.Count > 0) return result;
+ t = t.BaseType;
+ }
+ if (result != null) return result;
+ return new MemberList(0);
+ }
+ public override MemberList Members
+ {
+ get
+ {
+ return this.Type.Members;
+ }
+ set
+ {
+ base.Members = value;
+ }
+ }
+ }
+ public class MethodScope : Scope
+ {
+ protected Class closureClass;
+ public virtual Class ClosureClass
+ {
+ get
+ {
+ //if (this.DeclaringMethod == null) return null;
+ Class c = this.closureClass;
+ if (c == null)
+ {
+ c = this.closureClass = new ClosureClass();
+ c.Name = Identifier.For("closure:" + this.UniqueKey);
+ c.BaseClass = CoreSystemTypes.Object;
+ Class bclass = this.BaseClass;
+ c.DeclaringModule = bclass.DeclaringModule;
+ TypeScope tscope = bclass as TypeScope;
+ if (tscope != null)
+ c.DeclaringType = tscope.Type;
+ else
+ {
+ MethodScope mscope = bclass as MethodScope;
+ if (mscope != null)
+ c.DeclaringType = mscope.ClosureClass;
+ else
+ c.DeclaringType = ((BlockScope)bclass).ClosureClass;
+ }
+ c.IsGeneric = c.DeclaringType.IsGeneric || this.DeclaringMethod.IsGeneric;
+ c.TemplateParameters = this.CopyMethodTemplateParameters(c.DeclaringModule, c.DeclaringType);
+ c.Flags = TypeFlags.NestedPrivate | TypeFlags.SpecialName | TypeFlags.Sealed;
+ c.Interfaces = new InterfaceList(0);
+ if (this.ThisType != null)
+ {
+ Field f = new Field(c, null, FieldFlags.CompilerControlled | FieldFlags.SpecialName, StandardIds.ThisValue, this.ThisType, null);
+ this.ThisField = f;
+ c.Members.Add(f);
+ }
+ }
+ return c;
+ }
+ }
+ private TypeNodeList CopyMethodTemplateParameters(Module/*!*/ module, TypeNode/*!*/ type)
+ //^ requires this.DeclaringMethod != null;
+ {
+ TypeNodeList methTemplParams = this.DeclaringMethod.TemplateParameters;
+ if (methTemplParams == null || methTemplParams.Count == 0) return null;
+ this.tpDup = new TemplateParameterDuplicator(module, type);
+ return this.tpDup.VisitTypeParameterList(methTemplParams);
+ }
+ private TemplateParameterDuplicator tpDup;
+ private class TemplateParameterDuplicator : Duplicator
+ {
+ public TemplateParameterDuplicator(Module/*!*/ module, TypeNode/*!*/ type)
+ : base(module, type)
+ {
+ }
+
+ public override TypeNode VisitTypeParameter(TypeNode typeParameter)
+ {
+ if (typeParameter == null) return null;
+ TypeNode result = (TypeNode)this.DuplicateFor[typeParameter.UniqueKey];
+ if (result != null) return result;
+ MethodTypeParameter mtp = typeParameter as MethodTypeParameter;
+ if (mtp != null)
+ {
+ TypeParameter tp = new TypeParameter();
+ this.DuplicateFor[typeParameter.UniqueKey] = tp;
+ tp.Name = mtp.Name;
+ tp.Interfaces = this.VisitInterfaceReferenceList(mtp.Interfaces);
+ tp.TypeParameterFlags = mtp.TypeParameterFlags;
+ tp.DeclaringModule = mtp.DeclaringModule;
+ tp.DeclaringMember = this.TargetType;
+ result = tp;
+ }
+ else
+ {
+ MethodClassParameter mcp = typeParameter as MethodClassParameter;
+ if (mcp != null)
+ {
+ ClassParameter cp = new ClassParameter();
+ this.DuplicateFor[typeParameter.UniqueKey] = cp;
+ cp.Name = mcp.Name;
+ cp.BaseClass = (Class)this.VisitTypeReference(mcp.BaseClass);
+ cp.Interfaces = this.VisitInterfaceReferenceList(mcp.Interfaces);
+ cp.TypeParameterFlags = mcp.TypeParameterFlags;
+ cp.DeclaringModule = mcp.DeclaringModule;
+ cp.DeclaringMember = this.TargetType;
+ result = cp;
+ }
+ }
+ if (result == null) return typeParameter;
+ return result;
+ }
+ public override TypeNode VisitTypeReference(TypeNode type)
+ {
+ TypeNode result = base.VisitTypeReference(type);
+ if (result == type && (type is MethodClassParameter || type is MethodTypeParameter))
+ return this.VisitTypeParameter(type);
+ return result;
+ }
+ }
+ public virtual Class ClosureClassTemplateInstance
+ {
+ get
+ {
+ if (this.closureClassTemplateInstance == null)
+ {
+ if (this.DeclaringMethod == null || !this.DeclaringMethod.IsGeneric)
+ this.closureClassTemplateInstance = this.ClosureClass;
+ else
+ this.closureClassTemplateInstance = (Class)this.ClosureClass.GetTemplateInstance(this.DeclaringMethod.DeclaringType, this.DeclaringMethod.TemplateParameters);
+ }
+ return this.closureClassTemplateInstance;
+ }
+ }
+ Class closureClassTemplateInstance;
+ public TypeNode FixTypeReference(TypeNode type)
+ {
+ if (this.tpDup == null) return type;
+ return this.tpDup.VisitTypeReference(type);
+ }
+
+ public virtual Boolean CapturedForClosure
+ {
+ get
+ {
+ return this.closureClass != null;
+ }
+ }
+ public UsedNamespaceList UsedNamespaces;
+ public Field ThisField;
+ public TypeNode ThisType;
+ public TypeNode ThisTypeInstance;
+ public Method DeclaringMethod;
+ public MethodScope() { }
+ public MethodScope(Class/*!*/ parentScope, UsedNamespaceList usedNamespaces)
+ : this(parentScope, usedNamespaces, null)
+ {
+ }
+ public MethodScope(Class/*!*/ parentScope, UsedNamespaceList usedNamespaces, Method method)
+ {
+ this.baseClass = parentScope;
+ this.UsedNamespaces = usedNamespaces;
+ this.DeclaringModule = parentScope.DeclaringModule;
+ this.DeclaringMethod = method;
+ if (method != null && (method.Flags & MethodFlags.Static) == 0)
+ this.ThisType = this.ThisTypeInstance = method.DeclaringType;
+ if (method != null)
+ this.LexicalSourceExtent = method.SourceContext;
+ }
+ }
+ public class BlockScope : Scope
+ {
+ public Block AssociatedBlock;
+ public bool MembersArePinned;
+ public virtual Class ClosureClass
+ {
+ get
+ {
+ BlockScope bscope = this.BaseClass as BlockScope;
+ if (bscope != null) return bscope.ClosureClass;
+ MethodScope mscope = this.BaseClass as MethodScope;
+ if (mscope != null) return mscope.ClosureClass;
+ return ((TypeScope)this.BaseClass).Type as Class;
+ }
+ }
+ public virtual Boolean CapturedForClosure
+ {
+ get
+ {
+ BlockScope bscope = this.BaseClass as BlockScope;
+ if (bscope != null) return bscope.CapturedForClosure;
+ MethodScope mscope = this.BaseClass as MethodScope;
+ if (mscope != null) return mscope.CapturedForClosure;
+ return false;
+ }
+ }
+ public BlockScope()
+ {
+ }
+ public BlockScope(Scope/*!*/ parentScope, Block associatedBlock)
+ {
+ this.AssociatedBlock = associatedBlock;
+ if (associatedBlock != null)
+ {
+ associatedBlock.HasLocals = true; //TODO: set only if there really are locals
+ associatedBlock.Scope = this;
+ }
+ this.baseClass = parentScope;
+ this.DeclaringModule = parentScope.DeclaringModule;
+ if (associatedBlock != null)
+ this.LexicalSourceExtent = associatedBlock.SourceContext;
+ }
+ }
+ public class AttributeScope : Scope
+ {
+ public AttributeNode AssociatedAttribute;
+ public AttributeScope(Scope parentScope, AttributeNode associatedAttribute)
+ {
+ this.AssociatedAttribute = associatedAttribute;
+ this.baseClass = parentScope;
+ if (associatedAttribute != null)
+ this.LexicalSourceExtent = associatedAttribute.SourceContext;
+ }
+ }
+ public class NamespaceScope : Scope
+ {
+ public Namespace AssociatedNamespace;
+ public Module AssociatedModule;
+ public TrivialHashtable AliasedType;
+ public TrivialHashtable AliasedNamespace;
+ protected TrivialHashtable/*!*/ aliasFor = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ typeFor = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ namespaceFor = new TrivialHashtable();
+ protected TrivialHashtable/*!*/ nestedNamespaceFullName = new TrivialHashtable();
+ protected readonly static AliasDefinition/*!*/ noSuchAlias = new AliasDefinition();
+
+ public NamespaceScope()
+ {
+ }
+ public NamespaceScope(Scope outerScope, Namespace associatedNamespace, Module associatedModule)
+ : base(outerScope)
+ {
+ //^ base;
+ this.AssociatedNamespace = associatedNamespace;
+ this.AssociatedModule = associatedModule;
+ this.DeclaringModule = associatedModule; //TODO: make this go away
+ if (associatedNamespace != null)
+ this.LexicalSourceExtent = associatedNamespace.SourceContext;
+ }
+ public virtual AliasDefinition GetAliasFor(Identifier name)
+ {
+ if (name == null || this.AssociatedNamespace == null || this.AssociatedModule == null || this.aliasFor == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ AliasDefinition alias = (AliasDefinition)this.aliasFor[name.UniqueIdKey];
+ if (alias == noSuchAlias) return null;
+ if (alias != null) return alias;
+ //Check if there is an alias with this uri
+ Scope scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null)
+ {
+ AliasDefinitionList aliases = nsScope.AssociatedNamespace.AliasDefinitions;
+ if (aliases != null)
+ for (int i = 0, n = aliases.Count; i < n; i++)
+ {
+ AliasDefinition aliasDef = aliases[i];
+ if (aliasDef == null || aliasDef.Alias == null) continue;
+ if (aliasDef.Alias.UniqueIdKey == name.UniqueIdKey) { alias = aliasDef; goto done; }
+ }
+ }
+ scope = scope.OuterScope;
+ }
+ done:
+ if (alias != null)
+ this.aliasFor[name.UniqueIdKey] = alias;
+ else
+ this.aliasFor[name.UniqueIdKey] = noSuchAlias;
+ return alias;
+ }
+ public virtual AliasDefinition GetConflictingAlias(Identifier name)
+ {
+ if (name == null || this.typeFor == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ TypeNode type = this.AssociatedModule.GetType(this.AssociatedNamespace.FullNameId, name);
+ if (type != null)
+ {
+ AliasDefinitionList aliases = this.AssociatedNamespace.AliasDefinitions;
+ for (int i = 0, n = aliases == null ? 0 : aliases.Count; i < n; i++)
+ {
+ //^ assert aliases != null;
+ AliasDefinition aliasDef = aliases[i];
+ if (aliasDef == null || aliasDef.Alias == null) continue;
+ if (aliasDef.Alias.UniqueIdKey == name.UniqueIdKey) return aliasDef;
+ }
+ }
+ Scope scope = this;
+ while (scope != null)
+ {
+ NamespaceScope outerScope = scope.OuterScope as NamespaceScope;
+ if (outerScope != null) return outerScope.GetConflictingAlias(name);
+ scope = scope.OuterScope;
+ }
+ return null;
+ }
+ public virtual Identifier GetUriFor(Identifier name)
+ {
+ AliasDefinition aliasDef = this.GetAliasFor(name);
+ if (aliasDef == null) return null;
+ return aliasDef.AliasedUri;
+ }
+ public virtual Identifier GetNamespaceFullNameFor(Identifier name)
+ {
+ if (name == null || this.AssociatedNamespace == null || this.AssociatedModule == null || this.nestedNamespaceFullName == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ Identifier fullName = (Identifier)this.nestedNamespaceFullName[name.UniqueIdKey];
+ if (fullName == Identifier.Empty) return null;
+ if (fullName != null) return fullName;
+ //Check if there is an alias with this namespace
+ AliasDefinition aliasDef = this.GetAliasFor(name);
+ if (aliasDef != null && aliasDef.AliasedUri == null && aliasDef.AliasedType == null)
+ return aliasDef.AliasedExpression as Identifier;
+ //Check if module has a type with namespace equal to this namespace + name
+ fullName = name;
+ if (this.AssociatedNamespace.Name != null && this.AssociatedNamespace.Name.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ fullName = Identifier.For(this.AssociatedNamespace.FullName + "." + name);
+ if (this.AssociatedModule.IsValidNamespace(fullName))
+ {
+ this.namespaceFor[fullName.UniqueIdKey] = new TrivialHashtable();
+ goto returnFullName;
+ }
+ // If an inner type shadows an outer namespace, don't return the namespace
+ if (this.AssociatedModule.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
+ AssemblyReferenceList arefs = this.AssociatedModule.AssemblyReferences;
+ for (int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
+ {
+ AssemblyReference ar = arefs[i];
+ if (ar == null || ar.Assembly == null) continue;
+ if (ar.Assembly.IsValidNamespace(fullName)) goto returnFullName;
+ // If an inner type shadows an outer namespace, don't return the namespace
+ if (ar.Assembly.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
+ }
+ ModuleReferenceList mrefs = this.AssociatedModule.ModuleReferences;
+ if (mrefs != null)
+ for (int i = 0, n = mrefs.Count; i < n; i++)
+ {
+ ModuleReference mr = mrefs[i];
+ if (mr == null || mr.Module == null) continue;
+ if (mr.Module.IsValidNamespace(fullName)) goto returnFullName;
+ // If an inner type shadows an outer namespace, don't return the namespace
+ if (mr.Module.IsValidTypeName(this.AssociatedNamespace.Name, name)) { return null; }
+ }
+ Scope scope = this.OuterScope;
+ while (scope != null && !(scope is NamespaceScope)) scope = scope.OuterScope;
+ if (scope != null) return ((NamespaceScope)scope).GetNamespaceFullNameFor(name);
+ return null;
+ returnFullName:
+ this.nestedNamespaceFullName[name.UniqueIdKey] = fullName;
+ return fullName;
+ }
+ /// <summary>
+ /// Search this namespace for a type with this name nested in the given namespace. Also considers used name spaces.
+ /// If more than one type is found, a list is returned in duplicates.
+ /// </summary>
+ public virtual TypeNode GetType(Identifier Namespace, Identifier name, out TypeNodeList duplicates)
+ {
+ duplicates = null;
+ if (Namespace == null || name == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ if (this.namespaceFor == null)
+ {
+ Debug.Assert(false);
+ this.namespaceFor = new TrivialHashtable();
+ }
+ TrivialHashtable typeFor = (TrivialHashtable)this.namespaceFor[Namespace.UniqueIdKey];
+ if (typeFor == null) this.namespaceFor[Namespace.UniqueIdKey] = typeFor = new TrivialHashtable();
+ TypeNode result = (TypeNode)typeFor[name.UniqueIdKey];
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ //If the associated module declares a type with the given name in a nested namespace, it wins
+ Scope scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null)
+ {
+ Identifier nestedNamespace = Namespace;
+ if (nsScope.AssociatedNamespace.FullNameId != null && nsScope.AssociatedNamespace.FullNameId.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ nestedNamespace = Identifier.For(nsScope.AssociatedNamespace.FullName + "." + Namespace);
+ result = this.AssociatedModule.GetType(nestedNamespace, name);
+ if (result != null) break;
+ }
+ scope = scope.OuterScope;
+ }
+ if (result == null)
+ {
+ //Now get into situations where there might be duplicates.
+ duplicates = new TypeNodeList();
+ //Check the used namespaces of this and outer namespace scopes
+ TrivialHashtable alreadyUsed = new TrivialHashtable();
+ scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null)
+ {
+ UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
+ int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
+ if (usedNamespaces != null)
+ for (int i = 0; i < n; i++)
+ {
+ UsedNamespace usedNs = usedNamespaces[i];
+ if (usedNs == null || usedNs.Namespace == null) continue;
+ int key = usedNs.Namespace.UniqueIdKey;
+ if (alreadyUsed[key] != null) continue;
+ alreadyUsed[key] = usedNs.Namespace;
+ Identifier usedNestedNamespace = Identifier.For(usedNs.Namespace + "." + Namespace);
+ result = this.AssociatedModule.GetType(usedNestedNamespace, name);
+ if (result != null) duplicates.Add(result);
+ }
+ }
+ scope = scope.OuterScope;
+ }
+ if (duplicates.Count > 0) result = duplicates[0];
+ }
+ if (result == null)
+ {
+ //The associated module does not have a type by this name, so check its referenced modules and assemblies
+ int numDups = 0;
+ //Check this namespace and outer namespaces
+ scope = this;
+ while (scope != null && result == null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null)
+ {
+ Identifier nestedNamespace = Namespace;
+ if (nsScope.AssociatedNamespace.FullNameId != null && nsScope.AssociatedNamespace.FullNameId.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ nestedNamespace = Identifier.For(nsScope.AssociatedNamespace.FullName + "." + Namespace);
+ nsScope.GetReferencedTypes(nestedNamespace, name, duplicates);
+ numDups = duplicates.Count;
+ for (int i = numDups - 1; i >= 0; i--)
+ {
+ TypeNode dup = duplicates[i];
+ if (dup == null || !dup.IsPublic) numDups--;
+ result = dup;
+ }
+ }
+ scope = scope.OuterScope;
+ }
+ if (numDups == 0)
+ {
+ if (duplicates.Count > 0) duplicates = new TypeNodeList();
+ //Check the used namespaces of this and outer namespace scopes
+ TrivialHashtable alreadyUsed = new TrivialHashtable();
+ scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null)
+ {
+ UsedNamespaceList usedNamespaces = this.AssociatedNamespace.UsedNamespaces;
+ int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
+ if (usedNamespaces != null)
+ for (int i = 0; i < n; i++)
+ {
+ UsedNamespace usedNs = usedNamespaces[i];
+ if (usedNs == null) continue;
+ int key = usedNs.Namespace.UniqueIdKey;
+ if (alreadyUsed[key] != null) continue;
+ alreadyUsed[key] = usedNs.Namespace;
+ Identifier usedNestedNamespace = Identifier.For(usedNs.Namespace + "." + Namespace);
+ this.GetReferencedTypes(usedNestedNamespace, name, duplicates);
+ }
+ }
+ scope = scope.OuterScope;
+ }
+ numDups = duplicates.Count;
+ for (int i = numDups - 1; i >= 0; i--)
+ {
+ TypeNode dup = duplicates[i];
+ if (dup == null || !dup.IsPublic) numDups--;
+ result = dup;
+ }
+ }
+ if (numDups <= 1) duplicates = null;
+ }
+ if (result == null)
+ typeFor[name.UniqueIdKey] = Class.DoesNotExist;
+ else
+ typeFor[name.UniqueIdKey] = result;
+ return result;
+ }
+ /// <summary>
+ /// Searches this namespace for a type with this name. Also considers aliases and used name spaces, including those of outer namespaces.
+ /// If more than one type is found, a list is returned in duplicates. Types defined in the associated
+ /// module mask types defined in referenced modules and assemblies. Results are cached and duplicates are returned only when
+ /// there is a cache miss.
+ /// </summary>
+ public virtual TypeNode GetType(Identifier name, out TypeNodeList duplicates)
+ {
+ return this.GetType(name, out duplicates, false);
+ }
+ public virtual TypeNode GetType(Identifier name, out TypeNodeList duplicates, bool returnNullIfHiddenByNestedNamespace)
+ {
+ duplicates = null;
+ if (name == null || this.typeFor == null || this.AssociatedNamespace == null || this.AssociatedModule == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ AssemblyNode associatedAssembly = this.AssociatedModule as AssemblyNode;
+ TypeNode result = (TypeNode)this.typeFor[name.UniqueIdKey];
+ if (result == Class.DoesNotExist) return null;
+ if (result != null) return result;
+ //If the associated module declares a type with the given name in this namespace, it wins
+ result = this.AssociatedModule.GetType(this.AssociatedNamespace.FullNameId, name);
+ if (result == null && returnNullIfHiddenByNestedNamespace)
+ {
+ //Do not proceed to outer namespaces or look at aliases. The nested namespace hides these.
+ Identifier fullName = name;
+ if (this.AssociatedNamespace.FullName != null && this.AssociatedNamespace.Name.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ fullName = Identifier.For(this.AssociatedNamespace.FullName + "." + name);
+ if (this.AssociatedModule.IsValidNamespace(fullName))
+ result = Class.DoesNotExist;
+ }
+ if (result == null)
+ {
+ //If the namespace (or an outer namespace) has an alias definition with this name it wins. (Expected to be mutually exclusive with above.)
+ Scope scope = this;
+ while (scope != null && result == null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AliasedType != null)
+ result = (TypeNode)nsScope.AliasedType[name.UniqueIdKey];
+ if (result == null && returnNullIfHiddenByNestedNamespace && nsScope != null &&
+ nsScope.AliasedNamespace != null && nsScope.AliasedNamespace[name.UniqueIdKey] != null)
+ result = Class.DoesNotExist;
+ scope = scope.OuterScope;
+ }
+ }
+ if (result == null)
+ {
+ //Now get into situations where there might be duplicates.
+ duplicates = new TypeNodeList();
+ //Check the used namespaces of this and outer namespace scopes
+ TrivialHashtable alreadyUsed = new TrivialHashtable();
+ Scope scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null && nsScope.AssociatedNamespace != null && nsScope.AssociatedModule != null)
+ {
+ UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
+ int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
+ if (usedNamespaces != null)
+ for (int i = 0; i < n; i++)
+ {
+ UsedNamespace usedNs = usedNamespaces[i];
+ if (usedNs == null || usedNs.Namespace == null) continue;
+ int key = usedNs.Namespace.UniqueIdKey;
+ if (alreadyUsed[key] != null) continue;
+ alreadyUsed[key] = usedNs.Namespace;
+ result = this.AssociatedModule.GetType(usedNs.Namespace, name);
+ //^ assert duplicates != null;
+ if (result != null) duplicates.Add(result);
+ }
+ }
+ if (returnNullIfHiddenByNestedNamespace) break;
+ scope = scope.OuterScope;
+ }
+ if (duplicates.Count > 0) result = duplicates[0];
+ }
+ if (result == null)
+ //First see if the the current module has a class by this name in the empty namespace
+ result = this.AssociatedModule.GetType(Identifier.Empty, name);
+ if (result == null)
+ {
+ //The associated module does not have a type by this name, so check its referenced modules and assemblies
+ //First check this namespace
+ this.GetReferencedTypes(this.AssociatedNamespace.FullNameId, name, duplicates);
+ int numDups = duplicates.Count;
+ if (numDups == 1)
+ {
+ result = duplicates[0];
+ if (this.IsNotAccessible(associatedAssembly, result)) { numDups--; result = null; }
+ }
+ else
+ {
+ for (int i = numDups - 1; i >= 0; i--)
+ {
+ TypeNode dup = duplicates[i];
+ if (this.IsNotAccessible(associatedAssembly, dup)) { numDups--; continue; }
+ result = dup;
+ }
+ if (numDups == 0 && duplicates.Count > 0)
+ {
+ result = duplicates[0];
+ numDups = duplicates.Count;
+ }
+ }
+ if (numDups == 0)
+ {
+ if (duplicates.Count > 0) duplicates = new TypeNodeList();
+ //Check the used namespaces of this and outer namespace scopes
+ TrivialHashtable alreadyUsed = new TrivialHashtable();
+ Scope scope = this;
+ while (scope != null)
+ {
+ NamespaceScope nsScope = scope as NamespaceScope;
+ if (nsScope != null)
+ {
+ UsedNamespaceList usedNamespaces = nsScope.AssociatedNamespace.UsedNamespaces;
+ int n = usedNamespaces == null ? 0 : usedNamespaces.Count;
+ if (usedNamespaces != null)
+ for (int i = 0; i < n; i++)
+ {
+ UsedNamespace usedNs = usedNamespaces[i];
+ if (usedNs == null || usedNs.Namespace == null) continue;
+ int key = usedNs.Namespace.UniqueIdKey;
+ if (alreadyUsed[key] != null) continue;
+ alreadyUsed[key] = usedNs.Namespace;
+ this.GetReferencedTypes(usedNs.Namespace, name, duplicates);
+ }
+ }
+ scope = scope.OuterScope;
+ if (returnNullIfHiddenByNestedNamespace) break;
+ }
+ numDups = duplicates.Count;
+ for (int i = numDups - 1; i >= 0; i--)
+ {
+ TypeNode dup = duplicates[i];
+ if (this.IsNotAccessible(associatedAssembly, dup))
+ {
+ numDups--; continue;
+ }
+ result = dup;
+ }
+ }
+ if (numDups == 0)
+ {
+ if (duplicates.Count > 0) duplicates = new TypeNodeList();
+ this.GetReferencedTypes(Identifier.Empty, name, duplicates);
+ numDups = duplicates.Count;
+ for (int i = numDups - 1; i >= 0; i--)
+ {
+ TypeNode dup = duplicates[i];
+ if (this.IsNotAccessible(associatedAssembly, dup))
+ {
+ numDups--; continue;
+ }
+ result = dup;
+ }
+ }
+ if (numDups <= 1) duplicates = null;
+ }
+ if (result == null)
+ this.typeFor[name.UniqueIdKey] = Class.DoesNotExist;
+ else
+ this.typeFor[name.UniqueIdKey] = result;
+ if (result == Class.DoesNotExist) return null;
+ if (duplicates != null && duplicates.Count > 1 && this.AssociatedNamespace != null && this.AssociatedNamespace.Name != null && this.AssociatedNamespace.Name.Name != null)
+ {
+ result = null;
+ for (int i = 0, n = duplicates.Count; i < n; i++)
+ {
+ TypeNode t = duplicates[i];
+ if (t == null || t.Namespace == null) continue;
+ if (this.AssociatedNamespace.Name.Name.StartsWith(t.Namespace.Name))
+ {
+ if (result != null)
+ {
+ result = null;
+ break;
+ }
+ result = t;
+ }
+ }
+ if (result != null)
+ duplicates = null;
+ else
+ result = duplicates[0];
+ }
+ return result;
+ }
+ private bool IsNotAccessible(AssemblyNode associatedAssembly, TypeNode dup)
+ {
+ if (dup == null) return false;
+ return !dup.IsPublic && (associatedAssembly == null ||
+ !associatedAssembly.MayAccessInternalTypesOf(dup.DeclaringModule as AssemblyNode)) && !this.AssociatedModule.ContainsModule(dup.DeclaringModule);
+ }
+ /// <summary>
+ /// Searches the module and assembly references of the associated module to find types
+ /// </summary>
+ public virtual void GetReferencedTypes(Identifier Namespace, Identifier name, TypeNodeList types)
+ {
+ if (Namespace == null || name == null || types == null || this.AssociatedModule == null) { Debug.Assert(false); return; }
+ AssemblyReferenceList arefs = this.AssociatedModule.AssemblyReferences;
+ for (int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
+ {
+ AssemblyReference ar = arefs[i];
+ if (ar == null || ar.Assembly == null) continue;
+ TypeNode t = ar.Assembly.GetType(Namespace, name);
+ if (t == null) continue;
+ //TODO: deal with type forwarding
+ types.Add(t);
+ }
+ ModuleReferenceList mrefs = this.AssociatedModule.ModuleReferences;
+ if (mrefs != null)
+ for (int i = 0, n = mrefs.Count; i < n; i++)
+ {
+ ModuleReference mr = mrefs[i];
+ if (mr == null || mr.Module == null) continue;
+ TypeNode t = mr.Module.GetType(Namespace, name);
+ if (t == null) continue;
+ types.Add(t);
+ }
+ }
+ }
+#endif
+ public class DelegateNode : TypeNode
+ {
+ internal static readonly DelegateNode/*!*/ Dummy = new DelegateNode();
+ protected ParameterList parameters;
+ public virtual ParameterList Parameters
+ {
+ get
+ {
+ ParameterList pList = this.parameters;
+ if (pList == null)
+ {
+ MemberList members = this.Members; //Evaluate for side effect
+ if (members != null) members = null;
+ lock (this)
+ {
+ if (this.parameters != null) return this.parameters;
+ MemberList invokers = this.GetMembersNamed(StandardIds.Invoke);
+ for (int i = 0, n = invokers.Count; i < n; i++)
+ {
+ Method m = invokers[i] as Method;
+ if (m == null) continue;
+ this.parameters = pList = m.Parameters;
+ this.returnType = m.ReturnType;
+ break;
+ }
+ }
+ }
+ return pList;
+ }
+ set
+ {
+ this.parameters = value;
+ }
+ }
+ protected TypeNode returnType;
+ public virtual TypeNode ReturnType
+ {
+ get
+ {
+ TypeNode rt = this.returnType;
+ if (rt == null)
+ {
+ ParameterList pars = this.Parameters; //Evaluate for side effect
+ if (pars != null) pars = null;
+ rt = this.returnType;
+ }
+ return rt;
+ }
+ set
+ {
+ this.returnType = value;
+ }
+ }
+#if !MinimalReader
+ public TypeNode ReturnTypeExpression;
+#endif
+ public DelegateNode()
+ : base(NodeType.DelegateNode)
+ {
+ }
+ public DelegateNode(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.DelegateNode, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ }
+#if !MinimalReader
+ public DelegateNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
+ Identifier Namespace, Identifier name, TypeNode returnType, ParameterList parameters)
+ : base(declaringModule, declaringType, attributes, flags, Namespace, name, null, null, NodeType.DelegateNode)
+ {
+ this.parameters = parameters;
+ this.returnType = returnType;
+ }
+ private bool membersAlreadyProvided;
+ public virtual void ProvideMembers()
+ {
+ if (this.membersAlreadyProvided) return;
+ this.membersAlreadyProvided = true;
+ this.memberCount = 0;
+ MemberList members = this.members = new MemberList();
+ //ctor
+ ParameterList parameters = new ParameterList(2);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Method, CoreSystemTypes.IntPtr, null, null));
+ InstanceInitializer ctor = new InstanceInitializer(this, null, parameters, null);
+ ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;
+ ctor.CallingConvention = CallingConventionFlags.HasThis;
+ ctor.ImplFlags = MethodImplFlags.Runtime;
+ members.Add(ctor);
+ //Invoke
+ Method invoke = new Method(this, null, StandardIds.Invoke, this.Parameters, this.ReturnType, null);
+ invoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual;
+ invoke.CallingConvention = CallingConventionFlags.HasThis;
+ invoke.ImplFlags = MethodImplFlags.Runtime;
+ members.Add(invoke);
+ //BeginInvoke
+ ParameterList dparams = this.parameters;
+ int n = dparams == null ? 0 : dparams.Count;
+ parameters = new ParameterList(n + 2);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert dparams != null;
+ Parameter p = dparams[i];
+ if (p == null) continue;
+ parameters.Add((Parameter)p.Clone());
+ }
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.callback, SystemTypes.AsyncCallback, null, null));
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));
+ Method beginInvoke = new Method(this, null, StandardIds.BeginInvoke, parameters, SystemTypes.IASyncResult, null);
+ beginInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
+ beginInvoke.CallingConvention = CallingConventionFlags.HasThis;
+ beginInvoke.ImplFlags = MethodImplFlags.Runtime;
+ members.Add(beginInvoke);
+ //EndInvoke
+ parameters = new ParameterList(1);
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = dparams[i];
+ if (p == null || p.Type == null || !(p.Type is Reference)) continue;
+ parameters.Add((Parameter)p.Clone());
+ }
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.result, SystemTypes.IASyncResult, null, null));
+ Method endInvoke = new Method(this, null, StandardIds.EndInvoke, parameters, this.ReturnType, null);
+ endInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
+ endInvoke.CallingConvention = CallingConventionFlags.HasThis;
+ endInvoke.ImplFlags = MethodImplFlags.Runtime;
+ members.Add(endInvoke);
+ if (!this.IsGeneric)
+ {
+ TypeNodeList templPars = this.TemplateParameters;
+ for (int i = 0, m = templPars == null ? 0 : templPars.Count; i < m; i++)
+ {
+ //^ assert templPars != null;
+ TypeNode tpar = templPars[i];
+ if (tpar == null) continue;
+ members.Add(tpar);
+ }
+ }
+ }
+#endif
+ }
+#if !MinimalReader
+ public class FunctionType : DelegateNode
+ {
+ private FunctionType(Identifier name, TypeNode returnType, ParameterList parameters)
+ {
+ this.Flags = TypeFlags.Public | TypeFlags.Sealed;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = name;
+ this.returnType = returnType;
+ this.parameters = parameters;
+ }
+ public static FunctionType For(TypeNode returnType, ParameterList parameters, TypeNode referringType)
+ {
+ if (returnType == null || referringType == null) return null;
+ Module module = referringType.DeclaringModule;
+ if (module == null) return null;
+ TypeFlags visibility = returnType.Flags & TypeFlags.VisibilityMask;
+ StringBuilder name = new StringBuilder();
+ name.Append("Function_");
+ name.Append(returnType.Name.ToString());
+ int n = parameters == null ? 0 : parameters.Count;
+ if (parameters != null)
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = parameters[i];
+ if (p == null || p.Type == null) continue;
+ visibility = TypeNode.GetVisibilityIntersection(visibility, p.Type.Flags & TypeFlags.VisibilityMask);
+ name.Append('_');
+ name.Append(p.Type.Name.ToString());
+ }
+ FunctionType func = null;
+ int count = 0;
+ string fNameString = name.ToString();
+ Identifier fName = Identifier.For(fNameString);
+ TypeNode result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, fName);
+ while (result != null)
+ {
+ //Mangled name is the same. But mangling is not unique (types are not qualified with assemblies), so check for equality.
+ func = result as FunctionType;
+ bool goodMatch = func != null && func.ReturnType == returnType;
+ if (goodMatch)
+ {
+ //^ assert func != null;
+ ParameterList fpars = func.Parameters;
+ int m = fpars == null ? 0 : fpars.Count;
+ goodMatch = n == m;
+ if (parameters != null && fpars != null)
+ for (int i = 0; i < n && goodMatch; i++)
+ {
+ Parameter p = parameters[i];
+ Parameter q = fpars[i];
+ goodMatch = p != null && q != null && p.Type == q.Type;
+ }
+ }
+ if (goodMatch) return func;
+ //Mangle some more
+ fName = Identifier.For(fNameString + (++count).ToString());
+ result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, fName);
+ }
+ if (parameters != null)
+ {
+ ParameterList clonedParams = new ParameterList(n);
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = parameters[i];
+ if (p != null) p = (Parameter)p.Clone();
+ clonedParams.Add(p);
+ }
+ parameters = clonedParams;
+ }
+ func = new FunctionType(fName, returnType, parameters);
+ func.DeclaringModule = module;
+ switch (visibility)
+ {
+ case TypeFlags.NestedFamANDAssem:
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedPrivate:
+ referringType.Members.Add(func);
+ func.DeclaringType = referringType;
+ func.Flags &= ~TypeFlags.VisibilityMask;
+ func.Flags |= TypeFlags.NestedPrivate;
+ break;
+ default:
+ module.Types.Add(func);
+ break;
+ }
+ module.StructurallyEquivalentType[func.Name.UniqueIdKey] = func;
+ func.ProvideMembers();
+ return func;
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList();
+ result.Add(this.ReturnType);
+ ParameterList pars = this.Parameters;
+ for (int i = 0, n = pars == null ? 0 : pars.Count; i < n; i++)
+ {
+ Parameter par = pars[i];
+ if (par == null || par.Type == null) continue;
+ result.Add(par.Type);
+ }
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ FunctionType t = type as FunctionType;
+ if (t == null) return false;
+ if (this.Template != null) return base.IsStructurallyEquivalentTo(t);
+ if (this.Flags != t.Flags) return false;
+ if (this.ReturnType == null || t.ReturnType == null) return false;
+ if (this.ReturnType != t.ReturnType && !this.ReturnType.IsStructurallyEquivalentTo(t.ReturnType)) return false;
+ if (this.Parameters == null) return t.Parameters == null;
+ if (t.Parameters == null) return false;
+ int n = this.Parameters.Count; if (n != t.Parameters.Count) return false;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p1 = this.Parameters[i];
+ Parameter p2 = t.Parameters[i];
+ if (p1 == null || p2 == null) return false;
+ if (p1.Type == null || p2.Type == null) return false;
+ if (p1.Type != p2.Type && !p1.Type.IsStructurallyEquivalentTo(p2.Type)) return false;
+ }
+ return true;
+ }
+ }
+#endif
+ public class EnumNode : TypeNode
+ {
+ internal readonly static EnumNode/*!*/ Dummy = new EnumNode();
+
+ public EnumNode()
+ : base(NodeType.EnumNode)
+ {
+ this.typeCode = ElementType.ValueType;
+ this.Flags |= TypeFlags.Sealed;
+ }
+ public EnumNode(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.EnumNode, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.typeCode = ElementType.ValueType;
+ this.Flags |= TypeFlags.Sealed;
+ }
+#if !MinimalReader
+ public EnumNode(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags typeAttributes,
+ Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members)
+ : base(declaringModule, declaringType, attributes, typeAttributes, Namespace, name, interfaces, members, NodeType.EnumNode)
+ {
+ this.typeCode = ElementType.ValueType;
+ this.Flags |= TypeFlags.Sealed;
+ }
+#endif
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ return true;
+ }
+ }
+ protected internal TypeNode underlyingType;
+ /// <summary>
+ /// The underlying integer type used to store values of this enumeration.
+ /// </summary>
+ public virtual TypeNode UnderlyingType
+ {
+ get
+ {
+ if (this.underlyingType == null)
+ {
+ if (this.template is EnumNode)
+ return this.underlyingType = ((EnumNode)this.template).UnderlyingType;
+ this.underlyingType = CoreSystemTypes.Int32;
+ MemberList members = this.Members;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Member mem = members[i];
+ Field f = mem as Field;
+ if (f != null && (f.Flags & FieldFlags.Static) == 0)
+ return this.underlyingType = f.Type;
+ }
+ }
+ return this.underlyingType;
+ }
+ set
+ {
+ this.underlyingType = value;
+ MemberList members = this.Members;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Member mem = members[i];
+ Field f = mem as Field;
+ if (f != null && (f.Flags & FieldFlags.Static) == 0)
+ {
+ f.Type = value;
+ return;
+ }
+ }
+ this.Members.Add(new Field(this, null, FieldFlags.Public | FieldFlags.SpecialName | FieldFlags.RTSpecialName, StandardIds.Value__, value, null));
+ }
+ }
+#if !MinimalReader
+ public TypeNode UnderlyingTypeExpression;
+#endif
+ }
+#if FxCop
+ public class InterfaceNode : TypeNode{
+#else
+ public class Interface : TypeNode
+ {
+#endif
+ protected TrivialHashtable jointMemberTable;
+ protected MemberList jointDefaultMembers;
+
+ internal static readonly Interface/*!*/ Dummy = new Interface();
+
+#if FxCop
+ public InterfaceNode()
+ : base(NodeType.Interface){
+ this.Flags = TypeFlags.Interface|TypeFlags.Abstract;
+ }
+ public InterfaceNode(InterfaceList baseInterfaces)
+ : base(NodeType.Interface){
+ this.Interfaces = baseInterfaces;
+ this.Flags = TypeFlags.Interface|TypeFlags.Abstract;
+ }
+ public InterfaceNode(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.Interface, provideNestedTypes, provideAttributes, provideMembers, handle){
+ this.Interfaces = baseInterfaces;
+ }
+#else
+ public Interface()
+ : base(NodeType.Interface)
+ {
+ this.Flags = TypeFlags.Interface | TypeFlags.Abstract;
+ }
+ public Interface(InterfaceList baseInterfaces)
+ : base(NodeType.Interface)
+ {
+ this.Interfaces = baseInterfaces;
+ this.Flags = TypeFlags.Interface | TypeFlags.Abstract;
+ }
+ public Interface(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.Interface, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.Interfaces = baseInterfaces;
+ }
+#endif
+#if !MinimalReader
+ public Interface(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
+ Identifier Namespace, Identifier name, InterfaceList baseInterfaces, MemberList members)
+ : base(declaringModule, declaringType, attributes, flags, Namespace, name, baseInterfaces, members, NodeType.Interface)
+ {
+ this.Flags |= TypeFlags.Interface | TypeFlags.Abstract;
+ }
+ public override void GetAbstractMethods(MethodList/*!*/ result)
+ {
+ MemberList members = this.Members;
+ if (members == null) return;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Method m = members[i] as Method;
+ if (m != null) result.Add(m);
+ }
+ }
+ public virtual MemberList GetAllDefaultMembers()
+ {
+ if (this.jointDefaultMembers == null)
+ {
+ this.jointDefaultMembers = new MemberList();
+ MemberList defs = this.DefaultMembers;
+ for (int i = 0, n = defs == null ? 0 : defs.Count; i < n; i++)
+ this.jointDefaultMembers.Add(defs[i]);
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces != null)
+ for (int j = 0, m = interfaces.Count; j < m; j++)
+ {
+ Interface iface = interfaces[j];
+ if (iface == null) continue;
+ defs = iface.GetAllDefaultMembers();
+ if (defs == null) continue;
+ for (int i = 0, n = defs.Count; i < n; i++)
+ this.jointDefaultMembers.Add(defs[i]);
+ }
+ }
+ return this.jointDefaultMembers;
+ }
+ public virtual MemberList GetAllMembersNamed(Identifier/*!*/ name)
+ {
+ lock (this)
+ {
+ TrivialHashtable memberTable = this.jointMemberTable;
+ if (memberTable == null) this.jointMemberTable = memberTable = new TrivialHashtable();
+ MemberList result = (MemberList)memberTable[name.UniqueIdKey];
+ if (result != null) return result;
+ memberTable[name.UniqueIdKey] = result = new MemberList();
+ MemberList members = this.GetMembersNamed(name);
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ result.Add(members[i]);
+ InterfaceList interfaces = this.Interfaces;
+ for (int j = 0, m = interfaces == null ? 0 : interfaces.Count; j < m; j++)
+ {
+ Interface iface = interfaces[j];
+ if (iface == null) continue;
+ members = iface.GetAllMembersNamed(name);
+ if (members != null)
+ for (int i = 0, n = members.Count; i < n; i++)
+ result.Add(members[i]);
+ }
+ members = CoreSystemTypes.Object.GetMembersNamed(name);
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ result.Add(members[i]);
+ return result;
+ }
+ }
+#endif
+ }
+ public class Struct : TypeNode
+ {
+ internal static readonly Struct/*!*/ Dummy = new Struct();
+
+ public Struct()
+ : base(NodeType.Struct)
+ {
+ this.typeCode = ElementType.ValueType;
+ this.Flags = TypeFlags.Sealed;
+ }
+ public Struct(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(NodeType.Struct, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.typeCode = ElementType.ValueType;
+ }
+#if !MinimalReader
+ public Struct(Module declaringModule, TypeNode declaringType, AttributeList attributes, TypeFlags flags,
+ Identifier Namespace, Identifier name, InterfaceList interfaces, MemberList members)
+ : base(declaringModule, declaringType, attributes, flags, Namespace, name, interfaces, members, NodeType.Struct)
+ {
+ this.Interfaces = interfaces;
+ this.typeCode = ElementType.ValueType;
+ this.Flags |= TypeFlags.Sealed;
+ }
+ protected bool cachedUnmanaged;
+ protected bool cachedUnmanagedIsValid;
+ /// <summary>True if the type is a value type containing only fields of unmanaged types.</summary>
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ if (this.cachedUnmanagedIsValid) return this.cachedUnmanaged;
+ this.cachedUnmanagedIsValid = true; //protect against cycles
+ this.cachedUnmanaged = true; //Self references should not influence the answer
+ if (this.IsPrimitive) return this.cachedUnmanaged = true;
+ MemberList members = this.Members;
+ bool isUnmanaged = true;
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ {
+ Field f = members[i] as Field;
+ if (f == null || f.Type == null || f.IsStatic) continue;
+ if (!f.Type.IsUnmanaged) { isUnmanaged = false; break; }
+ }
+ return this.cachedUnmanaged = isUnmanaged;
+ }
+ }
+#endif
+ }
+ public interface ITypeParameter
+ {
+ Member DeclaringMember { get; set; }
+ /// <summary>
+ /// Zero based index into a parameter list containing this parameter.
+ /// </summary>
+ int ParameterListIndex { get; set; }
+ TypeParameterFlags TypeParameterFlags { get; set; }
+ bool IsUnmanaged { get; }
+#if !MinimalReader
+ Identifier Name { get; }
+ Module DeclaringModule { get; }
+ TypeNode DeclaringType { get; }
+ SourceContext SourceContext { get; }
+ int UniqueKey { get; }
+ TypeFlags Flags { get; }
+#endif
+ }
+ public class TypeParameter : Interface, ITypeParameter
+ {
+
+ public TypeParameter()
+ : base()
+ {
+ this.NodeType = NodeType.TypeParameter;
+ this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+ public TypeParameter(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(baseInterfaces, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.NodeType = NodeType.TypeParameter;
+ this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+
+ public Member DeclaringMember
+ {
+ get { return this.declaringMember; }
+ set { this.declaringMember = value; }
+ }
+ private Member declaringMember;
+#if !NoReflection && WHIDBEY
+ public override Type GetRuntimeType()
+ {
+ TypeNode t = this.DeclaringMember as TypeNode;
+ if (t == null) return null;
+ Type rt = t.GetRuntimeType();
+ if (rt == null) return null;
+ System.Type[] typeParameters = rt.GetGenericArguments();
+ if (this.ParameterListIndex >= typeParameters.Length) return null;
+ return typeParameters[this.ParameterListIndex];
+ }
+#endif
+ /// <summary>
+ /// Zero based index into a parameter list containing this parameter.
+ /// </summary>
+ public int ParameterListIndex
+ {
+ get { return this.parameterListIndex; }
+ set { this.parameterListIndex = value; }
+ }
+ private int parameterListIndex;
+#if ExtendedRuntime
+ private bool typeParameterFlagsIsValid = false;
+#endif
+ public TypeParameterFlags TypeParameterFlags
+ {
+ get
+ {
+#if ExtendedRuntime
+ if (!typeParameterFlagsIsValid) {
+ // check if we have the corresponding attribute
+ for (int i=0; i < (this.Attributes == null?0:this.Attributes.Count); i++) {
+ if (this.Attributes[i].Type == SystemTypes.TemplateParameterFlagsAttribute) {
+ Literal lit = this.Attributes[i].Expressions[0] as Literal;
+ if (lit != null && lit.Value is int) {
+ this.typeParameterFlags = (TypeParameterFlags)((int)lit.Value);
+ }
+ break;
+ }
+ }
+ this.typeParameterFlagsIsValid = true;
+ }
+#endif
+ return this.typeParameterFlags;
+ }
+ set
+ {
+ this.typeParameterFlags = value;
+#if ExtendedRuntime
+ this.typeParameterFlagsIsValid = true;
+#endif
+ }
+ }
+ private TypeParameterFlags typeParameterFlags;
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ /// <summary>True if the type serves as a parameter to a type template.</summary>
+ public override bool IsTemplateParameter
+ {
+ get
+ {
+ return true;
+ }
+ }
+ public override bool IsValueType
+ {
+ get
+ {
+ return ((this.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) == TypeParameterFlags.ValueTypeConstraint);
+ }
+ }
+#if ExtendedRuntime
+ public override bool IsReferenceType {
+ get {
+ return ((this.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) == TypeParameterFlags.ReferenceTypeConstraint);
+ }
+ }
+ private bool isUnmanagedIsValid = false;
+ private bool isUnmanaged = false;
+ public override bool IsUnmanaged{
+ get{
+ if (!isUnmanagedIsValid && SystemTypes.UnmanagedStructTemplateParameterAttribute != null){
+ // check if we have the corresponding attribute
+ for (int i=0; i < (this.Attributes == null?0:this.Attributes.Count); i++){
+ AttributeNode attr = this.Attributes[i];
+ if (attr == null) continue;
+ if (attr.Type == SystemTypes.UnmanagedStructTemplateParameterAttribute){
+ isUnmanaged = true;
+ break;
+ }
+ }
+ isUnmanagedIsValid = true;
+ }
+ return isUnmanaged;
+ }
+ }
+ public void SetIsUnmanaged(){
+ this.isUnmanaged = true;
+ this.isUnmanagedIsValid = true;
+ }
+#endif
+#if !NoXml
+ public override XmlNode Documentation
+ {
+ get
+ {
+ if (this.documentation == null && this.declaringMember != null && this.Name != null)
+ {
+ XmlNode parentDoc = this.declaringMember.Documentation;
+ if (parentDoc != null && parentDoc.HasChildNodes)
+ {
+ string myName = this.Name.Name;
+ foreach (XmlNode child in parentDoc.ChildNodes)
+ {
+ if (child.Name == "typeparam" && child.Attributes != null)
+ {
+ foreach (XmlAttribute attr in child.Attributes)
+ {
+ if (attr != null && attr.Name == "name" && attr.Value == myName)
+ return this.documentation = child;
+ }
+ }
+ }
+ }
+ }
+ return this.documentation;
+ }
+ set
+ {
+ this.documentation = value;
+ }
+ }
+ public override string HelpText
+ {
+ get
+ {
+ if (this.helpText == null)
+ {
+ XmlNode doc = this.Documentation;
+ if (doc != null) this.helpText = doc.InnerText;
+ }
+ return this.helpText;
+ }
+ set
+ {
+ this.helpText = value;
+ }
+ }
+#endif
+ protected internal TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList();
+ if (this.BaseType != null) result.Add(this.BaseType);
+ InterfaceList interfaces = this.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ result.Add(iface);
+ }
+ return result;
+ }
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0)
+ {
+ int n = methodTypeParameters == null ? 0 : methodTypeParameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert methodTypeParameters != null;
+ TypeNode mpar = methodTypeParameters[i];
+ if (mpar != this) continue;
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(i);
+ return;
+ }
+ n = typeParameters == null ? 0 : typeParameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode tpar = typeParameters[i];
+ if (tpar != this) continue;
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(i);
+ return;
+ }
+ sb.Append("not found:");
+ }
+ sb.Append(this.FullName);
+ }
+#endif
+ public override string GetFullUnmangledNameWithoutTypeParameters()
+ {
+ return this.GetUnmangledNameWithoutTypeParameters();
+ }
+ public override string GetFullUnmangledNameWithTypeParameters()
+ {
+ return this.GetUnmangledNameWithTypeParameters();
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (null == (object)type) return false;
+ if (this == type) return true;
+ ITypeParameter itype = type as ITypeParameter;
+ if (null == (object)itype) return false;
+ if (this.Name != null && type.Name != null && this.Name.UniqueIdKey != type.Name.UniqueIdKey)
+ {
+ if (this.DeclaringMember == itype.DeclaringMember) return false;
+ }
+ TypeNode bType = this.BaseType;
+ TypeNode tbType = type.BaseType;
+ if (null == (object)bType) bType = CoreSystemTypes.Object;
+ if (null == (object)tbType) tbType = CoreSystemTypes.Object;
+ if (bType != tbType /*&& !bType.IsStructurallyEquivalentTo(tbType)*/) return false;
+ if (this.Interfaces == null) return type.Interfaces == null || type.Interfaces.Count == 0;
+ if (type.Interfaces == null) return this.Interfaces.Count == 0;
+ int n = this.Interfaces.Count; if (n != type.Interfaces.Count) return false;
+ for (int i = 0; i < n; i++)
+ {
+ Interface i1 = this.Interfaces[i];
+ Interface i2 = type.Interfaces[i];
+ if (null == (object)i1 || null == (object)i2) return false;
+ if (i1 != i2 /*&& !i1.IsStructurallyEquivalentTo(i2)*/) return false;
+ }
+ return true;
+ }
+#if !MinimalReader
+ Module ITypeParameter.DeclaringModule { get { return this.DeclaringModule; } }
+ TypeFlags ITypeParameter.Flags { get { return this.Flags; } }
+ SourceContext ITypeParameter.SourceContext { get { return this.SourceContext; } }
+#endif
+#if FxCop
+ internal override void GetName(TypeFormat options, StringBuilder name)
+ {
+ if (options.TypeName == TypeNameFormat.FullyQualified)
+ {
+ TypeFormat typeFormat = options.Clone();
+ typeFormat.TypeName = TypeNameFormat.Short;
+ base.GetName(typeFormat, name);
+ return;
+ }
+ base.GetName(options, name);
+ }
+#endif
+ }
+ public class MethodTypeParameter : TypeParameter
+ {
+ public MethodTypeParameter()
+ : base()
+ {
+ this.NodeType = NodeType.TypeParameter;
+ this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+#if !MinimalReader
+ public MethodTypeParameter(InterfaceList baseInterfaces, NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(baseInterfaces, provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.NodeType = NodeType.TypeParameter;
+ this.Flags = TypeFlags.Interface | TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+#endif
+#if !NoReflection
+#if WHIDBEY
+ public override Type GetRuntimeType()
+ {
+ Method m = this.DeclaringMember as Method;
+ if (m == null) return null;
+ System.Reflection.MethodInfo mi = m.GetMethodInfo();
+ if (mi == null) return null;
+ System.Type[] typeParameters = mi.GetGenericArguments();
+ if (this.ParameterListIndex >= typeParameters.Length) return null;
+ return typeParameters[this.ParameterListIndex];
+ }
+#endif
+#endif
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (object.ReferenceEquals(this, type)) return true;
+ ITypeParameter tp = type as ITypeParameter;
+ if (tp == null) return false;
+ if (this.ParameterListIndex == tp.ParameterListIndex && this.DeclaringMember == tp.DeclaringMember) return true;
+ return base.IsStructurallyEquivalentTo(type as MethodTypeParameter);
+ }
+ }
+ public class ClassParameter : Class, ITypeParameter
+ {
+ protected TrivialHashtable jointMemberTable;
+
+ public ClassParameter()
+ : base()
+ {
+ this.NodeType = NodeType.ClassParameter;
+ this.baseClass = CoreSystemTypes.Object;
+ this.Flags = TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+ public ClassParameter(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle)
+ {
+ this.NodeType = NodeType.ClassParameter;
+ this.baseClass = CoreSystemTypes.Object;
+ this.Flags = TypeFlags.NestedPrivate | TypeFlags.Abstract | TypeFlags.SpecialName;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+
+ public Member DeclaringMember
+ {
+ get { return this.declaringMember; }
+ set { this.declaringMember = value; }
+ }
+ private Member declaringMember;
+#if !MinimalReader
+ public virtual MemberList GetAllMembersNamed(Identifier/*!*/ name)
+ {
+ lock (this)
+ {
+ TrivialHashtable memberTable = this.jointMemberTable;
+ if (memberTable == null) this.jointMemberTable = memberTable = new TrivialHashtable();
+ MemberList result = (MemberList)memberTable[name.UniqueIdKey];
+ if (result != null) return result;
+ memberTable[name.UniqueIdKey] = result = new MemberList();
+ TypeNode t = this;
+ while (t != null)
+ {
+ MemberList members = t.GetMembersNamed(name);
+ if (members != null)
+ for (int i = 0, n = members.Count; i < n; i++)
+ result.Add(members[i]);
+ t = t.BaseType;
+ }
+ InterfaceList interfaces = this.Interfaces;
+ if (interfaces != null)
+ for (int j = 0, m = interfaces.Count; j < m; j++)
+ {
+ Interface iface = interfaces[j];
+ if (iface == null) continue;
+ members = iface.GetAllMembersNamed(name);
+ if (members != null)
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ result.Add(members[i]);
+ }
+ members = CoreSystemTypes.Object.GetMembersNamed(name);
+ if (members != null)
+ for (int i = 0, n = members.Count; i < n; i++)
+ result.Add(members[i]);
+ return result;
+ }
+ }
+#endif
+
+#if !NoReflection && WHIDBEY
+ public override Type GetRuntimeType()
+ {
+ TypeNode t = this.DeclaringMember as TypeNode;
+ if (t == null) return null;
+ Type rt = t.GetRuntimeType();
+ if (rt == null) return null;
+ System.Type[] typeParameters = rt.GetGenericArguments();
+ if (this.ParameterListIndex >= typeParameters.Length) return null;
+ return typeParameters[this.ParameterListIndex];
+ }
+#endif
+
+ /// <summary>
+ /// Zero based index into a parameter list containing this parameter.
+ /// </summary>
+ public int ParameterListIndex
+ {
+ get { return this.parameterListIndex; }
+ set { this.parameterListIndex = value; }
+ }
+ private int parameterListIndex;
+ public TypeParameterFlags TypeParameterFlags
+ {
+ get { return this.typeParameterFlags; }
+ set { this.typeParameterFlags = value; }
+ }
+ private TypeParameterFlags typeParameterFlags;
+ public override bool IsValueType
+ {
+ get
+ {
+ return ((this.typeParameterFlags & TypeParameterFlags.SpecialConstraintMask) == TypeParameterFlags.ValueTypeConstraint);
+ }
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ /// <summary>True if the type serves as a parameter to a type template.</summary>
+ public override bool IsTemplateParameter
+ {
+ get
+ {
+ return true;
+ }
+ }
+#if ExtendedRuntime
+ public override bool IsReferenceType {
+ get {
+ return ((this.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) == TypeParameterFlags.ReferenceTypeConstraint)
+ || (this.baseClass != null && this.baseClass.IsReferenceType);
+ }
+ }
+ private bool isUnmanagedIsValid = false;
+ private bool isUnmanaged = false;
+ public override bool IsUnmanaged{
+ get{
+ if (!isUnmanagedIsValid && SystemTypes.UnmanagedStructTemplateParameterAttribute != null){
+ // check if we have the corresponding attribute
+ for (int i=0; i < (this.Attributes == null?0:this.Attributes.Count); i++){
+ if (this.Attributes[i].Type == SystemTypes.UnmanagedStructTemplateParameterAttribute){
+ isUnmanaged = true;
+ break;
+ }
+ }
+ isUnmanagedIsValid = true;
+ }
+ return isUnmanaged;
+ }
+ }
+ public void SetIsUnmanaged(){
+ this.isUnmanaged = true;
+ this.isUnmanagedIsValid = true;
+ }
+#endif
+#if !NoXml
+ public override XmlNode Documentation
+ {
+ get
+ {
+ if (this.documentation == null && this.declaringMember != null && this.Name != null)
+ {
+ XmlNode parentDoc = this.declaringMember.Documentation;
+ if (parentDoc != null && parentDoc.HasChildNodes)
+ {
+ string myName = this.Name.Name;
+ foreach (XmlNode child in parentDoc.ChildNodes)
+ {
+ if (child.Name == "typeparam" && child.Attributes != null)
+ {
+ foreach (XmlAttribute attr in child.Attributes)
+ {
+ if (attr != null && attr.Name == "name" && attr.Value == myName)
+ return this.documentation = child;
+ }
+ }
+ }
+ }
+ }
+ return this.documentation;
+ }
+ set
+ {
+ this.documentation = value;
+ }
+ }
+ public override string HelpText
+ {
+ get
+ {
+ if (this.helpText == null)
+ {
+ XmlNode doc = this.Documentation;
+ if (doc != null) this.helpText = doc.InnerText;
+ }
+ return this.helpText;
+ }
+ set
+ {
+ this.helpText = value;
+ }
+ }
+#endif
+ protected internal TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList();
+ if (this.BaseType != null) result.Add(this.BaseType);
+ InterfaceList interfaces = this.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ Interface iface = interfaces[i];
+ if (iface == null) continue;
+ result.Add(iface);
+ }
+ return result;
+ }
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0)
+ {
+ int n = methodTypeParameters == null ? 0 : methodTypeParameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert methodTypeParameters != null;
+ TypeNode mpar = methodTypeParameters[i];
+ if (mpar != this) continue;
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(i);
+ return;
+ }
+ n = typeParameters == null ? 0 : typeParameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode tpar = typeParameters[i];
+ if (tpar != this) continue;
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(i);
+ return;
+ }
+ sb.Append("not found:");
+ }
+ sb.Append(this.FullName);
+ }
+#endif
+ public override string GetFullUnmangledNameWithoutTypeParameters()
+ {
+ return this.GetUnmangledNameWithoutTypeParameters();
+ }
+ public override string GetFullUnmangledNameWithTypeParameters()
+ {
+ return this.GetUnmangledNameWithTypeParameters();
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (null == (object)type) return false;
+ if (this == type) return true;
+ ITypeParameter itype = type as ITypeParameter;
+ if (null == (object)itype) return false;
+ if (this.Name != null && type.Name != null && this.Name.UniqueIdKey != type.Name.UniqueIdKey)
+ {
+ if (this.DeclaringMember == itype.DeclaringMember) return false;
+ }
+ TypeNode bType = this.BaseType;
+ TypeNode tbType = type.BaseType;
+ if (null == (object)bType) bType = CoreSystemTypes.Object;
+ if (null == (object)tbType) tbType = CoreSystemTypes.Object;
+ if (bType != tbType /*&& !bType.IsStructurallyEquivalentTo(tbType)*/) return false;
+ if (this.Interfaces == null) return type.Interfaces == null || type.Interfaces.Count == 0;
+ if (type.Interfaces == null) return this.Interfaces.Count == 0;
+ int n = this.Interfaces.Count; if (n != type.Interfaces.Count) return false;
+ for (int i = 0; i < n; i++)
+ {
+ Interface i1 = this.Interfaces[i];
+ Interface i2 = type.Interfaces[i];
+ if (null == (object)i1 || null == (object)i2) return false;
+ if (i1 != i2 /*&& !i1.IsStructurallyEquivalentTo(i2)*/) return false;
+ }
+ return true;
+ }
+#if !MinimalReader
+ SourceContext ITypeParameter.SourceContext { get { return this.SourceContext; } }
+ Module ITypeParameter.DeclaringModule { get { return this.DeclaringModule; } }
+ TypeFlags ITypeParameter.Flags { get { return this.Flags; } }
+#endif
+#if FxCop
+ internal override void GetName(TypeFormat options, StringBuilder name)
+ {
+ if (options.TypeName == TypeNameFormat.FullyQualified)
+ {
+ TypeFormat typeFormat = options.Clone();
+ typeFormat.TypeName = TypeNameFormat.Short;
+ base.GetName(typeFormat, name);
+ return;
+ }
+ base.GetName(options, name);
+ }
+#endif
+ }
+ public class MethodClassParameter : ClassParameter
+ {
+ public MethodClassParameter()
+ : base()
+ {
+ this.NodeType = NodeType.ClassParameter;
+ this.baseClass = CoreSystemTypes.Object;
+ this.Flags = TypeFlags.NestedPublic | TypeFlags.Abstract;
+ this.Namespace = StandardIds.TypeParameter;
+ }
+#if !NoReflection && WHIDBEY
+ public override Type GetRuntimeType()
+ {
+ Method m = this.DeclaringMember as Method;
+ if (m == null) return null;
+ System.Reflection.MethodInfo mi = m.GetMethodInfo();
+ if (mi == null) return null;
+ System.Type[] typeParameters = mi.GetGenericArguments();
+ if (this.ParameterListIndex >= typeParameters.Length) return null;
+ return typeParameters[this.ParameterListIndex];
+ }
+#endif
+#if !MinimalReader
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (object.ReferenceEquals(this, type)) return true;
+ ITypeParameter tp = type as ITypeParameter;
+ if (tp == null) return false;
+ if (this.ParameterListIndex == tp.ParameterListIndex /* && this.DeclaringMember == tp.DeclaringMember*/) return true;
+ return base.IsStructurallyEquivalentTo(type as MethodClassParameter);
+ }
+#endif
+ }
+ public class ArrayType : TypeNode
+ {
+ private TypeNode/*!*/ elementType;
+ private int rank;
+ private int[] lowerBounds;
+ private int[] sizes;
+ internal ArrayType()
+ : base(NodeType.ArrayType)
+ {
+ }
+ internal ArrayType(TypeNode/*!*/ elementType, int rank)
+ : this(elementType, rank, new int[0], new int[0])
+ {
+ if (rank == 1)
+ this.typeCode = Metadata.ElementType.SzArray;
+ else
+ this.typeCode = Metadata.ElementType.Array;
+ }
+ internal ArrayType(TypeNode/*!*/ elementType, int rank, int[] sizes)
+ : this(elementType, rank, sizes, new int[0])
+ {
+ }
+ internal ArrayType(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds)
+ : base(null, null, null, elementType.Flags, null, null, null, null, NodeType.ArrayType)
+ {
+ Debug.Assert(elementType != null);
+ this.rank = rank;
+ this.elementType = elementType;
+ this.DeclaringModule = elementType.DeclaringModule;
+ this.lowerBounds = lowerBounds;
+ this.sizes = sizes;
+ if (rank == 1)
+ this.typeCode = Metadata.ElementType.SzArray;
+ else
+ this.typeCode = Metadata.ElementType.Array;
+ if (elementType == null || elementType.Name == null) return;
+ StringBuilder name = new StringBuilder(this.ElementType.Name.ToString());
+#if FxCop
+ GetNameSuffix(name, false);
+#else
+ name.Append('[');
+ int k = this.Sizes == null ? 0 : this.Sizes.Length;
+ int m = this.LowerBounds == null ? 0 : this.LowerBounds.Length;
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ if (i < k && this.Sizes[i] != 0)
+ {
+ if (i < m && this.LowerBounds[i] != 0)
+ {
+ name.Append(this.LowerBounds[i]);
+ name.Append(':');
+ }
+ name.Append(this.Sizes[i]);
+ }
+ if (i < n - 1)
+ name.Append(',');
+ }
+ name.Append(']');
+#endif
+ this.Name = Identifier.For(name.ToString());
+ this.Namespace = elementType.Namespace;
+ }
+ public TypeNode/*!*/ ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+ /// <summary>The interfaces implemented by this class or struct, or the extended by this interface.</summary>
+ public override InterfaceList Interfaces
+ {
+ get
+ {
+ if (this.interfaces == null)
+ {
+ InterfaceList interfaces = new InterfaceList(SystemTypes.ICloneable, SystemTypes.IList, SystemTypes.ICollection, SystemTypes.IEnumerable);
+ if (this.Rank == 1)
+ {
+ if (SystemTypes.GenericIEnumerable != null && SystemTypes.GenericIEnumerable.DeclaringModule == CoreSystemTypes.SystemAssembly)
+ {
+ interfaces.Add((Interface)SystemTypes.GenericIEnumerable.GetTemplateInstance(this, elementType));
+ if (SystemTypes.GenericICollection != null)
+ interfaces.Add((Interface)SystemTypes.GenericICollection.GetTemplateInstance(this, elementType));
+ if (SystemTypes.GenericIList != null)
+ interfaces.Add((Interface)SystemTypes.GenericIList.GetTemplateInstance(this, elementType));
+ }
+ }
+ this.interfaces = interfaces;
+ }
+ return this.interfaces;
+ }
+ set { this.interfaces = value; }
+ }
+ public int Rank
+ {
+ get { return this.rank; }
+ set { this.rank = value; }
+ }
+ public int[] LowerBounds
+ {
+ get { return this.lowerBounds; }
+ set { this.lowerBounds = value; }
+ }
+ public int[] Sizes
+ {
+ get { return this.sizes; }
+ set { this.sizes = value; }
+ }
+ public bool IsSzArray()
+ {
+ return this.typeCode == Metadata.ElementType.SzArray;
+ }
+ private MemberList ctorList = null;
+ private MemberList getterList = null;
+ private MemberList setterList = null;
+ private MemberList addressList = null;
+ public override MemberList Members
+ {
+ get
+ {
+ if (this.members == null || this.membersBeingPopulated)
+ {
+ lock (this)
+ {
+ if (this.members == null)
+ {
+ this.membersBeingPopulated = true;
+ MemberList members = this.members = new MemberList(5);
+ members.Add(this.Constructor);
+ //^ assume this.ctorList != null && this.ctorList.Length > 1;
+ members.Add(this.ctorList[1]);
+ members.Add(this.Getter);
+ members.Add(this.Setter);
+ members.Add(this.Address);
+ this.membersBeingPopulated = false;
+ }
+ }
+ }
+ return this.members;
+ }
+ set
+ {
+ this.members = value;
+ }
+ }
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.ElementType != null && this.ElementType.DeclaringType != null)
+ return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Name != null)
+ return this.Name.ToString();
+ else
+ return "";
+ }
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (this.ElementType == null) return;
+ this.ElementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('[');
+ int k = this.Sizes == null ? 0 : this.Sizes.Length;
+ int m = this.LowerBounds == null ? 0 : this.LowerBounds.Length;
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ if (i < k && this.Sizes[i] != 0)
+ {
+ if (i < m && this.LowerBounds[i] != 0)
+ {
+ sb.Append(this.LowerBounds[i]);
+ sb.Append(':');
+ }
+ sb.Append(this.Sizes[i]);
+ }
+ if (i < n - 1)
+ sb.Append(',');
+ }
+ sb.Append(']');
+ }
+#endif
+ public virtual void SetLowerBoundToUnknown()
+ {
+ Debug.Assert(this.Rank == 1);
+ this.typeCode = Metadata.ElementType.Array;
+ }
+ public virtual int GetLowerBound(int dimension)
+ {
+ if (this.LowerBounds == null || this.LowerBounds.Length <= dimension) return 0;
+ return this.LowerBounds[dimension];
+ }
+ public virtual int GetSize(int dimension)
+ {
+ if (this.Sizes == null || this.Sizes.Length <= dimension) return 0;
+ return this.Sizes[dimension];
+ }
+ public override MemberList/*!*/ GetMembersNamed(Identifier name)
+ {
+ if (name == null) return new MemberList(0);
+ if (name.UniqueIdKey == StandardIds.Get.UniqueIdKey)
+ {
+ if (this.getterList == null)
+ {
+ Method getter = this.Getter;
+ if (getter != null) getter = null;
+ //^ assume this.getterList != null;
+ }
+ return this.getterList;
+ }
+ else if (name.UniqueIdKey == StandardIds.Set.UniqueIdKey)
+ {
+ if (this.setterList == null)
+ {
+ Method setter = this.Setter;
+ if (setter != null) setter = null;
+ //^ assume this.setterList != null;
+ }
+ return this.setterList;
+ }
+ else if (name.UniqueIdKey == StandardIds.Ctor.UniqueIdKey)
+ {
+ if (this.ctorList == null)
+ {
+ Method ctor = this.Constructor;
+ if (ctor != null) ctor = null;
+ //^ assume this.ctorList != null;
+ }
+ return this.ctorList;
+ }
+ else if (name.UniqueIdKey == StandardIds.Address.UniqueIdKey)
+ {
+ if (this.addressList == null)
+ {
+ Method addr = this.Address;
+ if (addr != null) addr = null;
+ //^ assume this.addressList != null;
+ }
+ return this.addressList;
+ }
+ else
+ return new MemberList(0);
+ }
+#if !NoReflection
+ public override Type GetRuntimeType()
+ {
+ if (this.runtimeType == null)
+ {
+ if (this.ElementType == null) return null;
+ Type eType = this.ElementType.GetRuntimeType();
+ if (eType == null) return null;
+#if WHIDBEY
+ if (this.IsSzArray())
+ this.runtimeType = eType.MakeArrayType();
+ else
+ this.runtimeType = eType.MakeArrayType(this.Rank);
+#else
+ StringBuilder sb = new StringBuilder(eType.FullName);
+ sb.Append('[');
+ for (int i = 1, n = this.Rank; i < n; i++) sb.Append(',');
+ sb.Append(']');
+ if (eType.Assembly != null)
+ this.runtimeType = eType.Assembly.GetType(sb.ToString(), false);
+ else if (eType.Module != null)
+ this.runtimeType = eType.Module.GetType(sb.ToString(), false);
+#endif
+ }
+ return this.runtimeType;
+ }
+#endif
+ public Method Constructor
+ {
+ get
+ {
+ if (this.ctorList == null)
+ {
+ lock (this)
+ {
+ if (this.ctorList == null)
+ {
+ InstanceInitializer ctor = new InstanceInitializer();
+ ctor.DeclaringType = this;
+ ctor.Flags |= MethodFlags.Public;
+ int n = this.Rank;
+ ctor.Parameters = new ParameterList(n);
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = new Parameter();
+ par.DeclaringMethod = ctor;
+ par.Type = CoreSystemTypes.Int32;
+ ctor.Parameters.Add(par);
+ }
+ this.ctorList = new MemberList(2);
+ this.ctorList.Add(ctor);
+ ctor = new InstanceInitializer();
+ ctor.DeclaringType = this;
+ ctor.Flags |= MethodFlags.Public;
+ ctor.Parameters = new ParameterList(n = n * 2);
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = new Parameter();
+ par.Type = CoreSystemTypes.Int32;
+ par.DeclaringMethod = ctor;
+ ctor.Parameters.Add(par);
+ }
+ this.ctorList.Add(ctor);
+ }
+ }
+ }
+ return (Method)this.ctorList[0];
+ }
+ }
+ public Method Getter
+ {
+ get
+ {
+ if (this.getterList == null)
+ {
+ lock (this)
+ {
+ if (this.getterList == null)
+ {
+ Method getter = new Method();
+ getter.Name = StandardIds.Get;
+ getter.DeclaringType = this;
+ getter.CallingConvention = CallingConventionFlags.HasThis;
+ getter.Flags = MethodFlags.Public;
+ getter.Parameters = new ParameterList();
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ Parameter par = new Parameter();
+ par.Type = CoreSystemTypes.Int32;
+ par.DeclaringMethod = getter;
+ getter.Parameters.Add(par);
+ }
+ getter.ReturnType = this.ElementType;
+ this.getterList = new MemberList();
+ this.getterList.Add(getter);
+ }
+ }
+ }
+ return (Method)this.getterList[0];
+ }
+ }
+ public Method Setter
+ {
+ get
+ {
+ if (this.setterList == null)
+ {
+ lock (this)
+ {
+ if (this.setterList == null)
+ {
+ Method setter = new Method();
+ setter.Name = StandardIds.Set;
+ setter.DeclaringType = this;
+ setter.CallingConvention = CallingConventionFlags.HasThis;
+ setter.Flags = MethodFlags.Public;
+ setter.Parameters = new ParameterList();
+ Parameter par;
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ par = new Parameter();
+ par.Type = CoreSystemTypes.Int32;
+ par.DeclaringMethod = setter;
+ setter.Parameters.Add(par);
+ }
+ par = new Parameter();
+ par.Type = this.ElementType;
+ par.DeclaringMethod = setter;
+ setter.Parameters.Add(par);
+ setter.ReturnType = CoreSystemTypes.Void;
+ this.setterList = new MemberList();
+ this.setterList.Add(setter);
+ }
+ }
+ }
+ return (Method)this.setterList[0];
+ }
+ }
+ public Method Address
+ {
+ get
+ {
+ if (this.addressList == null)
+ {
+ lock (this)
+ {
+ if (this.addressList == null)
+ {
+ Method address = new Method();
+ address.Name = StandardIds.Address;
+ address.DeclaringType = this;
+ address.CallingConvention = CallingConventionFlags.HasThis;
+ address.Flags = MethodFlags.Public;
+ address.Parameters = new ParameterList();
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ Parameter par = new Parameter();
+ par.Type = CoreSystemTypes.Int32;
+ par.DeclaringMethod = address;
+ address.Parameters.Add(par);
+ }
+ address.ReturnType = this.ElementType.GetReferenceType();
+ this.addressList = new MemberList();
+ this.addressList.Add(address);
+ }
+ }
+ }
+ return (Method)this.addressList[0];
+ }
+ }
+ public override bool IsAssignableTo(TypeNode targetType)
+ {
+ if (targetType == null) return false;
+ if (targetType == this || targetType == CoreSystemTypes.Object || targetType == CoreSystemTypes.Array || targetType == SystemTypes.ICloneable) return true;
+ if (CoreSystemTypes.Array.IsAssignableTo(targetType)) return true;
+ if (targetType.Template != null && SystemTypes.GenericIEnumerable != null && SystemTypes.GenericIEnumerable.DeclaringModule == CoreSystemTypes.SystemAssembly)
+ {
+ if (targetType.Template == SystemTypes.GenericIEnumerable || targetType.Template == SystemTypes.GenericICollection ||
+ targetType.Template == SystemTypes.GenericIList)
+ {
+ if (targetType.TemplateArguments == null || targetType.TemplateArguments.Count != 1)
+ {
+ Debug.Assert(false); return false;
+ }
+ TypeNode ienumElementType = targetType.TemplateArguments[0];
+ if (this.ElementType == ienumElementType) return true;
+ if (this.ElementType.IsValueType) return false;
+ return this.ElementType.IsAssignableTo(ienumElementType);
+ }
+ }
+ ArrayType targetArrayType = targetType as ArrayType;
+ if (targetArrayType == null) return false;
+ if (this.Rank != 1 || targetArrayType.Rank != 1) return false;
+ TypeNode thisElementType = this.ElementType;
+ if (thisElementType == null) return false;
+#if ExtendedRuntime
+ thisElementType = TypeNode.StripModifier(thisElementType, ExtendedRuntimeTypes.NonNullType);
+ // DelayedAttribute is used as a modifier on some array allocation types to mark it as
+ // an explictly delayed allocation.
+ thisElementType = TypeNode.StripModifier(thisElementType, ExtendedRuntimeTypes.DelayedAttribute);
+#endif
+ if (thisElementType == targetArrayType.ElementType) return true;
+ if (thisElementType.IsValueType) return false;
+ return thisElementType.IsAssignableTo(targetArrayType.ElementType);
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ result.Add(this.ElementType);
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ ArrayType t = type as ArrayType;
+ if (t == null) return false;
+ if (this.Rank != t.Rank) return false;
+ if (this.ElementType == null || t.ElementType == null) return false;
+ if (this.ElementType != t.ElementType && !this.ElementType.IsStructurallyEquivalentTo(t.ElementType)) return false;
+ if (this.Sizes == null) return t.Sizes == null;
+ if (t.Sizes == null) return false;
+ int n = this.Sizes.Length; if (n != t.Sizes.Length) return false;
+ for (int i = 0; i < n; i++)
+ {
+ if (this.Sizes[i] != t.Sizes[i]) return false;
+ }
+ if (this.LowerBounds == null) return t.LowerBounds == null;
+ if (t.LowerBounds == null) return false;
+ n = this.LowerBounds.Length; if (n != t.LowerBounds.Length) return false;
+ for (int i = 0; i < n; i++)
+ {
+ if (this.LowerBounds[i] != t.LowerBounds[i]) return false;
+ }
+ return true;
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ this.ElementType.GetName(options, name);
+ GetNameSuffix(name, options.InsertSpacesBetweenMethodTypeParameters);
+ }
+ private void GetNameSuffix(StringBuilder name, bool insertSpacesBetweenParameters)
+ {
+ name.Append('[');
+ int k = this.Sizes == null ? 0 : this.Sizes.Length;
+ int m = this.LowerBounds == null ? 0 : this.LowerBounds.Length;
+ for (int i = 0, n = this.Rank; i < n; i++)
+ {
+ if (i < k && this.Sizes[i] != 0)
+ {
+ if (i < m && this.LowerBounds[i] != 0)
+ {
+ name.Append(this.LowerBounds[i].ToString("0", CultureInfo.InvariantCulture));
+ name.Append(':');
+ }
+ name.Append(this.Sizes[i].ToString("0", CultureInfo.InvariantCulture));
+ }
+ if (i < n - 1)
+ {
+ name.Append(',');
+ if (insertSpacesBetweenParameters)
+ name.Append(' ');
+ }
+ }
+ name.Append(']');
+ }
+#endif
+ }
+ public class Pointer : TypeNode
+ {
+ internal Pointer(TypeNode/*!*/ elementType)
+ : base(NodeType.Pointer)
+ {
+ this.elementType = elementType;
+ this.typeCode = Metadata.ElementType.Pointer;
+ this.Name = Identifier.For(elementType.Name + "*");
+ this.Namespace = elementType.Namespace;
+ }
+ private TypeNode/*!*/ elementType;
+ public TypeNode/*!*/ ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.ElementType != null && this.ElementType.DeclaringType != null)
+ return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Name != null)
+ return this.Name.ToString();
+ else
+ return "";
+ }
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (this.elementType == null) return;
+ this.elementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('*');
+ }
+#endif
+#if !NoReflection
+ public override Type GetRuntimeType()
+ {
+ if (this.runtimeType == null)
+ {
+ if (this.ElementType == null) return null;
+ Type eType = this.ElementType.GetRuntimeType();
+ if (eType == null) return null;
+#if WHIDBEY
+ this.runtimeType = eType.MakePointerType();
+#else
+ if (eType.Assembly != null)
+ this.runtimeType = eType.Assembly.GetType(eType.FullName+"*", false);
+ else
+ this.runtimeType = eType.Module.GetType(eType.FullName+"*", false);
+#endif
+ }
+ return this.runtimeType;
+ }
+#endif
+ public override bool IsAssignableTo(TypeNode targetType)
+ {
+ return targetType == this || (targetType is Pointer && ((Pointer)targetType).ElementType == CoreSystemTypes.Void);
+ }
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ return true;
+ }
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ public override bool IsPointerType
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ result.Add(this.ElementType);
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ Pointer t = type as Pointer;
+ if (t == null) return false;
+ if (this.ElementType == null || t.ElementType == null) return false;
+ return this.ElementType == t.ElementType || this.ElementType.IsStructurallyEquivalentTo(t.ElementType);
+ }
+#if FxCop
+ internal override void GetName(TypeFormat options, StringBuilder name)
+ {
+ this.ElementType.GetName(options, name);
+ name.Append('*');
+ }
+#endif
+ }
+ public class Reference : TypeNode
+ {
+ internal Reference(TypeNode/*!*/ elementType)
+ : base(NodeType.Reference)
+ {
+ this.elementType = elementType;
+ this.typeCode = Metadata.ElementType.Reference;
+ this.Name = Identifier.For(elementType.Name + "@");
+ this.Namespace = elementType.Namespace;
+ }
+ private TypeNode/*!*/ elementType;
+ public TypeNode/*!*/ ElementType
+ {
+ get { return this.elementType; }
+ set { this.elementType = value; }
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ if (this.elementType == null) return;
+ this.elementType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('@');
+ }
+#endif
+ public override bool IsAssignableTo(TypeNode targetType)
+ {
+ return targetType == this ||
+ (targetType is Pointer && (((Pointer)targetType).ElementType == this.ElementType ||
+ ((Pointer)targetType).ElementType == CoreSystemTypes.Void));
+ }
+
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.ElementType != null && this.ElementType.DeclaringType != null)
+ return this.ElementType.DeclaringType.FullName + "+" + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Namespace != null && this.Namespace.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ return this.Namespace.ToString() + "." + (this.Name == null ? "" : this.Name.ToString());
+ else if (this.Name != null)
+ return this.Name.ToString();
+ else
+ return "";
+ }
+ }
+#if !NoReflection
+ public override Type GetRuntimeType()
+ {
+ if (this.runtimeType == null)
+ {
+ if (this.ElementType == null) return null;
+ Type eType = this.ElementType.GetRuntimeType();
+ if (eType == null) return null;
+#if WHIDBEY
+ this.runtimeType = eType.MakeByRefType();
+#else
+ if (eType.Assembly != null)
+ this.runtimeType = eType.Assembly.GetType(eType.FullName+"&", false);
+ else
+ this.runtimeType = eType.Module.GetType(eType.FullName+"&", false);
+#endif
+ }
+ return this.runtimeType;
+ }
+#endif
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ result.Add(this.ElementType);
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ Reference t = type as Reference;
+ if (t == null) return false;
+ if (this.ElementType == null || t.ElementType == null) return false;
+ return this.ElementType == t.ElementType || this.ElementType.IsStructurallyEquivalentTo(t.ElementType);
+ }
+#if FxCop
+ internal override void GetName(TypeFormat options, StringBuilder name)
+ {
+ this.ElementType.GetName(options, name);
+ name.Append('&');
+ }
+#endif
+ }
+#if ExtendedRuntime
+ public class TupleType : Struct{
+ private TupleType(FieldList domains, Identifier/*!*/ name, TypeNode/*!*/ referringType, TypeFlags visibility) {
+ referringType.DeclaringModule.StructurallyEquivalentType[name.UniqueIdKey] = this;
+ this.DeclaringModule = referringType.DeclaringModule;
+ this.NodeType = NodeType.TupleType;
+ this.Flags = TypeFlags.Sealed;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = name;
+ this.isNormalized = true;
+ switch (visibility){
+ case TypeFlags.NestedFamANDAssem:
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedPrivate:
+ referringType.Members.Add(this);
+ this.DeclaringType = referringType;
+ this.Flags |= TypeFlags.NestedPrivate;
+ break;
+ default:
+ referringType.DeclaringModule.Types.Add(this);
+ this.Flags |= TypeFlags.Public;
+ break;
+ }
+ int n = domains == null ? 0 : domains.Count;
+ MemberList members = this.members = new MemberList(n);
+ TypeNodeList types = new TypeNodeList(n);
+ for (int i = 0; i < n; i++){
+ //^ assert domains != null;
+ Field f = domains[i];
+ if (f == null) continue;
+ f = (Field)f.Clone();
+ f.DeclaringType = this;
+ members.Add(f);
+ if (f.Type != null)
+ types.Add(f.Type);
+ }
+ TypeNode elemType = null;
+ if (n == 1)
+ elemType = types[0]; //TODO: get element type of stream?
+ else{
+ TypeUnion tu = TypeUnion.For(types, referringType);
+ //^ assume tu != null;
+ elemType = tu;
+ if (tu.Types.Count == 1) elemType = tu.Types[0];
+ }
+ if (elemType == null) elemType = CoreSystemTypes.Object;
+ Interface ienumerable = (Interface)SystemTypes.GenericIEnumerable.GetTemplateInstance(referringType, elemType);
+ Interface ienumerator = (Interface)SystemTypes.GenericIEnumerator.GetTemplateInstance(referringType, elemType);
+ this.Interfaces = new InterfaceList(SystemTypes.TupleType, ienumerable, SystemTypes.IEnumerable);
+
+ This ThisParameter = new This(this.GetReferenceType());
+ StatementList statements = new StatementList(1);
+ TypeNode tEnumerator = TupleEnumerator.For(this, n, elemType, ienumerator, referringType);
+ InstanceInitializer cons = tEnumerator.GetConstructor(this);
+ if (cons == null) { Debug.Fail(""); return; }
+ ExpressionList args = new ExpressionList(new AddressDereference(ThisParameter, this));
+ statements.Add(new Return(new Construct(new MemberBinding(null, cons), args)));
+ Block body = new Block(statements);
+ Method getEnumerator = new Method(this, null, StandardIds.GetEnumerator, null, ienumerator, body);
+ getEnumerator.Flags = MethodFlags.Public|MethodFlags.Virtual;
+ getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
+ getEnumerator.ThisParameter = ThisParameter;
+ this.members.Add(getEnumerator);
+
+ //IEnumerable.GetEnumerator
+ ThisParameter = new This(this.GetReferenceType());
+ statements = new StatementList(1);
+ MethodCall mcall = new MethodCall(new MemberBinding(ThisParameter, getEnumerator), new ExpressionList(0), NodeType.Call, SystemTypes.IEnumerator);
+ statements.Add(new Return(mcall));
+ getEnumerator = new Method(this, null, StandardIds.IEnumerableGetEnumerator, null, SystemTypes.IEnumerator, new Block(statements));
+ getEnumerator.ThisParameter = ThisParameter;
+ getEnumerator.ImplementedInterfaceMethods = new MethodList(SystemTypes.IEnumerable.GetMethod(StandardIds.GetEnumerator));
+ getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
+ getEnumerator.Flags = MethodFlags.Private | MethodFlags.Virtual | MethodFlags.SpecialName;
+ this.members.Add(getEnumerator);
+ }
+ internal TupleType(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle) {
+ this.NodeType = NodeType.TupleType;
+ this.typeCode = ElementType.ValueType;
+ }
+ public static TupleType For(FieldList domains, TypeNode referringType){
+ if (referringType == null) return null;
+ Module module = referringType.DeclaringModule;
+ if (module == null) return null;
+ TypeFlags visibility = TypeFlags.Public;
+ StringBuilder name = new StringBuilder();
+ name.Append("Tuple");
+ int n = domains == null ? 0 : domains.Count;
+ for (int i = 0; i < n; i++) {
+ //^ assert domains != null;
+ Field f = domains[i];
+ if (f == null || f.Type == null || f.Type.Name == null) continue;
+ visibility = TypeNode.GetVisibilityIntersection(visibility, f.Type.Flags & TypeFlags.VisibilityMask);
+ name.Append('_');
+ name.Append(f.Type.Name.ToString());
+ if (f.Name != null && !f.IsSpecialName) {
+ name.Append('_');
+ name.Append(f.Name.ToString());
+ }
+ }
+ TupleType tup = null;
+ int tCount = 0;
+ string tNameString = name.ToString();
+ Identifier tName = Identifier.For(tNameString);
+ TypeNode result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ while (result != null) {
+ //Mangled name is the same. But mangling is not unique (types are not qualified with assemblies), so check for equality.
+ tup = result as TupleType;
+ bool goodMatch = tup != null;
+ if (goodMatch) {
+ //^ assert tup != null;
+ MemberList tMembers = tup.Members;
+ int m = tMembers == null ? 0 : tMembers.Count;
+ goodMatch = n == m-2;
+ if (goodMatch) {
+ //^ assert domains != null;
+ //^ assert tMembers != null;
+ for (int i = 0; goodMatch && i < n; i++) {
+ Field f1 = domains[i];
+ Field f2 = tMembers[i] as Field;
+ goodMatch = f1 != null && f2 != null && f1.Type == f2.Type &&
+ f1.Name != null && f2.Name != null && f1.Name.UniqueIdKey == f2.Name.UniqueIdKey;
+ }
+ }
+ }
+ if (goodMatch) return tup;
+ //Mangle some more
+ tName = Identifier.For(tNameString+(++tCount).ToString());
+ result = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ }
+ tup = new TupleType(domains, tName, referringType, visibility);
+ return tup;
+ }
+ public override bool IsStructural{
+ get{return true;}
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes{
+ get{
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ MemberList members = this.Members;
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++){
+ Field f = members[i] as Field;
+ if (f == null || f.Type == null) continue;
+ result.Add(f.Type);
+ }
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type){
+ if (type == null) return false;
+ if (this == type) return true;
+ TupleType t = type as TupleType;
+ if (t == null) return false;
+ if (this.Members == null) return t.Members == null;
+ if (t.Members == null) return false;
+ int n = this.Members.Count; if (n != t.Members.Count) return false;
+ for (int i = 0; i < n; i++){
+ Member m1 = this.Members[i];
+ Member m2 = t.Members[i];
+ if (m1 == null || m2 == null) return false;
+ Field f1 = m1 as Field;
+ Field f2 = m2 as Field;
+ if (f1 == null && f2 == null) continue;
+ if (f1 == null || f2 == null) return false;
+ if (f1.Name == null || f2.Name == null) return false;
+ if (f1.Type == null || f2.Type == null) return false;
+ if (f1.Name.UniqueIdKey != f2.Name.UniqueIdKey) return false;
+ if (f1.Type != f2.Type && !f1.Type.IsStructurallyEquivalentTo(f2.Type)) return false;
+ }
+ return true;
+ }
+ }
+ internal sealed class TupleEnumerator{
+ private TupleEnumerator(){}
+ internal static TypeNode/*!*/ For(TupleType/*!*/ tuple, int numDomains, TypeNode/*!*/ elementType, Interface/*!*/ targetIEnumerator, TypeNode/*!*/ referringType) {
+ Identifier id = Identifier.For("Enumerator"+tuple.Name);
+ InterfaceList interfaces = new InterfaceList(targetIEnumerator, SystemTypes.IDisposable, SystemTypes.IEnumerator);
+ MemberList members = new MemberList(5);
+ Class enumerator = new Class(referringType.DeclaringModule, null, null, TypeFlags.Sealed, targetIEnumerator.Namespace, id, CoreSystemTypes.Object, interfaces, members);
+ enumerator.IsNormalized = true;
+ if ((tuple.Flags & TypeFlags.VisibilityMask) == TypeFlags.Public){
+ enumerator.Flags |= TypeFlags.Public;
+ referringType.DeclaringModule.Types.Add(enumerator);
+ }else{
+ enumerator.Flags |= TypeFlags.NestedPrivate;
+ referringType.Members.Add(enumerator);
+ enumerator.DeclaringType = referringType;
+ }
+ //Field to hold tuple
+ Field tField = new Field(enumerator, null, FieldFlags.Private, StandardIds.Value, tuple, null);
+ members.Add(tField);
+ //Field to hold current position
+ Field pField = new Field(enumerator, null, FieldFlags.Private, StandardIds.Position, CoreSystemTypes.Int32, null);
+ members.Add(pField);
+ //Constructor
+ Parameter par = new Parameter(null, ParameterFlags.None, StandardIds.Value, tuple, null, null);
+ StatementList statements = new StatementList(4);
+ InstanceInitializer constr = CoreSystemTypes.Object.GetConstructor();
+ if (constr == null) { Debug.Fail(""); return enumerator; }
+ This thisParameter = new This(enumerator);
+ MethodCall mcall = new MethodCall(new MemberBinding(thisParameter, constr), new ExpressionList(0), NodeType.Call, CoreSystemTypes.Void);
+ statements.Add(new ExpressionStatement(mcall));
+ statements.Add(new AssignmentStatement(new MemberBinding(thisParameter, tField), par));
+ statements.Add(new AssignmentStatement(new MemberBinding(thisParameter, pField), Literal.Int32MinusOne));
+ statements.Add(new Return());
+ InstanceInitializer econs = new InstanceInitializer(enumerator, null, new ParameterList(par), new Block(statements));
+ econs.ThisParameter = thisParameter;
+ econs.Flags |= MethodFlags.Public;
+ members.Add(econs);
+ //get_Current
+ thisParameter = new This(enumerator);
+ statements = new StatementList(numDomains+1);
+ BlockList blocks = new BlockList(numDomains);
+ statements.Add(new SwitchInstruction(new MemberBinding(thisParameter, pField), blocks));
+ constr = SystemTypes.InvalidOperationException.GetConstructor();
+ if (constr == null) { Debug.Fail(""); return enumerator; }
+ statements.Add(new Throw(new Construct(new MemberBinding(null, constr), null)));
+ for (int i = 0; i < numDomains; i++){
+ Field f = (Field)tuple.members[i];
+ MemberBinding mb = new MemberBinding(new UnaryExpression(new MemberBinding(thisParameter, tField), NodeType.AddressOf), f);
+ Block b = new Block();
+ statements.Add(b);
+ blocks.Add(b);
+ if (f.Type == elementType || f.Type == null)
+ b.Statements = new StatementList(new Return(mb));
+ else{
+ TypeUnion tUnion = elementType as TypeUnion;
+ Debug.Assert(tUnion != null);
+ if (tUnion != null){
+ Method m = tUnion.GetImplicitCoercionFromMethod(f.Type);
+ if (m != null){
+ MethodCall mCall = new MethodCall(new MemberBinding(null, m), new ExpressionList(mb));
+ b.Statements = new StatementList(new Return(mCall));
+ }else{
+ TypeUnion eUnion = f.Type as TypeUnion;
+ if (eUnion != null){
+ Method getTagAsType = eUnion.GetMethod(StandardIds.GetTagAsType);
+ Method getValue = eUnion.GetMethod(StandardIds.GetValue);
+ Method fromObject = tUnion.GetMethod(StandardIds.FromObject, CoreSystemTypes.Object, CoreSystemTypes.Type);
+ if (getTagAsType == null || getValue == null || fromObject == null) {
+ Debug.Fail(""); return enumerator;
+ }
+ Local temp = new Local(Identifier.Empty, eUnion);
+ Expression tempAddr = new UnaryExpression(temp, NodeType.AddressOf);
+ StatementList stats = new StatementList(2);
+ stats.Add(new AssignmentStatement(temp, mb));
+ ExpressionList arguments = new ExpressionList(2);
+ arguments.Add(new MethodCall(new MemberBinding(tempAddr, getValue), null));
+ arguments.Add(new MethodCall(new MemberBinding(tempAddr, getTagAsType), null));
+ stats.Add(new Return(new MethodCall(new MemberBinding(null, fromObject), arguments)));
+ b.Statements = stats;
+ }else{
+ Debug.Assert(false);
+ }
+ }
+ }
+ }
+ }
+ Method getCurrent = new Method(enumerator, null, StandardIds.getCurrent, null, elementType, new Block(statements));
+ getCurrent.Flags = MethodFlags.Public|MethodFlags.Virtual|MethodFlags.NewSlot|MethodFlags.HideBySig|MethodFlags.SpecialName;
+ getCurrent.CallingConvention = CallingConventionFlags.HasThis;
+ getCurrent.ThisParameter = thisParameter;
+ members.Add(getCurrent);
+
+ //IEnumerator.GetCurrent
+ statements = new StatementList(1);
+ This ThisParameter = new This(enumerator);
+ MethodCall callGetCurrent = new MethodCall(new MemberBinding(ThisParameter, getCurrent), new ExpressionList(0), NodeType.Call, elementType);
+ MemberBinding etExpr = new MemberBinding(null, elementType);
+ statements.Add(new Return(new BinaryExpression(callGetCurrent, etExpr, NodeType.Box, CoreSystemTypes.Object)));
+ Method ieGetCurrent = new Method(enumerator, null, StandardIds.IEnumeratorGetCurrent, null, CoreSystemTypes.Object, new Block(statements));
+ ieGetCurrent.ThisParameter = ThisParameter;
+ ieGetCurrent.ImplementedInterfaceMethods = new MethodList(SystemTypes.IEnumerator.GetMethod(StandardIds.getCurrent));
+ ieGetCurrent.CallingConvention = CallingConventionFlags.HasThis;
+ ieGetCurrent.Flags = MethodFlags.Private|MethodFlags.Virtual|MethodFlags.SpecialName;
+ members.Add(ieGetCurrent);
+
+ //IEnumerator.Reset
+ statements = new StatementList(2);
+ ThisParameter = new This(enumerator);
+ statements.Add(new AssignmentStatement(new MemberBinding(ThisParameter, pField), Literal.Int32Zero));
+ statements.Add(new Return());
+ Method reset = new Method(enumerator, null, StandardIds.IEnumeratorReset, null, CoreSystemTypes.Void, new Block(statements));
+ reset.ThisParameter = ThisParameter;
+ reset.ImplementedInterfaceMethods = new MethodList(SystemTypes.IEnumerator.GetMethod(StandardIds.Reset));
+ reset.CallingConvention = CallingConventionFlags.HasThis;
+ reset.Flags = MethodFlags.Private|MethodFlags.Virtual|MethodFlags.SpecialName;
+ members.Add(reset);
+
+ //MoveNext
+ ThisParameter = new This(enumerator);
+ statements = new StatementList(5);
+ MemberBinding pos = new MemberBinding(ThisParameter, pField);
+ Expression comparison = new BinaryExpression(pos, new Literal(numDomains, CoreSystemTypes.Int32), NodeType.Lt);
+ Block returnTrue = new Block();
+ statements.Add(new AssignmentStatement(pos, new BinaryExpression(pos, Literal.Int32One, NodeType.Add)));
+ statements.Add(new Branch(comparison, returnTrue));
+ statements.Add(new Return(Literal.False));
+ statements.Add(returnTrue);
+ statements.Add(new Return(Literal.True));
+ Method moveNext = new Method(enumerator, null, StandardIds.MoveNext, null, CoreSystemTypes.Boolean, new Block(statements));
+ moveNext.Flags = MethodFlags.Public|MethodFlags.Virtual|MethodFlags.NewSlot|MethodFlags.HideBySig;
+ moveNext.CallingConvention = CallingConventionFlags.HasThis;
+ moveNext.ThisParameter = ThisParameter;
+ members.Add(moveNext);
+ //IDispose.Dispose
+ statements = new StatementList(1);
+ statements.Add(new Return());
+ Method dispose = new Method(enumerator, null, StandardIds.Dispose, null, CoreSystemTypes.Void, new Block(statements));
+ dispose.CallingConvention = CallingConventionFlags.HasThis;
+ dispose.Flags = MethodFlags.Public|MethodFlags.Virtual;
+ enumerator.Members.Add(dispose);
+ return enumerator;
+ }
+ }
+ public class TypeAlias : Struct{
+ protected TypeNode aliasedType;
+ public TypeNode AliasedTypeExpression;
+ public bool RequireExplicitCoercionFromUnderlyingType;
+ public TypeAlias()
+ : this(null, null){
+ }
+ internal TypeAlias(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle, bool requireExplicitCoercionFromUnderlyingType)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle) {
+ this.RequireExplicitCoercionFromUnderlyingType = requireExplicitCoercionFromUnderlyingType;
+ }
+ public TypeAlias(TypeNode aliasedType, Identifier name)
+ : base(){
+ this.NodeType = NodeType.TypeAlias;
+ this.AliasedType = aliasedType;
+ this.Name = name;
+ }
+ public TypeNode AliasedType{
+ get{
+ if (this.aliasedType == null){
+ Field f = this.GetField(StandardIds.Value);
+ if (f != null)
+ this.aliasedType = f.Type;
+ }
+ return this.aliasedType;
+ }
+ set{
+ this.aliasedType = value;
+ }
+ }
+ public virtual void ProvideMembers(){
+ if (this.AliasedType == null) return;
+ this.Interfaces = new InterfaceList(1);
+ if (this.RequireExplicitCoercionFromUnderlyingType)
+ this.Interfaces.Add(SystemTypes.TypeDefinition);
+ else
+ this.Interfaces.Add(SystemTypes.TypeAlias);
+ MemberList members = this.members;
+ if (members == null) members = this.members = new MemberList();
+ //Value field
+ Field valueField = new Field(this, null, FieldFlags.Private, StandardIds.Value, this.AliasedType, null);
+ members.Add(valueField);
+ //Implicit conversion from this type to underlying type
+ ParameterList parameters = new ParameterList(1);
+ Parameter valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, this, null, null);
+ parameters.Add(valuePar);
+ Method toAliasedType = new Method(this, null, StandardIds.opImplicit, parameters, this.AliasedType, null);
+ toAliasedType.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(toAliasedType);
+ StatementList statements = new StatementList(1);
+ statements.Add(new Return(new MemberBinding(new UnaryExpression(valuePar, NodeType.AddressOf), valueField)));
+ toAliasedType.Body = new Block(statements);
+ //Implicit or explicit conversion from underlying type to this type
+ Identifier opId = this.RequireExplicitCoercionFromUnderlyingType ? StandardIds.opExplicit : StandardIds.opImplicit;
+ parameters = new ParameterList(1);
+ parameters.Add(valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, this.AliasedType, null, null));
+ Method fromAliasedType = new Method(this, null, opId, parameters, this, null);
+ fromAliasedType.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(fromAliasedType);
+ statements = new StatementList(2);
+ Local loc = new Local(this);
+ statements.Add(new AssignmentStatement(new MemberBinding(new UnaryExpression(loc, NodeType.AddressOf), valueField), valuePar));
+ statements.Add(new Return(loc));
+ fromAliasedType.Body = new Block(statements);
+ this.AddCoercionWrappers(this.AliasedType.ExplicitCoercionMethods, StandardIds.opExplicit, fromAliasedType, toAliasedType);
+ this.AddCoercionWrappers(this.AliasedType.ImplicitCoercionMethods, StandardIds.opImplicit, fromAliasedType, toAliasedType);
+ }
+ private void AddCoercionWrappers(MemberList coercions, Identifier id, Method/*!*/ fromAliasedType, Method/*!*/ toAliasedType)
+ //^ requires this.members != null;
+ {
+ if (coercions == null) return;
+ MemberList members = this.members;
+ for (int i = 0, n = coercions.Count; i < n; i++){
+ Method coercion = coercions[i] as Method;
+ if (coercion == null || coercion.Parameters == null || coercion.Parameters.Count != 1) continue;
+ ParameterList parameters = new ParameterList(1);
+ Parameter valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, null, null, null);
+ parameters.Add(valuePar);
+ Method m = new Method(this, null, id, parameters, null, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ Expression arg = valuePar;
+ MethodCall call = new MethodCall(new MemberBinding(null, coercion), new ExpressionList(arg));
+ if (coercion.ReturnType == this.AliasedType){
+ m.ReturnType = this;
+ if (this.RequireExplicitCoercionFromUnderlyingType) m.Name = StandardIds.opExplicit;
+ valuePar.Type = coercion.Parameters[0].Type;
+ call = new MethodCall(new MemberBinding(null, fromAliasedType), new ExpressionList(call));
+ }else{
+ m.ReturnType = coercion.ReturnType;
+ valuePar.Type = this;
+ //^ assume call.Operands != null;
+ call.Operands[0] = new MethodCall(new MemberBinding(null, toAliasedType), new ExpressionList(arg));
+ }
+ m.Body = new Block(new StatementList(new Return(call)));
+ members.Add(m);
+ }
+ }
+ public override bool IsStructural{
+ get{return this.RequireExplicitCoercionFromUnderlyingType;}
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes{
+ get{
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ result.Add(this.AliasedType);
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type){
+ if (type == null) return false;
+ if (this == type) return true;
+ if (this.RequireExplicitCoercionFromUnderlyingType) return false;
+ TypeAlias t = type as TypeAlias;
+ if (t == null) return false;
+ if (t.RequireExplicitCoercionFromUnderlyingType) return false;
+ if (this.AliasedType == null || t.AliasedType == null) return false;
+ return this.AliasedType == t.AliasedType || this.AliasedType.IsStructurallyEquivalentTo(t.AliasedType);
+ }
+ }
+ public class TypeIntersection : Struct{
+ private TypeNodeList types; //sorted by UniqueKey
+ public TypeNodeList Types{
+ get{
+ if (this.types != null) return this.types;
+ if (this.ProvideTypeMembers != null) { MemberList mems = this.Members; if (mems != null) mems = null; }
+ return this.types;
+ }
+ set{
+ this.types = value;
+ }
+ }
+
+ private TypeIntersection(TypeNodeList types, Identifier name) {
+ this.NodeType = NodeType.TypeIntersection;
+ this.Flags = TypeFlags.Public|TypeFlags.Sealed;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = name;
+ this.Types = types;
+ int n = types == null ? 0 : types.Count;
+ InterfaceList ifaces = this.Interfaces = new InterfaceList(n+1);
+ ifaces.Add(SystemTypes.TypeIntersection);
+ if (types != null)
+ for (int i = 0; i < n; i++){
+ Interface iface = types[i] as Interface;
+ if (iface == null) continue;
+ ifaces.Add(iface);
+ }
+ this.isNormalized = true;
+ }
+ internal TypeIntersection(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle) {
+ this.NodeType = NodeType.TypeIntersection;
+ this.typeCode = ElementType.ValueType;
+ }
+ public static TypeIntersection For(TypeNodeList types, Module module) {
+ if (module == null) return null;
+ if (types != null && !TypeUnion.AreNormalized(types))
+ types = TypeUnion.Normalize(types);
+ TypeFlags visibility = TypeFlags.Public;
+ string name = TypeUnion.BuildName(types, "And", ref visibility);
+ Identifier tName = Identifier.For(name);
+ int tCount = 0;
+ TypeIntersection result = null;
+ TypeNode t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ while (t != null){
+ //Mangled name is the same. But mangling is not unique, so check for equality.
+ TypeIntersection ti = t as TypeIntersection;
+ if (ti != null){
+ TypeNodeList ts = ti.Types;
+ int n = types == null ? 0 : types.Count;
+ bool goodMatch = ts != null && ts.Count == n;
+ for (int i = 0; goodMatch && i < n; i++) {
+ //^ assert types != null && ts != null;
+ goodMatch = types[i] == ts[i];
+ }
+ if (goodMatch) return ti;
+ }
+ //Mangle some more
+ tName = Identifier.For(name+(++tCount).ToString());
+ t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ }
+ result = new TypeIntersection(types, tName);
+ result.DeclaringModule = module;
+ module.Types.Add(result);
+ module.StructurallyEquivalentType[tName.UniqueIdKey] = result;
+ return result;
+ }
+ public static TypeIntersection For(TypeNodeList types, TypeNode referringType) {
+ if (referringType == null) return null;
+ Module module = referringType.DeclaringModule;
+ if (module == null) return null;
+ if (types != null && !TypeUnion.AreNormalized(types))
+ types = TypeUnion.Normalize(types);
+ TypeFlags visibility = TypeFlags.Public;
+ string name = TypeUnion.BuildName(types, "And", ref visibility);
+ Identifier tName = Identifier.For(name);
+ int tCount = 0;
+ TypeIntersection result = null;
+ TypeNode t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ while (t != null){
+ //Mangled name is the same. But mangling is not unique, so check for equality.
+ TypeIntersection ti = t as TypeIntersection;
+ if (ti != null){
+ TypeNodeList ts = ti.Types;
+ int n = types == null ? 0 : types.Count;
+ bool goodMatch = ts != null && ts.Count == n;
+ for (int i = 0; goodMatch && i < n; i++) {
+ //^ assert ts != null && types != null;
+ goodMatch = types[i] == ts[i];
+ }
+ if (goodMatch) return ti;
+ }
+ //Mangle some more
+ tName = Identifier.For(name+(++tCount).ToString());
+ t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ }
+ result = new TypeIntersection(types, tName);
+ result.DeclaringModule = module;
+ switch (visibility){
+ case TypeFlags.NestedFamANDAssem:
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedPrivate:
+ referringType.Members.Add(result);
+ result.DeclaringType = referringType;
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= TypeFlags.NestedPrivate;
+ break;
+ default:
+ module.Types.Add(result);
+ break;
+ }
+ module.StructurallyEquivalentType[tName.UniqueIdKey] = result;
+ return result;
+ }
+ public override bool IsAssignableTo(TypeNode targetType){
+ return targetType == this || targetType == CoreSystemTypes.Object;
+ }
+ public override bool IsStructural{
+ get{return true;}
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes{
+ get{
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ TypeNodeList types = this.Types;
+ for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){
+ TypeNode t = types[i];
+ if (t == null) continue;
+ result.Add(t);
+ }
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type){
+ if (type == null) return false;
+ if (this == type) return true;
+ TypeIntersection t = type as TypeIntersection;
+ if (t == null) return false;
+ return this.IsStructurallyEquivalentList(this.Types, t.Types);
+ }
+ private TrivialHashtable/*!*/ interfaceMethodFor = new TrivialHashtable();
+ public override MemberList Members{
+ get{
+ MemberList members = this.members;
+ if (members == null || this.membersBeingPopulated){
+ if (this.ProvideTypeMembers != null){
+ lock(this){
+ if (this.members != null) return this.members;
+ members = base.Members;
+ MemberList coercions = this.ExplicitCoercionMethods;
+ int n = coercions == null ? 0 : coercions.Count;
+ TypeNodeList typeList = this.Types = new TypeNodeList(n);
+ for (int i = 0; i < n; i++){
+ Method coercion = coercions[i] as Method;
+ if (coercion == null) continue;
+ typeList.Add(coercion.ReturnType);
+ }
+ }
+ return this.members;
+ }
+ members = this.Members = new MemberList();
+ //Value field
+ members.Add(new Field(this, null, FieldFlags.Private, StandardIds.Value, CoreSystemTypes.Object, null));
+ //FromObject
+ ParameterList parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, CoreSystemTypes.Object, null, null));
+ Method m = new Method(this, null, StandardIds.FromObject, parameters, this, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ //coercion operators
+ parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, CoreSystemTypes.Object, null, null));
+ m = new Method(this, null, StandardIds.opExplicit, parameters, this, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, this, null, null));
+ m = new Method(this, null, StandardIds.opImplicit, parameters, CoreSystemTypes.Object, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ TypeNodeList types = this.Types;
+ for (int i = 0, n = types.Count; i < n; i++){
+ TypeNode t = types[i];
+ parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, this, null, null));
+ m = new Method(this, null, StandardIds.opImplicit, parameters, t, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ }
+ //Routines to forward interface calls to embedded object
+ InterfaceList ifaces = this.Interfaces;
+ if (ifaces != null){
+ for (int i = 0, n = ifaces.Count; i < n; i++){
+ Interface iface = ifaces[i];
+ if (iface == null) continue;
+ MemberList imembers = iface.Members;
+ if (imembers == null) continue;
+ for (int j = 0, k = imembers.Count; j < k; j++){
+ Method imeth = imembers[j] as Method;
+ if (imeth == null) continue;
+ if (imeth.IsStatic) continue;
+ Method meth = (Method)imeth.Clone();
+ meth.Flags &= ~MethodFlags.Abstract;
+ meth.DeclaringType = this;
+ members.Add(meth);
+ meth.Parameters = (imeth.Parameters == null ? null : imeth.Parameters.Clone());
+ for (int a = 0, b = meth.Parameters == null ? 0 : meth.Parameters.Count; a < b; a++){
+ Parameter par = meth.Parameters[a];
+ if (par == null) continue;
+ meth.Parameters[a] = par = (Parameter)par.Clone();
+ par.DeclaringMethod = meth;
+ }
+ this.interfaceMethodFor[meth.UniqueKey] = imeth;
+ }
+ }
+ }
+ this.ProvideBodiesForMethods();
+ }
+ return members;
+ }
+ set{
+ this.members = value;
+ }
+ }
+ private void ProvideBodiesForMethods()
+ //^ requires this.members != null;
+ {
+ MemberList members = this.members;
+ Field valueField = (Field)members[0];
+ //FromObject
+ Method fromObject = (Method)members[1];
+ StatementList statements = new StatementList(2);
+ Local resultLoc = new Local(Identifier.Empty, this);
+ Expression param = fromObject.Parameters[0];
+ statements.Add(new AssignmentStatement(new MemberBinding(new UnaryExpression(resultLoc, NodeType.AddressOf), valueField), param));
+ statements.Add(new Return(resultLoc));
+ fromObject.Body = new Block(statements);
+ //to coercion
+ Method toMethod = (Method)members[2];
+ statements = new StatementList(2);
+ resultLoc = new Local(Identifier.Empty, this);
+ param = toMethod.Parameters[0];
+ Expression castExpr = param;
+ TypeNodeList types = this.Types;
+ int n = types.Count;
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ castExpr = new BinaryExpression(castExpr, new Literal(t, CoreSystemTypes.Type), NodeType.Castclass);
+ }
+ statements.Add(new AssignmentStatement(new MemberBinding(new UnaryExpression(resultLoc, NodeType.AddressOf), valueField), castExpr));
+ statements.Add(new Return(resultLoc));
+ toMethod.Body = new Block(statements);
+ //from coercions
+ Method opImplicit = (Method)members[3];
+ opImplicit.Body = new Block(statements = new StatementList(1));
+ Expression val = new MemberBinding(new UnaryExpression(opImplicit.Parameters[0], NodeType.AddressOf), valueField);
+ statements.Add(new Return(val));
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ opImplicit = (Method)members[4+i];
+ opImplicit.Body = new Block(statements = new StatementList(1));
+ val = new MemberBinding(new UnaryExpression(opImplicit.Parameters[0], NodeType.AddressOf), valueField);
+ val = new BinaryExpression(val, new Literal(t, CoreSystemTypes.Type), NodeType.Castclass);
+ statements.Add(new Return(val));
+ }
+ //Routines to forward interface calls to embedded object
+ for (int i = 4+n, m = members.Count; i < m; i++){
+ Method meth = (Method)members[i];
+ Method imeth = (Method)this.interfaceMethodFor[meth.UniqueKey];
+ Interface iface = (Interface)imeth.DeclaringType;
+ statements = new StatementList(2);
+ ParameterList parameters = meth.Parameters;
+ int k = parameters == null ? 0 : parameters.Count;
+ ExpressionList arguments = new ExpressionList(k);
+ if (parameters != null)
+ for (int j = 0; j < k; j++) arguments.Add(parameters[j]);
+ Expression obj = new BinaryExpression(new MemberBinding(meth.ThisParameter, valueField), new Literal(iface, CoreSystemTypes.Type), NodeType.Castclass);
+ MethodCall mcall = new MethodCall(new MemberBinding(obj, imeth), arguments, NodeType.Callvirt);
+ mcall.Type = imeth.ReturnType;
+ statements.Add(new ExpressionStatement(mcall));
+ statements.Add(new Return());
+ meth.Body = new Block(statements);
+ }
+ }
+ }
+ public class TypeUnion : Struct{
+ private TypeNodeList types; //sorted by UniqueKey
+ public TypeNodeList Types{
+ get{
+ if (this.types != null) return this.types;
+ if (this.ProvideTypeMembers != null) { MemberList mems = this.Members; if (mems != null) mems = null; }
+ return this.types;
+ }
+ set{
+ this.types = value;
+ }
+ }
+
+ private TypeUnion(TypeNodeList types, Identifier tName){
+ this.NodeType = NodeType.TypeUnion;
+ this.Flags = TypeFlags.Public|TypeFlags.Sealed;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = tName;
+ this.Types = types;
+ this.Interfaces = new InterfaceList(SystemTypes.TypeUnion);
+ this.isNormalized = true;
+ }
+ internal TypeUnion(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle) {
+ this.NodeType = NodeType.TypeUnion;
+ this.typeCode = ElementType.ValueType;
+ }
+
+ internal static string/*!*/ BuildName(TypeNodeList types, string separator, ref TypeFlags visibility) {
+ int n = types == null ? 0 : types.Count;
+ if (n == 0) return "EmtpyUnion";
+ StringBuilder sb = new StringBuilder();
+ if (types != null)
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ if (t == null) continue;
+ visibility = TypeNode.GetVisibilityIntersection(visibility, t.Flags & TypeFlags.VisibilityMask);
+ sb.Append(t.Name.ToString());
+ if (i < n-1) sb.Append(separator);
+ }
+ return sb.ToString();
+ }
+ public static bool AreNormalized(TypeNodeList/*!*/ types) {
+ int id = 0;
+ for (int i = 0, n = types.Count; i < n; i++){
+ TypeNode type = types[i];
+ if (type == null) continue;
+ if (type.UniqueKey <= id || type is TypeUnion) return false;
+ id = type.UniqueKey;
+ }
+ return true;
+ }
+ public static TypeNodeList/*!*/ Normalize(TypeNodeList/*!*/ types) {
+ if (types.Count == 0) return types;
+ Hashtable ht = new Hashtable();
+ for (int i = 0, n = types.Count; i < n; i++){
+ TypeNode type = types[i];
+ if (type == null) continue; // error already reported.
+ TypeUnion tu = type as TypeUnion;
+ if (tu != null){
+ for (int ti = 0, tn = tu.Types.Count; ti < tn; ti++){
+ type = tu.Types[ti];
+ ht[type.UniqueKey] = type;
+ }
+ }else{
+ ht[type.UniqueKey] = type;
+ }
+ }
+ SortedList list = new SortedList(ht);
+ TypeNodeList result = new TypeNodeList(list.Count);
+ foreach (TypeNode t in list.Values)
+ result.Add(t);
+ return result;
+ }
+ public static TypeUnion For(TypeNodeList types, Module module) {
+ if (module == null) return null;
+ if (types != null && !TypeUnion.AreNormalized(types))
+ types = TypeUnion.Normalize(types);
+ TypeFlags visibility = TypeFlags.Public;
+ string name = TypeUnion.BuildName(types, "Or", ref visibility);
+ Identifier tName = Identifier.For(name);
+ int tCount = 0;
+ TypeUnion result = null;
+ TypeNode t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ while (t != null){
+ //Mangled name is the same. But mangling is not unique, so check for equality.
+ TypeUnion tu = t as TypeUnion;
+ if (tu != null){
+ TypeNodeList ts = tu.Types;
+ int n = types == null ? 0 : types.Count;
+ bool goodMatch = ts != null && ts.Count == n;
+ for (int i = 0; goodMatch && i < n; i++) {
+ //^ assert types != null && ts != null;
+ goodMatch = types[i] == ts[i];
+ }
+ if (goodMatch) return tu;
+ }
+ //Mangle some more
+ tName = Identifier.For(name+(++tCount).ToString());
+ t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ }
+ result = new TypeUnion(types, tName);
+ result.DeclaringModule = module;
+ module.Types.Add(result);
+ module.StructurallyEquivalentType[tName.UniqueIdKey] = result;
+ return result;
+ }
+ public static TypeUnion For(TypeNodeList/*!*/ types, TypeNode/*!*/ referringType) {
+ Module module = referringType.DeclaringModule;
+ if (module == null) return null;
+ if (!TypeUnion.AreNormalized(types))
+ types = TypeUnion.Normalize(types);
+ TypeFlags visibility = TypeFlags.Public;
+ string name = TypeUnion.BuildName(types, "Or", ref visibility);
+ Identifier tName = Identifier.For(name);
+ int tCount = 0;
+ TypeUnion result = null;
+ TypeNode t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ while (t != null){
+ //Mangled name is the same. But mangling is not unique, so check for equality.
+ TypeUnion tu = t as TypeUnion;
+ if (tu != null){
+ TypeNodeList ts = tu.Types;
+ int n = types.Count;
+ bool goodMatch = ts != null && ts.Count == n;
+ for (int i = 0; goodMatch && i < n; i++) {
+ //^ assert ts != null;
+ goodMatch = types[i] == ts[i];
+ }
+ if (goodMatch) return tu;
+ }
+ //Mangle some more
+ tName = Identifier.For(name+(++tCount).ToString());
+ t = module.GetStructurallyEquivalentType(StandardIds.StructuralTypes, tName);
+ }
+ result = new TypeUnion(types, tName);
+ result.DeclaringModule = module;
+ switch (visibility){
+ case TypeFlags.NestedFamANDAssem:
+ case TypeFlags.NestedFamily:
+ case TypeFlags.NestedPrivate:
+ referringType.Members.Add(result);
+ result.DeclaringType = referringType;
+ result.Flags &= ~TypeFlags.VisibilityMask;
+ result.Flags |= TypeFlags.NestedPrivate;
+ break;
+ default:
+ module.Types.Add(result);
+ break;
+ }
+ module.StructurallyEquivalentType[tName.UniqueIdKey] = result;
+ return result;
+ }
+ public override bool IsAssignableTo(TypeNode targetType){
+ return targetType == this || targetType == CoreSystemTypes.Object;
+ }
+ public override bool IsStructural{
+ get{return true;}
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type){
+ if (type == null) return false;
+ if (this == type) return true;
+ TypeUnion t = type as TypeUnion;
+ if (t == null) return false;
+ return this.IsStructurallyEquivalentList(this.Types, t.Types);
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes{
+ get{
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ TypeNodeList types = this.Types;
+ for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){
+ TypeNode t = types[i];
+ if (t == null) continue;
+ result.Add(t);
+ }
+ return result;
+ }
+ }
+ protected TypeUnion unlabeledUnion = null;
+ public virtual TypeUnion UnlabeledUnion{
+ get{
+ TypeUnion result = this.unlabeledUnion;
+ if (result != null) return result;
+ if (this.Types == null) return this.unlabeledUnion = this;
+ TypeNodeList types = this.Types.Clone();
+ bool noChange = true;
+ for (int i = 0, n = types.Count; i < n; i++){
+ TupleType tup = types[i] as TupleType;
+ if (tup != null && tup.Members != null && tup.Members.Count == 3 && tup.Members[0] is Field){
+ types[i] = ((Field)tup.Members[0]).Type;
+ noChange = false;
+ }
+ }
+ if (noChange)
+ return this.unlabeledUnion = this;
+ else
+ return this.unlabeledUnion = new TypeUnion(types, Identifier.Empty);
+ }
+ }
+ public override MemberList Members{
+ get{
+ MemberList members = this.members;
+ if (members == null || this.membersBeingPopulated){
+ if (this.ProvideTypeMembers != null){
+ lock(this){
+ if (this.members != null) return this.members;
+ members = base.Members;
+ MemberList coercions = this.ExplicitCoercionMethods;
+ int n = coercions == null ? 0 : coercions.Count;
+ TypeNodeList typeList = this.Types = new TypeNodeList(n);
+ for (int i = 0; i < n; i++){
+ Method coercion = coercions[i] as Method;
+ if (coercion == null) continue;
+ typeList.Add(coercion.ReturnType);
+ }
+ return this.members;
+ }
+ }
+ members = this.Members = new MemberList();
+ //Value field
+ members.Add(new Field(this, null, FieldFlags.Private, StandardIds.Value, CoreSystemTypes.Object, null));
+ //Tag field
+ members.Add(new Field(this, null, FieldFlags.Private, StandardIds.Tag, CoreSystemTypes.UInt32, null));
+ //GetValue method (used to convert from subtype to supertype via FromObject on the superType)
+ ParameterList parameters = new ParameterList(0);
+ Method m = new Method(this, null, StandardIds.GetValue, parameters, CoreSystemTypes.Object, null);
+ m.Flags = MethodFlags.SpecialName|MethodFlags.Public; m.CallingConvention = CallingConventionFlags.HasThis;
+ members.Add(m);
+ //GetTag method (used in typeswitch)
+ parameters = new ParameterList(0);
+ m = new Method(this, null, StandardIds.GetTag, parameters, CoreSystemTypes.UInt32, null);
+ m.Flags = MethodFlags.SpecialName|MethodFlags.Public; m.CallingConvention = CallingConventionFlags.HasThis;
+ members.Add(m);
+ //GetTagAsType method (used to convert from subtype to supertype via FromObject on the superType)
+ parameters = new ParameterList(0);
+ m = new Method(this, null, StandardIds.GetTagAsType, parameters, CoreSystemTypes.Type, null);
+ m.Flags = MethodFlags.SpecialName|MethodFlags.Public; m.CallingConvention = CallingConventionFlags.HasThis;
+ members.Add(m);
+ //GetType
+ parameters = new ParameterList(0);
+ m = new Method(this, null, StandardIds.GetType, parameters, CoreSystemTypes.Type, null);
+ m.Flags = MethodFlags.Public; m.CallingConvention = CallingConventionFlags.HasThis;
+ members.Add(m);
+ //FromObject
+ parameters = new ParameterList(2);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, CoreSystemTypes.Object, null, null));
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.TagType, CoreSystemTypes.Type, null, null));
+ m = new Method(this, null, StandardIds.FromObject, parameters, this, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ //coercion operators
+ TypeNodeList types = this.Types;
+ for (int i = 0, n = types.Count; i < n; i++){
+ TypeNode t = types[i];
+ parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, t, null, null));
+ m = new Method(this, null, StandardIds.opImplicit, parameters, this, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ parameters = new ParameterList(1);
+ parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, this, null, null));
+ m = new Method(this, null, StandardIds.opExplicit, parameters, t, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(m);
+ }
+ this.ProvideBodiesForMethods();
+ }
+ return members;
+ }
+ set{
+ this.members = value;
+ }
+ }
+ public void ProvideBodiesForMethods(){
+ Method objectGetType = CoreSystemTypes.Object.GetMethod(StandardIds.GetType);
+ Method typeGetTypeFromHandle = (Method)CoreSystemTypes.Type.GetMembersNamed(Identifier.For("GetTypeFromHandle"))[0];
+ Method typeGetTypeHandle = (Method)CoreSystemTypes.Type.GetMembersNamed(Identifier.For("get_TypeHandle"))[0];
+ Method runtimeTypeHandleGetValue = (Method)CoreSystemTypes.RuntimeTypeHandle.GetMembersNamed(Identifier.For("get_Value"))[0];
+ if (objectGetType == null || typeGetTypeFromHandle == null || typeGetTypeHandle == null || runtimeTypeHandleGetValue == null) {
+ Debug.Fail(""); return;
+ }
+ MemberList members = this.members;
+ if (members == null) return;
+ Field valueField = (Field)members[0];
+ Field tagField = (Field)members[1];
+ //GetValue
+ Method getValueMethod = (Method)members[2];
+ StatementList statements = new StatementList(1);
+ statements.Add(new Return(new MemberBinding(getValueMethod.ThisParameter, valueField)));
+ getValueMethod.Body = new Block(statements);
+ //GetTag
+ Method getTagMethod = (Method)members[3];
+ statements = new StatementList(1);
+ statements.Add(new Return(new MemberBinding(getTagMethod.ThisParameter, tagField)));
+ getTagMethod.Body = new Block(statements);
+ //GetTagAsType
+ Method getTagAsTypeMethod = (Method)members[4];
+ TypeNodeList types = this.Types;
+ int n = types.Count;
+ Block returnBlock = new Block();
+ statements = new StatementList(n+4);
+ getTagAsTypeMethod.Body = new Block(statements);
+ BlockList targets = new BlockList(n);
+ SwitchInstruction sw = new SwitchInstruction(new MemberBinding(getTagAsTypeMethod.ThisParameter, tagField), targets);
+ statements.Add(sw);
+ //TODO: throw an exception
+ statements.Add(new ExpressionStatement(new UnaryExpression(new Literal(CoreSystemTypes.Object, CoreSystemTypes.Type), NodeType.Ldtoken)));
+ statements.Add(returnBlock);
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ StatementList ldToken = new StatementList(2);
+ ldToken.Add(new ExpressionStatement(new UnaryExpression(new Literal(t, CoreSystemTypes.Type), NodeType.Ldtoken)));
+ ldToken.Add(new Branch(null, returnBlock));
+ Block ldtokBlock = new Block(ldToken);
+ targets.Add(ldtokBlock);
+ statements.Add(ldtokBlock);
+ }
+ statements = returnBlock.Statements = new StatementList(1);
+ statements.Add(new Return(new MethodCall(new MemberBinding(null, typeGetTypeFromHandle), null)));
+ //GetType
+ Method getTypeMethod = (Method)members[5];
+ statements = new StatementList(4);
+ getTypeMethod.Body = new Block(statements);
+ MemberBinding mb = new MemberBinding(getTypeMethod.ThisParameter, valueField);
+ Local loc = new Local(CoreSystemTypes.Object);
+ statements.Add(new AssignmentStatement(loc, mb));
+ Block callGetTagAsType = new Block();
+ statements.Add(new Branch(new UnaryExpression(loc, NodeType.LogicalNot), callGetTagAsType));
+ statements.Add(new Return(new MethodCall(new MemberBinding(loc, objectGetType), null)));
+ statements.Add(callGetTagAsType);
+ statements.Add(new Return(new MethodCall(new MemberBinding(getTypeMethod.ThisParameter, getTagAsTypeMethod), null)));
+ //FromObject
+ Method fromObjectMethod = (Method)members[6];
+ fromObjectMethod.InitLocals = true;
+ statements = new StatementList(n+8); //TODO: get the right expression
+ fromObjectMethod.Body = new Block(statements);
+ MethodCall getTypeHandle = new MethodCall(new MemberBinding(fromObjectMethod.Parameters[1], typeGetTypeHandle), null, NodeType.Callvirt);
+ Local handle = new Local(Identifier.Empty, CoreSystemTypes.RuntimeTypeHandle);
+ statements.Add(new AssignmentStatement(handle, getTypeHandle));
+ MethodCall getValue = new MethodCall(new MemberBinding(new UnaryExpression(handle, NodeType.AddressOf), runtimeTypeHandleGetValue), null);
+ getValue.Type = CoreSystemTypes.UIntPtr;
+ statements.Add(new ExpressionStatement(getValue));
+ Local temp = new Local(Identifier.Empty, CoreSystemTypes.UInt32);
+ Local result = new Local(Identifier.Empty, this);
+ Expression dup = new Expression(NodeType.Dup);
+ Block next = new Block();
+ Block curr = new Block();
+ Block setTag = new Block();
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ StatementList stats = curr.Statements = new StatementList(4);
+ UnaryExpression ldtok = new UnaryExpression(new Literal(t, CoreSystemTypes.Type), NodeType.Ldtoken);
+ stats.Add(new AssignmentStatement(handle, ldtok));
+ getValue = new MethodCall(new MemberBinding(new UnaryExpression(handle, NodeType.AddressOf), runtimeTypeHandleGetValue), null);
+ Expression compare = new BinaryExpression(dup, getValue, NodeType.Eq);
+ stats.Add(new Branch(compare, next));
+ stats.Add(new AssignmentStatement(temp, new Literal(i, CoreSystemTypes.UInt32)));
+ if (i < n-1)
+ stats.Add(new Branch(null, setTag));
+ statements.Add(curr);
+ curr = next;
+ next = new Block();
+ }
+ statements.Add(curr);
+ statements.Add(setTag);
+ statements.Add(new ExpressionStatement(new UnaryExpression(null, NodeType.Pop)));
+ Expression resultAddr = new UnaryExpression(result, NodeType.AddressOf);
+ statements.Add(new AssignmentStatement(new MemberBinding(resultAddr, tagField), temp));
+ statements.Add(new AssignmentStatement(new MemberBinding(resultAddr, valueField), fromObjectMethod.Parameters[0]));
+ statements.Add(new Return(result));
+ for (int i = 0; i < n; i++){
+ TypeNode t = types[i];
+ if (t == null) continue;
+ bool isValueType = t.IsValueType;
+ MemberBinding tExpr = new MemberBinding(null, t);
+ Method opImplicit = (Method)members[7+i*2];
+ opImplicit.Body = new Block(statements = new StatementList(3));
+ statements.Add(new AssignmentStatement(new MemberBinding(resultAddr, tagField), new Literal(i, CoreSystemTypes.UInt32)));
+ Parameter p0 = opImplicit.Parameters[0];
+ p0.Type = t;
+ Expression val = p0;
+ if (isValueType) val = new BinaryExpression(val, tExpr, NodeType.Box, CoreSystemTypes.Object);
+ statements.Add(new AssignmentStatement(new MemberBinding(resultAddr, valueField), val));
+ statements.Add(new Return(result));
+ Method opExplicit = (Method)members[8+i*2];
+ opExplicit.ReturnType = t;
+ opExplicit.Body = new Block(statements = new StatementList(1));
+ Expression loadValue = new MemberBinding(new UnaryExpression(opExplicit.Parameters[0], NodeType.AddressOf), valueField);
+ if (isValueType)
+ val = new AddressDereference(new BinaryExpression(loadValue, tExpr, NodeType.Unbox), t);
+ else
+ val = new BinaryExpression(loadValue, tExpr, NodeType.Castclass);
+ statements.Add(new Return(val));
+ }
+ }
+ }
+ /// <summary>
+ /// Bundles a type with a boolean expression. The bundle is a subtype of the given type.
+ /// The class is a struct with a single private field of the given type and implicit coercions to and from the underlying type.
+ /// The to coercion checks that the constraint is satisfied and throws ArgumentOutOfRangeException if not.
+ /// </summary>
+ public class ConstrainedType : Struct{
+ protected TypeNode underlyingType;
+ public TypeNode UnderlyingTypeExpression;
+ public Expression Constraint;
+ public ConstrainedType(TypeNode/*!*/ underlyingType, Expression/*!*/ constraint) {
+ this.NodeType = NodeType.ConstrainedType;
+ this.underlyingType = underlyingType;
+ this.Flags = TypeFlags.Public|TypeFlags.Sealed|TypeFlags.SpecialName;
+ this.Constraint = constraint;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = Identifier.For("Constrained type:"+base.UniqueKey);
+ this.Interfaces = new InterfaceList(SystemTypes.ConstrainedType);
+ }
+ public ConstrainedType(TypeNode/*!*/ underlyingType, Expression/*!*/ constraint, TypeNode/*!*/ declaringType) {
+ this.NodeType = NodeType.ConstrainedType;
+ this.underlyingType = underlyingType;
+ this.Flags = TypeFlags.NestedPublic|TypeFlags.Sealed|TypeFlags.SpecialName;
+ this.Constraint = constraint;
+ this.Namespace = StandardIds.StructuralTypes;
+ this.Name = Identifier.For("Constrained type:"+base.UniqueKey);
+ this.Interfaces = new InterfaceList(SystemTypes.ConstrainedType);
+ this.DeclaringType = declaringType;
+ this.DeclaringModule = declaringType.DeclaringModule;
+ declaringType.Members.Add(this);
+ }
+ internal ConstrainedType(NestedTypeProvider provideNestedTypes, TypeAttributeProvider provideAttributes, TypeMemberProvider provideMembers, object handle)
+ : base(provideNestedTypes, provideAttributes, provideMembers, handle) {
+ this.NodeType = NodeType.ConstrainedType;
+ this.typeCode = ElementType.ValueType;
+ }
+ public override bool IsStructural{
+ get{return true;}
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes{
+ get{
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(1);
+ result.Add(this.UnderlyingType);
+ return result;
+ }
+ }
+ public virtual void ProvideMembers(){
+ MemberList members = this.members = new MemberList();
+ //Value field
+ Field valueField = new Field(this, null, FieldFlags.Assembly, StandardIds.Value, this.underlyingType, null);
+ members.Add(valueField);
+ //Implicit conversion from this type to underlying type
+ ParameterList parameters = new ParameterList(1);
+ Parameter valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, this, null, null);
+ parameters.Add(valuePar);
+ Method toUnderlying = new Method(this, null, StandardIds.opImplicit, parameters, this.underlyingType, null);
+ toUnderlying.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(toUnderlying);
+ //Implicit conversion from underlying type to this type
+ parameters = new ParameterList(1);
+ parameters.Add(valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, this.underlyingType, null, null));
+ Method fromUnderlying = new Method(this, null, StandardIds.opImplicit, parameters, this, null);
+ fromUnderlying.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ members.Add(fromUnderlying);
+ this.AddCoercionWrappers(this.UnderlyingType.ExplicitCoercionMethods, StandardIds.opExplicit, fromUnderlying, toUnderlying);
+ this.AddCoercionWrappers(this.UnderlyingType.ImplicitCoercionMethods, StandardIds.opImplicit, fromUnderlying, toUnderlying);
+ }
+ private void AddCoercionWrappers(MemberList/*!*/ coercions, Identifier/*!*/ id, Method/*!*/ fromUnderlying, Method/*!*/ toUnderlying) {
+ MemberList members = this.members;
+ for (int i = 0, n = coercions.Count; i < n; i++){
+ Method coercion = coercions[i] as Method;
+ if (coercion == null || coercion.Parameters == null || coercion.Parameters.Count != 1) continue;
+ ParameterList parameters = new ParameterList(1);
+ Parameter valuePar = new Parameter(null, ParameterFlags.None, StandardIds.Value, null, null, null);
+ parameters.Add(valuePar);
+ Method m = new Method(this, null, id, parameters, null, null);
+ m.Flags = MethodFlags.Static|MethodFlags.SpecialName|MethodFlags.Public;
+ Expression arg = valuePar;
+ MethodCall call = new MethodCall(new MemberBinding(null, coercion), new ExpressionList(arg));
+ if (coercion.ReturnType == this.UnderlyingType){
+ m.ReturnType = this;
+ valuePar.Type = coercion.Parameters[0].Type;
+ call = new MethodCall(new MemberBinding(null, fromUnderlying), new ExpressionList(call));
+ }else{
+ m.ReturnType = coercion.ReturnType;
+ valuePar.Type = this;
+ call.Operands[0] = new MethodCall(new MemberBinding(null, toUnderlying), new ExpressionList(arg));
+ }
+ m.Body = new Block(new StatementList(new Return(call)));
+ members.Add(m);
+ }
+ }
+ public void ProvideBodiesForMethods(){
+ MemberList members = this.members;
+ if (members == null) return;
+ Field valueField = (Field)members[0];
+ //Implicit conversion from this type to underlying type
+ Method toUnderlying = (Method)members[1];
+ Parameter valuePar = toUnderlying.Parameters[0];
+ StatementList statements = new StatementList(1);
+ statements.Add(new Return(new MemberBinding(new UnaryExpression(valuePar, NodeType.AddressOf), valueField)));
+ toUnderlying.Body = new Block(statements);
+ //Implicit conversion from underlying type to this type
+ Method fromUnderlying = (Method)members[2];
+ valuePar = fromUnderlying.Parameters[0];
+ statements = new StatementList(4);
+ fromUnderlying.Body = new Block(statements);
+ Block succeed = new Block();
+ Local temp = new Local(Identifier.Empty, this);
+ statements.Add(new Branch(this.Constraint, succeed));
+ InstanceInitializer constr = SystemTypes.ArgumentOutOfRangeException.GetConstructor();
+ if (constr == null) { Debug.Fail(""); return; }
+ MemberBinding argException = new MemberBinding(null, constr);
+ statements.Add(new Throw(new Construct(argException, null)));
+ statements.Add(succeed);
+ statements.Add(new AssignmentStatement(new MemberBinding(new UnaryExpression(temp, NodeType.AddressOf), valueField), valuePar));
+ statements.Add(new Return(temp));
+ }
+ public TypeNode UnderlyingType{
+ get{
+ TypeNode underlyingType = this.underlyingType;
+ if (underlyingType == null){
+ Field f = this.GetField(StandardIds.Value);
+ if (f != null)
+ this.underlyingType = underlyingType = f.Type;
+ }
+ return underlyingType;
+ }
+ set{
+ this.underlyingType = value;
+ }
+ }
+ }
+#endif
+ public abstract class TypeModifier : TypeNode
+ {
+ private TypeNode/*!*/ modifier;
+ private TypeNode/*!*/ modifiedType;
+#if !MinimalReader
+ public TypeNode ModifierExpression;
+ public TypeNode ModifiedTypeExpression;
+#endif
+ internal TypeModifier(NodeType type, TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
+ : base(type)
+ {
+ this.modifier = modifier;
+ this.modifiedType = modified;
+ this.DeclaringModule = modified.DeclaringModule;
+ this.Namespace = modified.Namespace;
+ if (type == NodeType.OptionalModifier)
+ {
+ this.typeCode = ElementType.OptionalModifier;
+ this.Name = Identifier.For("optional(" + modifier.Name + ") " + modified.Name);
+ this.fullName = "optional(" + modifier.FullName + ") " + modified.FullName;
+ }
+ else
+ {
+ this.typeCode = ElementType.RequiredModifier;
+ this.Name = Identifier.For("required(" + modifier.Name + ") " + modified.Name);
+ this.fullName = "required(" + modifier.FullName + ") " + modified.FullName;
+ }
+ this.Flags = modified.Flags;
+ }
+ public TypeNode/*!*/ Modifier
+ {
+ get { return this.modifier; }
+ set { this.modifier = value; }
+ }
+ public TypeNode/*!*/ ModifiedType
+ {
+ get { return this.modifiedType; }
+ set { this.modifiedType = value; }
+ }
+ public override Node/*!*/ Clone()
+ {
+ Debug.Assert(false);
+ return base.Clone();
+ }
+ public override string GetFullUnmangledNameWithoutTypeParameters()
+ {
+ return this.ModifiedType.GetFullUnmangledNameWithoutTypeParameters();
+ }
+ public override string GetFullUnmangledNameWithTypeParameters()
+ {
+ return this.ModifiedType.GetFullUnmangledNameWithTypeParameters();
+ }
+ public override string/*!*/ GetUnmangledNameWithoutTypeParameters()
+ {
+ return this.ModifiedType.GetUnmangledNameWithoutTypeParameters();
+ }
+ public override bool IsUnmanaged
+ {
+ get { return this.ModifiedType.IsUnmanaged; }
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ if (this.NodeType != type.NodeType) return false;
+ TypeModifier t = type as TypeModifier;
+ if (t == null) { Debug.Assert(false); return false; }
+ if (this.Modifier != t.Modifier && (this.Modifier == null || !this.Modifier.IsStructurallyEquivalentTo(t.Modifier)))
+ return false;
+ if (this.ModifiedType != t.ModifiedType && (this.ModifiedType == null || !this.ModifiedType.IsStructurallyEquivalentTo(t.ModifiedType)))
+ return false;
+ return true;
+ }
+ public override bool IsValueType
+ {
+ get
+ {
+ return this.ModifiedType.IsValueType;
+ }
+ }
+
+ public override bool IsPointerType
+ {
+ get
+ {
+ return this.ModifiedType.IsPointerType;
+ }
+ }
+
+#if ExtendedRuntime
+ public override bool IsReferenceType {
+ get {
+ return this.ModifiedType.IsReferenceType;
+ }
+ }
+#endif
+
+ public override bool IsTemplateParameter
+ {
+ get
+ {
+ return this.ModifiedType.IsTemplateParameter;
+ }
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList(2);
+ result.Add(this.ModifiedType);
+ result.Add(this.Modifier);
+ return result;
+ }
+ }
+#if FxCop
+ internal override void GetName(TypeFormat options, StringBuilder name)
+ {
+ if (options.ShowTypeModifiers)
+ {
+ base.GetName(options, name);
+ return;
+ }
+ this.modifiedType.GetName(options, name);
+ }
+#endif
+ }
+ public class OptionalModifier : TypeModifier
+ {
+ internal OptionalModifier(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
+ : base(NodeType.OptionalModifier, modifier, modified)
+ {
+ }
+ public static OptionalModifier/*!*/ For(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
+ {
+ return (OptionalModifier)modified.GetModified(modifier, true);
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ this.ModifiedType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('!');
+ this.Modifier.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ }
+#endif
+ }
+ public class RequiredModifier : TypeModifier
+ {
+ internal RequiredModifier(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
+ : base(NodeType.RequiredModifier, modifier, modified)
+ {
+ }
+ public static RequiredModifier/*!*/ For(TypeNode/*!*/ modifier, TypeNode/*!*/ modified)
+ {
+ return (RequiredModifier)modified.GetModified(modifier, false);
+ }
+#if !NoXml
+ internal override void AppendDocumentIdMangledName(StringBuilder/*!*/ sb, TypeNodeList methodTypeParameters, TypeNodeList typeParameters)
+ {
+ this.ModifiedType.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ sb.Append('|');
+ this.Modifier.AppendDocumentIdMangledName(sb, methodTypeParameters, typeParameters);
+ }
+#endif
+ }
+#if !MinimalReader
+ public class OptionalModifierTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ModifiedType;
+ public TypeNode Modifier;
+
+ public OptionalModifierTypeExpression(TypeNode elementType, TypeNode modifier)
+ : base(NodeType.OptionalModifierTypeExpression)
+ {
+ this.ModifiedType = elementType;
+ this.Modifier = modifier;
+ }
+ public OptionalModifierTypeExpression(TypeNode elementType, TypeNode modifier, SourceContext sctx)
+ : this(elementType, modifier)
+ {
+ this.SourceContext = sctx;
+ }
+ /// <summary>
+ /// Only needed because IsUnmanaged test is performed in the Looker rather than checker. Once the test
+ /// is moved, this code can be removed.
+ /// </summary>
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ return this.ModifiedType == null ? false : this.ModifiedType.IsUnmanaged;
+ }
+ }
+
+ }
+ public class RequiredModifierTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ModifiedType;
+ public TypeNode Modifier;
+
+ public RequiredModifierTypeExpression(TypeNode elementType, TypeNode modifier)
+ : base(NodeType.RequiredModifierTypeExpression)
+ {
+ this.ModifiedType = elementType;
+ this.Modifier = modifier;
+ }
+ public RequiredModifierTypeExpression(TypeNode elementType, TypeNode modifier, SourceContext sctx)
+ : this(elementType, modifier)
+ {
+ this.SourceContext = sctx;
+ }
+ /// <summary>
+ /// Can be removed once the Unmanaged check moves from Looker to Checker.
+ /// </summary>
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ return this.ModifiedType == null ? false : this.ModifiedType.IsUnmanaged;
+ }
+ }
+
+ }
+#endif
+ public class FunctionPointer : TypeNode
+ {
+ internal FunctionPointer(TypeNodeList parameterTypes, TypeNode/*!*/ returnType, Identifier name)
+ : base(NodeType.FunctionPointer)
+ {
+ this.Name = name;
+ this.Namespace = returnType.Namespace;
+ this.parameterTypes = parameterTypes;
+ this.returnType = returnType;
+ this.typeCode = ElementType.FunctionPointer;
+ this.varArgStart = int.MaxValue;
+ }
+ private CallingConventionFlags callingConvention;
+ public CallingConventionFlags CallingConvention
+ {
+ get { return this.callingConvention; }
+ set { this.callingConvention = value; }
+ }
+ private TypeNodeList parameterTypes;
+ public TypeNodeList ParameterTypes
+ {
+ get { return this.parameterTypes; }
+ set { this.parameterTypes = value; }
+ }
+ private TypeNode returnType;
+ public TypeNode ReturnType
+ {
+ get { return this.returnType; }
+ set { this.returnType = value; }
+ }
+ private int varArgStart;
+ public int VarArgStart
+ {
+ get { return this.varArgStart; }
+ set { this.varArgStart = value; }
+ }
+ public override bool IsStatic
+ {
+ get { return (this.CallingConvention & CallingConventionFlags.HasThis) == 0; }
+ }
+ public override bool IsStructural
+ {
+ get { return true; }
+ }
+ protected TypeNodeList structuralElementTypes;
+ public override TypeNodeList StructuralElementTypes
+ {
+ get
+ {
+ TypeNodeList result = this.structuralElementTypes;
+ if (result != null) return result;
+ this.structuralElementTypes = result = new TypeNodeList();
+ result.Add(this.ReturnType);
+ TypeNodeList ptypes = this.ParameterTypes;
+ for (int i = 0, n = ptypes == null ? 0 : ptypes.Count; i < n; i++)
+ {
+ TypeNode ptype = ptypes[i];
+ if (ptype == null) continue;
+ result.Add(ptype);
+ }
+ return result;
+ }
+ }
+ public override bool IsStructurallyEquivalentTo(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this == type) return true;
+ FunctionPointer t = type as FunctionPointer;
+ if (t == null) return false;
+ if (this.Flags != t.Flags || this.CallingConvention != t.CallingConvention || this.VarArgStart != t.VarArgStart) return false;
+ if (this.ReturnType == null || t.ReturnType == null) return false;
+ if (this.ReturnType != t.ReturnType && !this.ReturnType.IsStructurallyEquivalentTo(t.ReturnType)) return false;
+ return this.IsStructurallyEquivalentList(this.ParameterTypes, t.ParameterTypes);
+ }
+ public static FunctionPointer/*!*/ For(TypeNodeList/*!*/ parameterTypes, TypeNode/*!*/ returnType)
+ {
+ Module mod = returnType.DeclaringModule;
+ if (mod == null) { Debug.Fail(""); mod = new Module(); }
+ StringBuilder sb = new StringBuilder("function pointer ");
+ sb.Append(returnType.FullName);
+ sb.Append('(');
+ for (int i = 0, n = parameterTypes == null ? 0 : parameterTypes.Count; i < n; i++)
+ {
+ TypeNode type = parameterTypes[i];
+ if (type == null) continue;
+ if (i != 0) sb.Append(',');
+ sb.Append(type.FullName);
+ }
+ sb.Append(')');
+ Identifier name = Identifier.For(sb.ToString());
+ TypeNode t = mod.GetStructurallyEquivalentType(returnType.Namespace, name);
+ int counter = 1;
+ while (t != null)
+ {
+ FunctionPointer fp = t as FunctionPointer;
+ if (fp != null)
+ {
+ if (fp.ReturnType == returnType && FunctionPointer.ParameterTypesAreEquivalent(fp.ParameterTypes, parameterTypes))
+ return fp;
+ }
+ name = Identifier.For(name.ToString() + counter++);
+ t = mod.GetStructurallyEquivalentType(returnType.Namespace, name);
+ }
+ FunctionPointer result = t as FunctionPointer;
+ if (result == null)
+ {
+ result = new FunctionPointer(parameterTypes, returnType, name);
+ result.DeclaringModule = mod;
+ mod.StructurallyEquivalentType[name.UniqueIdKey] = result;
+ }
+ return result;
+ }
+ private static bool ParameterTypesAreEquivalent(TypeNodeList list1, TypeNodeList list2)
+ {
+ if (list1 == null || list2 == null) return list1 == list2;
+ int n = list1.Count;
+ if (n != list2.Count) return false;
+ for (int i = 0; i < n; i++)
+ if (list1[i] != list2[i]) return false;
+ return true;
+ }
+ }
+ public interface ISymbolicTypeReference
+ {
+ }
+#if !MinimalReader
+ public class ArrayTypeExpression : ArrayType, ISymbolicTypeReference
+ {
+ //TODO: add expressions for elementType, rank, sizes and lowerbounds
+ public bool LowerBoundIsUnknown;
+ public ArrayTypeExpression()
+ : base()
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank)
+ : base(elementType, rank)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes)
+ : base(elementType, rank, sizes)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds)
+ : base(elementType, rank, sizes, sizes)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, SourceContext sctx)
+ : base(elementType, rank)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ this.SourceContext = sctx;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, SourceContext sctx)
+ : base(elementType, rank, sizes)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ this.SourceContext = sctx;
+ }
+ public ArrayTypeExpression(TypeNode/*!*/ elementType, int rank, int[] sizes, int[] lowerBounds, SourceContext sctx)
+ : base(elementType, rank, sizes, sizes)
+ {
+ this.NodeType = NodeType.ArrayTypeExpression;
+ this.SourceContext = sctx;
+ }
+ }
+ public class ClassExpression : Class, ISymbolicTypeReference
+ {
+ public Expression Expression;
+
+ public ClassExpression(Expression expression)
+ {
+ this.NodeType = NodeType.ClassExpression;
+ this.Expression = expression;
+ }
+ public ClassExpression(Expression expression, TypeNodeList templateArguments)
+ {
+ this.NodeType = NodeType.ClassExpression;
+ this.Expression = expression;
+ this.TemplateArguments = templateArguments;
+ if (templateArguments != null) this.TemplateArgumentExpressions = templateArguments.Clone();
+ }
+ public ClassExpression(Expression expression, SourceContext sctx)
+ {
+ this.NodeType = NodeType.ClassExpression;
+ this.Expression = expression;
+ this.SourceContext = sctx;
+ }
+ public ClassExpression(Expression expression, TypeNodeList templateArguments, SourceContext sctx)
+ {
+ this.NodeType = NodeType.ClassExpression;
+ this.Expression = expression;
+ this.TemplateArguments = this.TemplateArgumentExpressions = templateArguments;
+ if (templateArguments != null) this.TemplateArgumentExpressions = templateArguments.Clone();
+ this.SourceContext = sctx;
+ }
+ }
+#endif
+ public class InterfaceExpression : Interface, ISymbolicTypeReference
+ {
+ private Expression expression;
+ public InterfaceExpression(Expression expression)
+ : base(null)
+ {
+ this.NodeType = NodeType.InterfaceExpression;
+ this.Expression = expression;
+ }
+#if !MinimalReader
+ public InterfaceExpression(Expression expression, SourceContext sctx)
+ : base(null)
+ {
+ this.NodeType = NodeType.InterfaceExpression;
+ this.Expression = expression;
+ this.SourceContext = sctx;
+ }
+#endif
+ public Expression Expression
+ {
+ get { return this.expression; }
+ set { this.expression = value; }
+ }
+ }
+#if !MinimalReader
+ public class FlexArrayTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public FlexArrayTypeExpression(TypeNode elementType)
+ : base(NodeType.FlexArrayTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public FlexArrayTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.FlexArrayTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class FunctionTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public ParameterList Parameters;
+ public TypeNode ReturnType;
+ public FunctionTypeExpression(TypeNode returnType, ParameterList parameters)
+ : base(NodeType.FunctionTypeExpression)
+ {
+ this.ReturnType = returnType;
+ this.Parameters = parameters;
+ }
+ public FunctionTypeExpression(TypeNode returnType, ParameterList parameters, SourceContext sctx)
+ : base(NodeType.FunctionTypeExpression)
+ {
+ this.ReturnType = returnType;
+ this.Parameters = parameters;
+ this.SourceContext = sctx;
+ }
+ }
+ public class PointerTypeExpression : Pointer, ISymbolicTypeReference
+ {
+ public PointerTypeExpression(TypeNode/*!*/ elementType)
+ : base(elementType)
+ {
+ this.NodeType = NodeType.PointerTypeExpression;
+ }
+ public PointerTypeExpression(TypeNode/*!*/ elementType, SourceContext sctx)
+ : base(elementType)
+ {
+ this.NodeType = NodeType.PointerTypeExpression;
+ this.SourceContext = sctx;
+ }
+ /// <summary>
+ /// This is only needed because the Unmanaged test is done in the Looker rather than the checker.
+ /// (Once the check moves, this can be removed).
+ /// </summary>
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ }
+ public class ReferenceTypeExpression : Reference, ISymbolicTypeReference
+ {
+ public ReferenceTypeExpression(TypeNode/*!*/ elementType)
+ : base(elementType)
+ {
+ this.NodeType = NodeType.ReferenceTypeExpression;
+ }
+ public ReferenceTypeExpression(TypeNode/*!*/ elementType, SourceContext sctx)
+ : base(elementType)
+ {
+ this.NodeType = NodeType.ReferenceTypeExpression;
+ this.SourceContext = sctx;
+ }
+ }
+ public class StreamTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public StreamTypeExpression(TypeNode elementType)
+ : base(NodeType.StreamTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public StreamTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.StreamTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class NonEmptyStreamTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public NonEmptyStreamTypeExpression(TypeNode elementType)
+ : base(NodeType.NonEmptyStreamTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public NonEmptyStreamTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.NonEmptyStreamTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class BoxedTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public BoxedTypeExpression(TypeNode elementType)
+ : base(NodeType.BoxedTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public BoxedTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.BoxedTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class InvariantTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public InvariantTypeExpression(TypeNode elementType)
+ : base(NodeType.InvariantTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public InvariantTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.InvariantTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class NonNullTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public NonNullTypeExpression(TypeNode elementType)
+ : base(NodeType.NonNullTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public NonNullTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.NonNullTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class NonNullableTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public NonNullableTypeExpression(TypeNode elementType)
+ : base(NodeType.NonNullableTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public NonNullableTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.NonNullableTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class NullableTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNode ElementType;
+ public NullableTypeExpression(TypeNode elementType)
+ : base(NodeType.NullableTypeExpression)
+ {
+ this.ElementType = elementType;
+ }
+ public NullableTypeExpression(TypeNode elementType, SourceContext sctx)
+ : base(NodeType.NullableTypeExpression)
+ {
+ this.ElementType = elementType;
+ this.SourceContext = sctx;
+ }
+ }
+ public class TupleTypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public FieldList Domains;
+ public TupleTypeExpression(FieldList domains)
+ : base(NodeType.TupleTypeExpression)
+ {
+ this.Domains = domains;
+ }
+ public TupleTypeExpression(FieldList domains, SourceContext sctx)
+ : base(NodeType.TupleTypeExpression)
+ {
+ this.Domains = domains;
+ this.SourceContext = sctx;
+ }
+ }
+ public class TypeIntersectionExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNodeList Types;
+ public TypeIntersectionExpression(TypeNodeList types)
+ : base(NodeType.TypeIntersectionExpression)
+ {
+ this.Types = types;
+ }
+ public TypeIntersectionExpression(TypeNodeList types, SourceContext sctx)
+ : base(NodeType.TypeIntersectionExpression)
+ {
+ this.Types = types;
+ this.SourceContext = sctx;
+ }
+ }
+ public class TypeUnionExpression : TypeNode, ISymbolicTypeReference
+ {
+ public TypeNodeList Types;
+ public TypeUnionExpression(TypeNodeList types)
+ : base(NodeType.TypeUnionExpression)
+ {
+ this.Types = types;
+ }
+ public TypeUnionExpression(TypeNodeList types, SourceContext sctx)
+ : base(NodeType.TypeUnionExpression)
+ {
+ this.Types = types;
+ this.SourceContext = sctx;
+ }
+ }
+ public class TypeExpression : TypeNode, ISymbolicTypeReference
+ {
+ public Expression Expression;
+ public int Arity;
+
+ public TypeExpression(Expression expression)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ }
+ public TypeExpression(Expression expression, TypeNodeList templateArguments)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ this.templateArguments = this.TemplateArgumentExpressions = templateArguments;
+ }
+ public TypeExpression(Expression expression, int arity)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ this.Arity = arity;
+ }
+ public TypeExpression(Expression expression, SourceContext sctx)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ this.SourceContext = sctx;
+ }
+ public TypeExpression(Expression expression, TypeNodeList templateArguments, SourceContext sctx)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ this.templateArguments = this.TemplateArgumentExpressions = templateArguments;
+ this.SourceContext = sctx;
+ }
+ public TypeExpression(Expression expression, int arity, SourceContext sctx)
+ : base(NodeType.TypeExpression)
+ {
+ this.Expression = expression;
+ this.Arity = arity;
+ this.SourceContext = sctx;
+ }
+ public override bool IsUnmanaged
+ {
+ get
+ {
+ Literal lit = this.Expression as Literal;
+ if (lit != null)
+ {
+ TypeNode t = lit.Value as TypeNode;
+ if (t != null) return t.IsUnmanaged;
+ if (lit.Value is TypeCode) return true;
+ }
+ return true;
+ }
+ }
+ }
+ public class TypeReference : Node
+ {
+ public TypeNode Type;
+ public TypeNode Expression;
+
+ public TypeReference(TypeNode typeExpression)
+ : base(NodeType.TypeReference)
+ {
+ this.Expression = typeExpression;
+ if (typeExpression != null)
+ this.SourceContext = typeExpression.SourceContext;
+ }
+ public TypeReference(TypeNode typeExpression, TypeNode type)
+ : base(NodeType.TypeReference)
+ {
+ this.Expression = typeExpression;
+ this.Type = type;
+ if (typeExpression != null)
+ this.SourceContext = typeExpression.SourceContext;
+ }
+ public static explicit operator TypeNode(TypeReference typeReference)
+ {
+ return null == (object)typeReference ? null : typeReference.Type;
+ }
+ public static bool operator ==(TypeReference typeReference, TypeNode type)
+ {
+ return null == (object)typeReference ? null == (object)type : typeReference.Type == type;
+ }
+ public static bool operator ==(TypeNode type, TypeReference typeReference)
+ {
+ return null == (object)typeReference ? null == (object)type : typeReference.Type == type;
+ }
+ public static bool operator !=(TypeReference typeReference, TypeNode type)
+ {
+ return null == (object)typeReference ? null != (object)type : typeReference.Type != type;
+ }
+ public static bool operator !=(TypeNode type, TypeReference typeReference)
+ {
+ return null == (object)typeReference ? null != (object)type : typeReference.Type != type;
+ }
+ public override bool Equals(object obj)
+ {
+ return obj == (object)this || obj == (object)this.Type;
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ }
+ public class ArglistArgumentExpression : NaryExpression
+ {
+ public ArglistArgumentExpression(ExpressionList args, SourceContext sctx)
+ : base(args, NodeType.ArglistArgumentExpression)
+ {
+ this.SourceContext = sctx;
+ }
+ }
+ public class ArglistExpression : Expression
+ {
+ public ArglistExpression(SourceContext sctx)
+ : base(NodeType.ArglistExpression)
+ {
+ this.SourceContext = sctx;
+ }
+ }
+ public class RefValueExpression : BinaryExpression
+ {
+ public RefValueExpression(Expression typedreference, Expression type, SourceContext sctx)
+ : base(typedreference, type, NodeType.RefValueExpression)
+ {
+ this.SourceContext = sctx;
+ }
+
+ }
+ public class RefTypeExpression : UnaryExpression
+ {
+ public RefTypeExpression(Expression typedreference, SourceContext sctx)
+ : base(typedreference, NodeType.RefTypeExpression)
+ {
+ this.SourceContext = sctx;
+ }
+
+ }
+#endif
+#if ExtendedRuntime
+ public delegate Expression Coercer(Expression source, TypeNode targetType, TypeViewer typeViewer);
+ public sealed class StreamAdapter{
+ private StreamAdapter(){}
+ public static TypeNode For(Interface/*!*/ sourceStream, Interface/*!*/ targetStream, Module/*!*/ module, Coercer/*!*/ coercer, SourceContext sctx) {
+ return StreamAdapter.For(sourceStream, targetStream, null, module, coercer, sctx);
+ }
+ public static TypeNode For(Interface /*!*/sourceStream, Interface/*!*/ targetStream, TypeNode/*!*/ referringType, Coercer/*!*/ coercer, SourceContext sctx) {
+ if (referringType == null){Debug.Assert(false); return null;}
+ return StreamAdapter.For(sourceStream, targetStream, referringType, referringType.DeclaringModule, coercer, sctx);
+ }
+ public static TypeNode For(Interface/*!*/ sourceStream, Interface/*!*/ targetStream, TypeNode referringType, Module/*!*/ module, Coercer/*!*/ coercer, SourceContext sctx) {
+ Debug.Assert(sourceStream.Template == SystemTypes.GenericIEnumerable && targetStream.Template == SystemTypes.GenericIEnumerable);
+ Identifier id = Identifier.For("AdapterFor" + sourceStream.Name + "To" + targetStream.Name);
+ for (int i = 1; ;i++){
+ TypeNode t = module.GetStructurallyEquivalentType(targetStream.Namespace, id);
+ if (t == null) break;
+ if (t.IsAssignableTo(targetStream)){
+ InstanceInitializer cons = t.GetConstructor(sourceStream);
+ if (cons != null) return t;
+ }
+ id = Identifier.For(id.ToString()+i);
+ }
+ Method sGetEnumerator = sourceStream.GetMethod(StandardIds.GetEnumerator);
+ Method tGetEnumerator = targetStream.GetMethod(StandardIds.GetEnumerator);
+ if (sGetEnumerator == null || tGetEnumerator == null) { Debug.Fail(""); return null; }
+ Interface sGetEnumeratorReturnType = (Interface)TypeNode.StripModifiers(sGetEnumerator.ReturnType);
+ Interface tGetEnumeratorReturnType = (Interface)TypeNode.StripModifiers(tGetEnumerator.ReturnType);
+ //^ assert sGetEnumeratorReturnType != null && tGetEnumeratorReturnType != null;
+ TypeNode enumeratorAdapter = null;
+ if (referringType != null)
+ enumeratorAdapter = EnumeratorAdapter.For(id, sGetEnumeratorReturnType, tGetEnumeratorReturnType, referringType, coercer, sctx);
+ else
+ enumeratorAdapter = EnumeratorAdapter.For(id, sGetEnumeratorReturnType, tGetEnumeratorReturnType, module, coercer, sctx);
+ if (enumeratorAdapter == null) return null;
+ InterfaceList interfaces = new InterfaceList(targetStream);
+ MemberList members = new MemberList(3);
+ Class adapter = new Class(module, null, null, TypeFlags.Sealed, targetStream.Namespace, id, CoreSystemTypes.Object, interfaces, members);
+ adapter.IsNormalized = true;
+ if (referringType == null ||
+ (sourceStream.Flags & TypeFlags.VisibilityMask) == TypeFlags.Public && (targetStream.Flags & TypeFlags.VisibilityMask) == TypeFlags.Public){
+ adapter.Flags |= TypeFlags.Public;
+ module.Types.Add(adapter);
+ }else{
+ adapter.Flags |= TypeFlags.NestedPrivate;
+ referringType.Members.Add(adapter);
+ adapter.DeclaringType = referringType;
+ }
+ module.StructurallyEquivalentType[id.UniqueIdKey] = adapter;
+
+ //Field to hold source stream
+ Field ssField = new Field(adapter, null, FieldFlags.Private, StandardIds.Value, sourceStream, null);
+ members.Add(ssField);
+
+ //Constructor
+ This ThisParameter = new This(adapter);
+ Parameter par = new Parameter(null, ParameterFlags.None, StandardIds.Value, sourceStream, null, null);
+ StatementList statements = new StatementList(3);
+ InstanceInitializer cstr = CoreSystemTypes.Object.GetConstructor();
+ if (cstr == null) { Debug.Fail(""); return adapter; }
+ MethodCall mcall = new MethodCall(new MemberBinding(ThisParameter, cstr), new ExpressionList(0), NodeType.Call, CoreSystemTypes.Void);
+ statements.Add(new ExpressionStatement(mcall));
+ statements.Add(new AssignmentStatement(new MemberBinding(ThisParameter, ssField), par));
+ statements.Add(new Return());
+ InstanceInitializer acons = new InstanceInitializer(adapter, null, new ParameterList(par), new Block(statements));
+ acons.Flags |= MethodFlags.Public;
+ acons.ThisParameter = ThisParameter;
+ members.Add(acons);
+
+ //GetEnumerator
+ ThisParameter = new This(adapter);
+ statements = new StatementList(1);
+ mcall = new MethodCall(new MemberBinding(new MemberBinding(ThisParameter, ssField), sGetEnumerator),
+ new ExpressionList(0), NodeType.Callvirt, sGetEnumerator.ReturnType);
+ cstr = enumeratorAdapter.GetConstructor(sGetEnumerator.ReturnType);
+ if (cstr == null) { Debug.Fail(""); return adapter; }
+ Construct constr = new Construct(new MemberBinding(null, cstr), new ExpressionList(mcall));
+ statements.Add(new Return(constr));
+ Method getEnumerator = new Method(adapter, null, StandardIds.GetEnumerator, null, tGetEnumerator.ReturnType, new Block(statements));
+ getEnumerator.Flags = MethodFlags.Public | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.HideBySig;
+ getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
+ getEnumerator.ThisParameter = ThisParameter;
+ members.Add(getEnumerator);
+
+ //IEnumerable.GetEnumerator
+ Method ieGetEnumerator = SystemTypes.IEnumerable.GetMethod(StandardIds.GetEnumerator);
+ if (ieGetEnumerator == null) { Debug.Fail(""); return adapter; }
+ ThisParameter = new This(adapter);
+ statements = new StatementList(1);
+ mcall = new MethodCall(new MemberBinding(new MemberBinding(ThisParameter, ssField), ieGetEnumerator),
+ new ExpressionList(0), NodeType.Callvirt, SystemTypes.IEnumerator);
+ statements.Add(new Return(mcall));
+ getEnumerator = new Method(adapter, null, StandardIds.IEnumerableGetEnumerator, null, SystemTypes.IEnumerator, new Block(statements));
+ getEnumerator.ThisParameter = ThisParameter;
+ getEnumerator.ImplementedInterfaceMethods = new MethodList(ieGetEnumerator);
+ getEnumerator.CallingConvention = CallingConventionFlags.HasThis;
+ getEnumerator.Flags = MethodFlags.Private | MethodFlags.Virtual | MethodFlags.SpecialName;
+ members.Add(getEnumerator);
+
+ return adapter;
+ }
+ }
+ internal sealed class EnumeratorAdapter{
+ private EnumeratorAdapter(){}
+ internal static TypeNode For(Identifier/*!*/ id, Interface/*!*/ sourceIEnumerator, Interface/*!*/ targetIEnumerator, Module/*!*/ module, Coercer/*!*/ coercer, SourceContext sctx) {
+ return EnumeratorAdapter.For(id, sourceIEnumerator, targetIEnumerator, null, module, coercer, sctx);
+ }
+ internal static TypeNode For(Identifier/*!*/ id, Interface/*!*/ sourceIEnumerator, Interface/*!*/ targetIEnumerator, TypeNode/*!*/ referringType, Coercer/*!*/ coercer, SourceContext sctx) {
+ if (referringType == null){Debug.Assert(false); return null;}
+ return EnumeratorAdapter.For(id, sourceIEnumerator, targetIEnumerator, referringType, referringType.DeclaringModule, coercer, sctx);
+ }
+ private static TypeNode For(Identifier/*!*/ id, Interface/*!*/ sourceIEnumerator, Interface/*!*/ targetIEnumerator, TypeNode referringType, Module/*!*/ module, Coercer/*!*/ coercer, SourceContext sctx) {
+ Method sGetCurrent = sourceIEnumerator.GetMethod(StandardIds.getCurrent);
+ if (sGetCurrent == null) { Debug.Fail(""); return null; }
+ Method sMoveNext = sourceIEnumerator.GetMethod(StandardIds.MoveNext);
+ if (sMoveNext == null) sMoveNext = SystemTypes.IEnumerator.GetMethod(StandardIds.MoveNext);
+ Method tGetCurrent = targetIEnumerator.GetMethod(StandardIds.getCurrent);
+ if (tGetCurrent == null) { Debug.Fail(""); return null; }
+ Method tMoveNext = targetIEnumerator.GetMethod(StandardIds.MoveNext);
+ if (tMoveNext == null) tMoveNext = SystemTypes.IEnumerator.GetMethod(StandardIds.MoveNext);
+ Local loc = new Local(sGetCurrent.ReturnType);
+ Expression curr = coercer(loc, tGetCurrent.ReturnType, null);
+ if (curr == null) return null;
+ id = Identifier.For("Enumerator"+id.ToString());
+ InterfaceList interfaces = new InterfaceList(targetIEnumerator, SystemTypes.IDisposable);
+ MemberList members = new MemberList(5);
+ Class adapter = new Class(module, null, null, TypeFlags.Public, targetIEnumerator.Namespace, id, CoreSystemTypes.Object, interfaces, members);
+ adapter.IsNormalized = true;
+ if (referringType == null ||
+ (sourceIEnumerator.Flags & TypeFlags.VisibilityMask) == TypeFlags.Public && (targetIEnumerator.Flags & TypeFlags.VisibilityMask) == TypeFlags.Public){
+ adapter.Flags |= TypeFlags.Public;
+ module.Types.Add(adapter);
+ }else{
+ adapter.Flags |= TypeFlags.NestedPrivate;
+ referringType.Members.Add(adapter);
+ adapter.DeclaringType = referringType;
+ }
+ //Field to hold source enumerator
+ Field seField = new Field(adapter, null, FieldFlags.Private, StandardIds.Value, sourceIEnumerator, null);
+ members.Add(seField);
+
+ //Constructor
+ Parameter par = new Parameter(null, ParameterFlags.None, StandardIds.Value, sourceIEnumerator, null, null);
+ StatementList statements = new StatementList(3);
+ This ThisParameter = new This(adapter);
+ InstanceInitializer constr = CoreSystemTypes.Object.GetConstructor();
+ if (constr == null) { Debug.Fail(""); return null; }
+ MethodCall mcall = new MethodCall(new MemberBinding(ThisParameter, constr),
+ new ExpressionList(0), NodeType.Call, CoreSystemTypes.Void);
+ statements.Add(new ExpressionStatement(mcall));
+ statements.Add(new AssignmentStatement(new MemberBinding(ThisParameter, seField), par));
+ statements.Add(new Return());
+ InstanceInitializer acons = new InstanceInitializer(adapter, null, new ParameterList(par), new Block(statements));
+ acons.Flags |= MethodFlags.Public;
+ acons.ThisParameter = ThisParameter;
+ members.Add(acons);
+
+ //get_Current
+ statements = new StatementList(2);
+ ThisParameter = new This(adapter);
+ mcall = new MethodCall(new MemberBinding(new MemberBinding(ThisParameter, seField), sGetCurrent),
+ new ExpressionList(0), NodeType.Callvirt, sGetCurrent.ReturnType);
+ mcall.SourceContext = sctx;
+ statements.Add(new AssignmentStatement(loc, mcall));
+ statements.Add(new Return(curr));
+ Method getCurrent = new Method(adapter, null, StandardIds.getCurrent, null, tGetCurrent.ReturnType, new Block(statements));
+ getCurrent.Flags = MethodFlags.Public | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.HideBySig | MethodFlags.SpecialName;
+ getCurrent.CallingConvention = CallingConventionFlags.HasThis;
+ getCurrent.ThisParameter = ThisParameter;
+ members.Add(getCurrent);
+
+ //IEnumerator.GetCurrent
+ statements = new StatementList(1);
+ ThisParameter = new This(adapter);
+ MethodCall callGetCurrent = new MethodCall(new MemberBinding(ThisParameter, getCurrent), new ExpressionList(0), NodeType.Call, getCurrent.ReturnType);
+ if (getCurrent.ReturnType.IsValueType) {
+ MemberBinding etExpr = new MemberBinding(null, getCurrent.ReturnType);
+ statements.Add(new Return(new BinaryExpression(callGetCurrent, etExpr, NodeType.Box, CoreSystemTypes.Object)));
+ }else
+ statements.Add(new Return(callGetCurrent));
+ Method ieGetCurrent = new Method(adapter, null, StandardIds.IEnumeratorGetCurrent, null, CoreSystemTypes.Object, new Block(statements));
+ ieGetCurrent.ThisParameter = ThisParameter;
+ ieGetCurrent.ImplementedInterfaceMethods = new MethodList(SystemTypes.IEnumerator.GetMethod(StandardIds.getCurrent));
+ ieGetCurrent.CallingConvention = CallingConventionFlags.HasThis;
+ ieGetCurrent.Flags = MethodFlags.Private | MethodFlags.Virtual | MethodFlags.SpecialName;
+ members.Add(ieGetCurrent);
+
+ //IEnumerator.Reset
+ Method ieReset = SystemTypes.IEnumerator.GetMethod(StandardIds.Reset);
+ if (ieReset == null) { Debug.Fail(""); return null; }
+ statements = new StatementList(2);
+ ThisParameter = new This(adapter);
+ MethodCall callSourceReset = new MethodCall(new MemberBinding(ThisParameter, ieReset), new ExpressionList(0), NodeType.Callvirt, CoreSystemTypes.Object);
+ statements.Add(new ExpressionStatement(callSourceReset));
+ statements.Add(new Return());
+ Method reset = new Method(adapter, null, StandardIds.IEnumeratorReset, null, CoreSystemTypes.Void, new Block(statements));
+ reset.ThisParameter = ThisParameter;
+ reset.ImplementedInterfaceMethods = new MethodList(ieReset);
+ reset.CallingConvention = CallingConventionFlags.HasThis;
+ reset.Flags = MethodFlags.Private | MethodFlags.Virtual | MethodFlags.SpecialName;
+ members.Add(reset);
+
+ //MoveNext
+ if (sMoveNext == null) { Debug.Fail(""); return null; }
+ statements = new StatementList(1);
+ ThisParameter = new This(adapter);
+ mcall = new MethodCall(new MemberBinding(new MemberBinding(ThisParameter, seField), sMoveNext),
+ new ExpressionList(0), NodeType.Callvirt, CoreSystemTypes.Boolean);
+ statements.Add(new Return(mcall));
+ Method moveNext = new Method(adapter, null, StandardIds.MoveNext, null, CoreSystemTypes.Boolean, new Block(statements));
+ moveNext.Flags = MethodFlags.Public | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.HideBySig;
+ moveNext.CallingConvention = CallingConventionFlags.HasThis;
+ moveNext.ThisParameter = ThisParameter;
+ members.Add(moveNext);
+
+ //IDispose.Dispose
+ statements = new StatementList(1);
+ //TODO: call Dispose on source enumerator
+ statements.Add(new Return());
+ Method dispose = new Method(adapter, null, StandardIds.Dispose, null, CoreSystemTypes.Void, new Block(statements));
+ dispose.CallingConvention = CallingConventionFlags.HasThis;
+ dispose.Flags = MethodFlags.Public | MethodFlags.Virtual;
+ adapter.Members.Add(dispose);
+ return adapter;
+ }
+ }
+#endif
+#if FxCop
+ public class EventNode : Member{
+#else
+ public class Event : Member
+ {
+#endif
+ private EventFlags flags;
+ private Method handlerAdder;
+ private Method handlerCaller;
+ private MethodFlags handlerFlags;
+ private Method handlerRemover;
+ private TypeNode handlerType;
+ private MethodList otherMethods;
+#if !MinimalReader
+ public TypeNode HandlerTypeExpression;
+ /// <summary>The list of types (just one in C#) that contain abstract or virtual events that are explicity implemented or overridden by this event.</summary>
+ public TypeNodeList ImplementedTypes;
+ public TypeNodeList ImplementedTypeExpressions;
+ /// <summary>Provides a delegate instance that is added to the event upon initialization.</summary>
+ public Expression InitialHandler;
+ public Field BackingField;
+#endif
+#if FxCop
+ public EventNode()
+#else
+ public Event()
+#endif
+ : base(NodeType.Event)
+ {
+ }
+#if !MinimalReader
+ public Event(TypeNode declaringType, AttributeList attributes, EventFlags flags, Identifier name,
+ Method handlerAdder, Method handlerCaller, Method handlerRemover, TypeNode handlerType)
+ : base(declaringType, attributes, name, NodeType.Event)
+ {
+ this.Flags = flags;
+ this.HandlerAdder = handlerAdder;
+ this.HandlerCaller = handlerCaller;
+ this.HandlerRemover = handlerRemover;
+ this.HandlerType = handlerType;
+ }
+#endif
+ /// <summary>Bits characterizing this event.</summary>
+ public EventFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ /// <summary>The method to be called in order to add a handler to an event. Corresponds to the add clause of a C# event declaration.</summary>
+ public Method HandlerAdder
+ {
+ get { return this.handlerAdder; }
+ set { this.handlerAdder = value; }
+ }
+ /// <summary>The method that gets called to fire an event. There is no corresponding C# syntax.</summary>
+ public Method HandlerCaller
+ {
+ get { return this.handlerCaller; }
+ set { this.handlerCaller = value; }
+ }
+ public MethodFlags HandlerFlags
+ {
+ get { return this.handlerFlags; }
+ set { this.handlerFlags = value; }
+ }
+ /// <summary>The method to be called in order to remove a handler from an event. Corresponds to the remove clause of a C# event declaration.</summary>
+ public Method HandlerRemover
+ {
+ get { return this.handlerRemover; }
+ set { this.handlerRemover = value; }
+ }
+ /// <summary>The delegate type that a handler for this event must have. Corresponds to the type clause of C# event declaration.</summary>
+ public TypeNode HandlerType
+ {
+ get { return this.handlerType; }
+ set { this.handlerType = value; }
+ }
+ public MethodList OtherMethods
+ {
+ get { return this.otherMethods; }
+ set { this.otherMethods = value; }
+ }
+ protected string fullName;
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ string result = this.fullName;
+ if (result == null)
+ this.fullName = result = this.DeclaringType.FullName + "." + (this.Name == null ? "" : this.Name.ToString());
+ return result;
+ }
+ }
+#if !NoXml
+ protected override Identifier GetDocumentationId()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("E:");
+ if (this.DeclaringType == null) return Identifier.Empty;
+ this.DeclaringType.AppendDocumentIdMangledName(sb, null, null);
+ sb.Append(".");
+ if (this.Name == null) return Identifier.Empty;
+ sb.Append(this.Name.Name);
+ return Identifier.For(sb.ToString());
+ }
+#endif
+#if !NoReflection
+ public static Event GetEvent(System.Reflection.EventInfo eventInfo)
+ {
+ if (eventInfo == null) return null;
+ TypeNode tn = TypeNode.GetTypeNode(eventInfo.DeclaringType);
+ if (tn == null) return null;
+ return tn.GetEvent(Identifier.For(eventInfo.Name));
+ }
+ protected System.Reflection.EventInfo eventInfo;
+ public virtual System.Reflection.EventInfo GetEventInfo()
+ {
+ if (this.eventInfo == null)
+ {
+ TypeNode tn = this.DeclaringType;
+ if (tn == null) return null;
+ Type t = tn.GetRuntimeType();
+ if (t == null) return null;
+ System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
+ if (this.IsPublic) flags |= System.Reflection.BindingFlags.Public; else flags |= System.Reflection.BindingFlags.NonPublic;
+ if (this.IsStatic) flags |= System.Reflection.BindingFlags.Static; else flags |= System.Reflection.BindingFlags.Instance;
+ this.eventInfo = t.GetEvent(this.Name.ToString(), flags);
+ }
+ return this.eventInfo;
+ }
+#endif
+ /// <summary>
+ /// True if the methods constituting this event are abstract.
+ /// </summary>
+ public bool IsAbstract
+ {
+ get { return (this.HandlerFlags & MethodFlags.Abstract) != 0; }
+ }
+ public override bool IsAssembly
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Assembly; }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.CompilerControlled; }
+ }
+ public override bool IsFamily
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Family; }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.FamANDAssem; }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.FamORAssem; }
+ }
+ public bool IsFinal
+ {
+ get { return (this.HandlerFlags & MethodFlags.Final) != 0; }
+ }
+ public override bool IsPrivate
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Private; }
+ }
+ public override bool IsPublic
+ {
+ get { return (this.HandlerFlags & MethodFlags.MethodAccessMask) == MethodFlags.Public; }
+ }
+ public override bool IsSpecialName
+ {
+ get { return (this.Flags & EventFlags.SpecialName) != 0; }
+ }
+ public override bool IsStatic
+ {
+ get { return (this.HandlerFlags & MethodFlags.Static) != 0; }
+ }
+ /// <summary>
+ /// True if that the methods constituting this event are virtual.
+ /// </summary>
+ public bool IsVirtual
+ {
+ get { return (this.HandlerFlags & MethodFlags.Virtual) != 0; }
+ }
+ public override bool IsVisibleOutsideAssembly
+ {
+ get
+ {
+ return (this.HandlerAdder != null && this.HandlerAdder.IsVisibleOutsideAssembly) ||
+ (this.HandlerCaller != null && this.HandlerCaller.IsVisibleOutsideAssembly) ||
+ (this.HandlerRemover != null && this.HandlerRemover.IsVisibleOutsideAssembly);
+ }
+ }
+ public static readonly Event NotSpecified = new Event();
+ public override Member HiddenMember
+ {
+ get
+ {
+ return this.HiddenEvent;
+ }
+ set
+ {
+ this.HiddenEvent = (Event)value;
+ }
+ }
+ protected Property hiddenEvent;
+ public virtual Event HiddenEvent
+ {
+ get
+ {
+ if (this.hiddenMember == Event.NotSpecified) return null;
+ Event hiddenEvent = this.hiddenMember as Event;
+ if (hiddenEvent != null) return hiddenEvent;
+
+ Method hiddenAdder = this.HandlerAdder == null ? null : this.HandlerAdder.HiddenMethod;
+ Method hiddenCaller = this.HandlerCaller == null ? null : this.HandlerCaller.HiddenMethod;
+ Method hiddenRemover = this.HandlerRemover == null ? null : this.HandlerRemover.HiddenMethod;
+ Event hiddenAdderEvent = hiddenAdder == null ? null : hiddenAdder.DeclaringMember as Event;
+ Event hiddenCallerEvent = hiddenCaller == null ? null : hiddenCaller.DeclaringMember as Event;
+ Event hiddenRemoverEvent = hiddenRemover == null ? null : hiddenRemover.DeclaringMember as Event;
+
+ hiddenEvent = hiddenAdderEvent;
+ if (hiddenCallerEvent != null)
+ {
+ if (hiddenEvent == null ||
+ (hiddenCallerEvent.DeclaringType != null && hiddenCallerEvent.DeclaringType.IsDerivedFrom(hiddenEvent.DeclaringType)))
+ hiddenEvent = hiddenCallerEvent;
+ }
+ if (hiddenRemoverEvent != null)
+ {
+ if (hiddenEvent == null ||
+ (hiddenRemoverEvent.DeclaringType != null && hiddenRemoverEvent.DeclaringType.IsDerivedFrom(hiddenEvent.DeclaringType)))
+ hiddenEvent = hiddenRemoverEvent;
+ }
+ if (hiddenEvent == null)
+ {
+ this.hiddenMember = Event.NotSpecified;
+ return null;
+ }
+ this.hiddenMember = hiddenEvent;
+ return hiddenEvent;
+ }
+ set
+ {
+ this.hiddenMember = value;
+ }
+ }
+ public override Member OverriddenMember
+ {
+ get
+ {
+ return this.OverriddenEvent;
+ }
+ set
+ {
+ this.OverriddenEvent = (Event)value;
+ }
+ }
+ protected Property overriddenEvent;
+ public virtual Event OverriddenEvent
+ {
+ get
+ {
+ if (this.overriddenMember == Event.NotSpecified) return null;
+ Event overriddenEvent = this.overriddenMember as Event;
+ if (overriddenEvent != null) return overriddenEvent;
+
+ Method overriddenAdder = this.HandlerAdder == null ? null : this.HandlerAdder.OverriddenMethod;
+ Method overriddenCaller = this.HandlerCaller == null ? null : this.HandlerCaller.OverriddenMethod;
+ Method overriddenRemover = this.HandlerRemover == null ? null : this.HandlerRemover.OverriddenMethod;
+ Event overriddenAdderEvent = overriddenAdder == null ? null : overriddenAdder.DeclaringMember as Event;
+ Event overriddenCallerEvent = overriddenCaller == null ? null : overriddenCaller.DeclaringMember as Event;
+ Event overriddenRemoverEvent = overriddenRemover == null ? null : overriddenRemover.DeclaringMember as Event;
+
+ overriddenEvent = overriddenAdderEvent;
+ if (overriddenCallerEvent != null)
+ {
+ if (overriddenEvent == null ||
+ (overriddenCallerEvent.DeclaringType != null && overriddenCallerEvent.DeclaringType.IsDerivedFrom(overriddenEvent.DeclaringType)))
+ overriddenEvent = overriddenCallerEvent;
+ }
+ if (overriddenRemoverEvent != null)
+ {
+ if (overriddenEvent == null ||
+ (overriddenRemoverEvent.DeclaringType != null && overriddenRemoverEvent.DeclaringType.IsDerivedFrom(overriddenEvent.DeclaringType)))
+ overriddenEvent = overriddenRemoverEvent;
+ }
+ if (overriddenEvent == null)
+ {
+ this.overriddenMember = Event.NotSpecified;
+ return null;
+ }
+ this.overriddenMember = overriddenEvent;
+ return overriddenEvent;
+ }
+ set
+ {
+ this.overriddenMember = value;
+ }
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ base.GetName(options, name);
+ Method.AppendReturnType(options.ReturnType, this.HandlerType, name);
+ }
+#endif
+ }
+
+#if ExtendedRuntime
+ public abstract class MethodContractElement : Node{
+ protected MethodContractElement(NodeType nodeType)
+ : base(nodeType){
+ }
+ public bool Inherited;
+ }
+ public abstract class Requires : MethodContractElement {
+ public Expression Condition;
+ protected Requires()
+ : base(NodeType.Requires) {}
+ protected Requires(NodeType nodeType)
+ : base(nodeType){
+ }
+ protected Requires(NodeType nodeType, Expression expression)
+ : base(nodeType){
+ Condition = expression;
+ }
+ }
+ public class RequiresPlain : Requires {
+ public RequiresPlain()
+ : base(NodeType.RequiresPlain) {}
+ public RequiresPlain(Expression expression)
+ : base(NodeType.RequiresPlain, expression) {}
+ }
+ public class OldExpression : Expression {
+ public Expression expression;
+ public OldExpression()
+ : base(NodeType.OldExpression) {}
+ public OldExpression(Expression expression)
+ : base(NodeType.OldExpression) {this.expression = expression;}
+ }
+ public class RequiresOtherwise : Requires {
+ /// <summary>
+ /// The ThrowException can be a type reference (like "NullReferenceException")
+ /// or a value that would evaluate to something of an exception type.
+ /// (like new NullReferenceException("...") or C.f where the f is a static field
+ /// of class C whose type is an exception.
+ /// </summary>
+ public Expression ThrowException;
+ public RequiresOtherwise()
+ : base(NodeType.RequiresOtherwise) {}
+ public RequiresOtherwise(Expression cond, Expression exc)
+ : base(NodeType.RequiresOtherwise, cond){ ThrowException = exc; }
+ }
+
+ abstract public class Ensures : MethodContractElement {
+ public Expression PostCondition;
+ protected Ensures()
+ : base(NodeType.Ensures) {}
+ protected Ensures(NodeType nodeType)
+ : base(nodeType){
+ }
+ protected Ensures(NodeType nodeType, Expression expression)
+ : base(nodeType){
+ this.PostCondition = expression;
+ }
+ }
+ public class EnsuresNormal : Ensures{
+ public EnsuresNormal()
+ : base(NodeType.EnsuresNormal){
+ }
+ public EnsuresNormal(Expression expression)
+ : base(NodeType.EnsuresNormal, expression){
+ }
+ }
+ public class EnsuresExceptional : Ensures{
+ public TypeNode Type;
+ public TypeNode TypeExpression;
+ public Expression Variable;
+ public EnsuresExceptional()
+ : base(NodeType.EnsuresExceptional){
+ }
+ public EnsuresExceptional(Expression expression)
+ : base(NodeType.EnsuresExceptional, expression){
+ }
+ }
+
+ public class ContractDeserializerContainer{
+ public static IContractDeserializer ContractDeserializer;
+ }
+ public class MethodContract : Node{
+ public Method/*!*/ DeclaringMethod;
+ public Method/*!*/ OriginalDeclaringMethod;
+ protected internal RequiresList requires;
+ protected internal EnsuresList ensures;
+ protected internal ExpressionList modifies;
+ private static SourceContext SetContext(string/*!*/ filename, int startLine, int startCol, int endLine, int endCol, string/*!*/ sourceText) {
+ SourceContext context;
+ context.Document = new DocumentWithPrecomputedLineNumbers(filename, startLine, startCol, endLine, endCol);
+ context.StartPos = 0;
+ context.EndPos = sourceText.Length;
+ context.Document.Text = new DocumentText(sourceText);
+ context.Document.Text.Length = sourceText.Length;
+ return context;
+ }
+ public static SourceContext GetSourceContext(AttributeNode/*!*/ attr) {
+ string filename = "";
+ int startLine = 0;
+ int startCol = 0;
+ int endLine = 0;
+ int endCol = 0;
+ string sourceText = "";
+ if (attr.Expressions != null) {
+ for (int expIndex = 1, expLen = attr.Expressions.Count; expIndex < expLen; expIndex++) {
+ NamedArgument na = attr.Expressions[expIndex] as NamedArgument;
+ if (na == null || na.Name == null) continue;
+ Literal lit = na.Value as Literal;
+ if (lit == null) continue;
+ switch (na.Name.Name) {
+ case "Filename":
+ case "FileName":
+ filename = (string)lit.Value; break;
+ case "StartColumn": startCol = (int)lit.Value; break;
+ case "StartLine": startLine = (int)lit.Value; break;
+ case "EndColumn": endCol = (int)lit.Value; break;
+ case "EndLine": endLine = (int)lit.Value; break;
+ case "SourceText": sourceText = (string)lit.Value; break;
+ default: break;
+ }
+ }
+ }
+ SourceContext ctx = SetContext(filename, startLine, startCol, endLine, endCol,sourceText);
+ return ctx;
+ }
+ public RequiresList Requires{
+ get{
+ if (this.requires != null) return this.requires;
+ RequiresList rs = this.requires = new RequiresList();
+ if (this.DeclaringMethod != null){
+ if (this.Specializer != null && this.DeclaringMethod.Template != null) {
+ this.CopyFrom(this.DeclaringMethod.Template.Contract);
+ this.ensures = (EnsuresList)this.Specializer(this.DeclaringMethod, this.ensures);
+ return this.requires = (RequiresList)this.Specializer(this.DeclaringMethod, this.requires);
+ }
+ AttributeList attributes = this.DeclaringMethod.Attributes;
+ if (attributes == null || attributes.Count == 0) return rs;
+ IContractDeserializer ds = Cci.ContractDeserializerContainer.ContractDeserializer;
+ if (ds != null){
+ TypeNode t = this.DeclaringMethod.DeclaringType;
+ ds.CurrentAssembly = t == null ? null : t.DeclaringModule;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++){
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null){
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.RequiresAttribute) continue;
+ if (attr.Expressions == null || !(attr.Expressions.Count > 0)) continue;
+
+ Literal l = attr.Expressions[0] as Literal;
+ if (l == null) continue;
+ string s = (string) l.Value;
+ Expression e = null;
+ try {
+ e = ds.ParseContract(this,s,null);
+ } catch {
+ continue; //return this.requires = new RequiresList();
+ }
+ if (e != null){
+ RequiresPlain rp = new RequiresPlain(e);
+ SourceContext ctx = MethodContract.GetSourceContext(attr);
+ e.SourceContext = ctx;
+ rs.Add(rp);
+ }
+ }
+ }
+ ds.CurrentAssembly = null;
+ }
+ }
+ return this.requires;
+ }
+ set{
+ this.requires = value;
+ }
+ }
+ public EnsuresList Ensures{
+ get{
+ if (this.ensures != null) return this.ensures;
+ EnsuresList es = this.ensures = new EnsuresList();
+ if (this.DeclaringMethod != null){
+ if (this.Specializer != null && this.DeclaringMethod.Template != null) {
+ this.CopyFrom(this.DeclaringMethod.Contract);
+ this.requires = (RequiresList)this.Specializer(this.DeclaringMethod, this.requires);
+ return this.ensures = (EnsuresList)this.Specializer(this.DeclaringMethod, this.ensures);
+ }
+ AttributeList attributes = this.DeclaringMethod.Attributes;
+ if (attributes == null || attributes.Count == 0) return es;
+ IContractDeserializer ds = Cci.ContractDeserializerContainer.ContractDeserializer;
+ if (ds != null){
+ TypeNode t = this.DeclaringMethod.DeclaringType;
+ ds.CurrentAssembly = t == null ? null : t.DeclaringModule;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++){
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null){
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.EnsuresAttribute) continue;
+ if (attr.Expressions == null || !(attr.Expressions.Count > 0)) continue;
+ Literal l = attr.Expressions[0] as Literal;
+ if (l == null) continue;
+ string s = (string) l.Value;
+ Expression e = null;
+ try {
+ e = ds.ParseContract(this,s,null);
+ } catch {
+ continue; //return this.ensures = new EnsuresList();
+ }
+ EnsuresNormal ens = new EnsuresNormal(e);
+ SourceContext ctx = MethodContract.GetSourceContext(attr);
+ e.SourceContext = ctx;
+ es.Add(ens);
+ }
+ }
+ ds.CurrentAssembly = null;
+ }
+ }
+ return this.ensures;
+ }
+ set{
+ this.ensures = value;
+ }
+ }
+ public ExpressionList Modifies{
+ get{
+ if (this.modifies != null) return this.modifies;
+ ExpressionList ms = this.modifies = new ExpressionList();
+ if (this.DeclaringMethod != null){
+ AttributeList attributes = this.DeclaringMethod.Attributes;
+ if (attributes == null || attributes.Count == 0) return ms;
+ IContractDeserializer ds = Cci.ContractDeserializerContainer.ContractDeserializer;
+ if (ds != null){
+ TypeNode t = this.DeclaringMethod.DeclaringType;
+ ds.CurrentAssembly = t == null ? null : t.DeclaringModule;
+ for (int i = 0, n = attributes == null || attributes.Count == 0 ? 0 : attributes.Count; i < n; i++) {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null){
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.ModifiesAttribute) continue;
+ if (attr.Expressions == null || !(attr.Expressions.Count > 0)) continue;
+
+ Literal l = attr.Expressions[0] as Literal;
+ if (l == null) continue;
+ string s = (string) l.Value;
+ Expression e = ds.ParseContract(this,s,null);
+ if (e == null) continue;
+ SourceContext ctx = MethodContract.GetSourceContext(attr);
+ e.SourceContext = ctx;
+ ms.Add(e);
+ }
+ }
+ ds.CurrentAssembly = null;
+ }
+ }
+ return this.modifies;
+ }
+ set{
+ this.modifies = value;
+ }
+ }
+ public Local LocalForResult;
+ public delegate object ContractSpecializerDelegate(Method method, object part);
+ public ContractSpecializerDelegate Specializer;
+ public MethodContract(Method/*!*/ declaringMethod)
+ : base(NodeType.MethodContract) {
+ this.DeclaringMethod = this.OriginalDeclaringMethod = declaringMethod;
+ }
+
+
+ public void CopyFrom(MethodContract sourceContract) {
+ if ( sourceContract == null ) return;
+ this.OriginalDeclaringMethod = sourceContract.OriginalDeclaringMethod;
+
+ // Force deserialization (if necessary) to make sure sourceContract is fully populated
+ // This is needed for LocalForResult: it is populated in the sourceContract only if the
+ // postconditions have been deserialized.
+ int dummy = sourceContract.Requires.Count;
+ dummy = sourceContract.Ensures.Count + dummy;
+
+ TypeNode t = this.DeclaringMethod.DeclaringType;
+ Module m = t.DeclaringModule;
+ Duplicator dup = new Duplicator(m,t);
+ // Set up DuplicateFor table: all references to parameters from the source contract should be replaced
+ // with references to the equivalent parameter from the target contract.
+ // These references can be of type "Parameter" or "ParameterField".
+ // Also, the local that holds the "result" of the method should be likewise mapped.
+ // Also, the "this" parameter should be mapped.
+ Method sourceMethod = sourceContract.DeclaringMethod;
+ if (sourceMethod != null){
+ MethodScope sourceScope = sourceMethod.Scope;
+ Method targetMethod = this.DeclaringMethod;
+ if (targetMethod != null){
+ #region Map the self parameter
+ if (sourceMethod.ThisParameter != null && targetMethod.ThisParameter != null){
+ dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter;
+ }
+ #endregion
+ #region Map the method parameters
+ if (sourceMethod.Parameters != null && targetMethod.Parameters != null
+ && sourceMethod.Parameters.Count == targetMethod.Parameters.Count){
+ for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++){
+ dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i];
+ }
+ }
+ #endregion
+ #region Map the ParameterFields
+ MethodScope targetScope = targetMethod.Scope;
+ if (sourceScope != null && targetScope != null){
+ MemberList sourceScopeMembers = sourceScope.Members;
+ for (int i = 0, n = sourceScopeMembers != null ? sourceScopeMembers.Count : 0; i < n; i++){
+ ParameterField sourcePF = sourceScopeMembers[i] as ParameterField;
+ if (sourcePF == null) continue;
+ Parameter sourceP = sourcePF.Parameter;
+ if (sourceP == null){ Debug.Assert(false); continue; }
+ int index = sourceP.ParameterListIndex;
+ if (targetMethod.Parameters == null || targetMethod.Parameters.Count <= index || index < 0){
+ Debug.Assert(false); continue;
+ }
+ Parameter targetParameter = targetMethod.Parameters[index];
+ Field f = targetScope.GetField(targetParameter.Name);
+ if (f == null){ Debug.Assert(false); continue; }
+ ParameterField targetPF = f as ParameterField;
+ if (targetPF == null){ Debug.Assert(false); continue; }
+ dup.DuplicateFor[sourcePF.UniqueKey] = targetPF;
+ }
+ }
+ #endregion
+ }
+ }
+ if ( sourceContract.LocalForResult != null ) {
+ if (this.LocalForResult == null)
+ this.LocalForResult = sourceContract.LocalForResult;
+ dup.DuplicateFor[sourceContract.LocalForResult.UniqueKey] = this.LocalForResult;
+ }
+ MethodContract duplicatedMC = dup.VisitMethodContract(sourceContract);
+ if (duplicatedMC != null && duplicatedMC.Requires != null && duplicatedMC.Requires.Count > 0) {
+ RequiresList reqList = new RequiresList();
+ for (int i = 0, n = duplicatedMC.Requires.Count; i< n; i++){
+ Requires r = duplicatedMC.Requires[i];
+ if (r != null) r.Inherited = true;
+ reqList.Add(r);
+ }
+ foreach(Requires r in this.Requires) {
+ reqList.Add(r);
+ }
+ this.Requires = reqList;
+ }
+ if (duplicatedMC != null && duplicatedMC.Ensures != null && duplicatedMC.Ensures.Count > 0 ) {
+ // Copy only those "throws" ensures for which the target contract does not have
+ // an extension. The checking that is done before calling this method is assumed
+ // to have signalled an error if needed, so there is no checking done here.
+ // REVIEW: should this just be done during the checking and then don't copy any of
+ // the ensures in this method?
+ EnsuresList enList = new EnsuresList();
+ for(int i = 0, n = duplicatedMC.Ensures.Count; i < n; i++) {
+ Ensures e = duplicatedMC.Ensures[i];
+ e.Inherited = true;
+ EnsuresExceptional superThrows = e as EnsuresExceptional;
+ if (superThrows == null){
+ // normal ensures
+ enList.Add(e);
+ continue;
+ }
+ bool found = false;
+ for (int j = 0, subEnsuresLength = this.Ensures == null ? 0 : this.Ensures.Count; j < subEnsuresLength && !found; j++){
+ EnsuresExceptional subThrows = this.Ensures[j] as EnsuresExceptional;
+ if (subThrows == null || subThrows.Type == null) continue;
+ if (subThrows.Type.IsAssignableTo(superThrows.Type))
+ found = true;
+ }
+ if(!found)
+ enList.Add(e);
+ }
+ foreach(Ensures e in this.Ensures) {
+ enList.Add(e);
+ }
+ this.Ensures = enList;
+ }
+ if (duplicatedMC != null && duplicatedMC.Modifies != null && duplicatedMC.Modifies.Count > 0) {
+ ExpressionList modlist = this.Modifies = (this.Modifies == null ? new ExpressionList() : this.Modifies);
+ for (int i = 0, n = duplicatedMC.Modifies.Count; i < n; i++)
+ modlist.Add(duplicatedMC.Modifies[i]);
+ }
+ return;
+ }
+ }
+
+ public class Invariant : Method{
+ public Expression Condition;
+ public Invariant(TypeNode declaringType, AttributeList attributes, Identifier name){
+ this.NodeType = NodeType.Invariant;
+ this.attributes = attributes;
+ this.DeclaringType = declaringType;
+ this.Name = name;
+ // this is called from the parser, so we have to avoid triggering CoreSystemType initialization.
+ this.ReturnType = new TypeExpression(new Literal(TypeCode.Boolean), 0);
+ this.ReturnTypeExpression = new TypeExpression(new Literal(TypeCode.Boolean), 0);
+ }
+ }
+
+ public class ModelfieldContract : Node {
+ protected Field mf; //the modelfield this contract applies to (might be a temporary modelfield that stores unresolved override information)
+ protected Property ifaceMf; //the interface modelfield this contract applies to.
+ //invariant mf != null && ifaceMF == null || mf == null && ifaceMf != null;
+
+ public Expression Witness;
+ public ExpressionList/*!*/ SatisfiesList = new ExpressionList();
+
+ public TypeNode DeclaringType;
+
+ public Member/*!*/ Modelfield { get { return this.mf == null ? (Member)this.ifaceMf : (Member)this.mf; } }
+ public TypeNode/*!*/ ModelfieldType { get { return this.mf == null ? this.ifaceMf.Type : this.mf.Type; } }
+ private bool isOverride = false;
+ public bool IsOverride {
+ //slighty complicated to work both before and after serialization, and before and after update of modelfield reference if this contract is overriding a baseclass contract.
+ get {
+ if (this.isOverride == true) return true;
+ return !(this.Modelfield.DeclaringType == this.DeclaringType);
+ }
+ set {
+ //requires value == true; (setting to false has no real meaning or effect)
+ isOverride = value;
+ }
+ }
+
+ private bool isSealed = false; //set to true if modelfield itself is sealed (i.e., has the keyword).
+ public bool IsSealed {
+ get { if (this.isSealed) return true;
+ if (this.DeclaringType == null) return false; //defensive check
+ return this.DeclaringType.IsSealed;
+ }
+ set { //requires value == true and the modelfield(contract) itself is sealed</summary>
+ this.isSealed = value; }
+ }
+
+ /// <summary>
+ /// ensures that the result is a new modelfieldcontract with an empty set of satisfies clauses and a default witness.
+ /// ensures that the SourceContext of the result and the default witness are set to sctx.
+ /// requires all attributes to be non-null
+ /// </summary>
+ public ModelfieldContract(TypeNode declaringType, AttributeList attrs, TypeNode type, Identifier name, SourceContext sctx)
+ : base(NodeType.ModelfieldContract)
+ {
+ this.DeclaringType = declaringType;
+ this.SourceContext = sctx;
+ if (declaringType is Class) {
+ mf = new Field(declaringType, attrs, FieldFlags.Public, name, type, null); //note: if the modelfield has an override modifier, then mf is a placeholder. This will be signalled by a 'Private' flag.
+ mf.IsModelfield = true;
+ mf.SourceContext = this.SourceContext;
+ } else if (declaringType is Interface) {
+ //Treat as a property with a getter that will return a modelfield from an implementing class
+ #region create a default abstract getter method getM
+ Method getM = new Method(declaringType, new AttributeList(), new Identifier("get_" + name.Name), new ParameterList(), type, null);
+ getM.SourceContext = this.SourceContext;
+ getM.CallingConvention = CallingConventionFlags.HasThis; //needs to be changed when we want to allow static modelfields
+ declaringType.Members.Add(getM);
+ getM.Flags = MethodFlags.Public | MethodFlags.Abstract | MethodFlags.NewSlot | MethodFlags.Virtual | MethodFlags.SpecialName | MethodFlags.HideBySig;
+ #endregion
+ ifaceMf = new Property(declaringType, attrs, PropertyFlags.None, name, getM, null);
+ ifaceMf.IsModelfield = true;
+ ifaceMf.SourceContext = this.SourceContext;
+ getM.DeclaringMember = ifaceMf;
+ }
+ this.setWitnessToDefault();
+ }
+
+ /// <summary>
+ /// ensures result.HasDefaultWitness and result.Modelfield == modelfield
+ /// </summary>
+ public ModelfieldContract(TypeNode/* ! */ declaringType, Field/* ! */ modelfield)
+ : base(NodeType.ModelfieldContract) {
+ this.DeclaringType = declaringType;
+ this.SourceContext = modelfield.SourceContext;
+ this.mf = modelfield;
+ this.setWitnessToDefault();
+ if (modelfield.DeclaringType != declaringType)
+ this.IsOverride = true;
+ }
+
+ private void setWitnessToDefault() {
+ if (this.ModelfieldType.IsReferenceType)
+ this.Witness = new Literal(null, this.ModelfieldType, this.SourceContext); //this.HasDefaultWitness relies on this intialization of witness.sourcecontext.
+ else
+ this.Witness = new Literal(0, this.ModelfieldType, this.SourceContext); //this.HasDefaultWitness relies on this intialization of witness.sourcecontext.
+ }
+
+ /// <summary>
+ /// requires this.IsOverride == true;
+ /// requires that newMf is a member of a superclass of mfC.DeclaringType;
+ /// ensures this.Modelfield == newMf;
+ /// use this method to update the modelfield of an overriding modelfieldcontract to the modelfield that is overridden.
+ /// </summary>
+ /// <param name="newMf">The overridden modelfield that this modelfieldContract applies to</param>
+ public void UpdateModelfield(Field newMf) {
+ this.mf = newMf;
+ }
+
+ public bool HasDefaultWitness { get { return this.Witness.SourceContext.Equals(this.SourceContext); } }
+
+
+ private ModelfieldContract nearestOverriddenContract; //null when this not an overriding contract (or when getNearestContractContract has not yet been called)
+ /// <summary>
+ /// ensures: if this contract overrides a superclass contract, then result is the nearest overridden contract, else result == null.
+ /// </summary>
+ public ModelfieldContract NearestOverriddenContract {
+ get {
+ if (this.nearestOverriddenContract != null) return this.nearestOverriddenContract;
+
+ if (this.mf == null) return null; //interface modelfieldContracts can't override
+ if (!this.IsOverride) return null;
+ #region scan superclasses until nearest overriden contract is found, then return that contract.
+ for (Class currentClass = this.DeclaringType.BaseType as Class; currentClass != null; currentClass = currentClass.BaseClass) {
+ foreach (ModelfieldContract currentMfC in currentClass.Contract.ModelfieldContracts) {
+ if (currentMfC.Modelfield == this.mf) {
+ this.nearestOverriddenContract = currentMfC;
+ return this.nearestOverriddenContract;
+ }
+ }
+ }
+ Debug.Assert(false); //an overridden contract should have been found and returned.
+ return this.nearestOverriddenContract;
+ #endregion
+ }
+ }
+
+ }
+
+ public sealed class ModelfieldContractList {
+ private ModelfieldContract[]/*!*/ elements;
+ private int count = 0;
+ public ModelfieldContractList() {
+ this.elements = new ModelfieldContract[8];
+ //^ base();
+ }
+ public ModelfieldContractList(int n) {
+ this.elements = new ModelfieldContract[n];
+ //^ base();
+ }
+ public ModelfieldContractList(params ModelfieldContract[] elements) {
+ if (elements == null) elements = new ModelfieldContract[0];
+ this.elements = elements;
+ this.count = elements.Length;
+ //^ base();
+ }
+ public void Add(ModelfieldContract element) {
+ int n = this.elements.Length;
+ int i = this.count++;
+ if (i == n) {
+ int m = n * 2; if (m < 8) m = 8;
+ ModelfieldContract[] newElements = new ModelfieldContract[m];
+ for (int j = 0; j < n; j++) newElements[j] = elements[j];
+ this.elements = newElements;
+ }
+ this.elements[i] = element;
+ }
+ public ModelfieldContractList/*!*/ Clone() {
+ ModelfieldContract[] elements = this.elements;
+ int n = this.count;
+ ModelfieldContractList result = new ModelfieldContractList(n);
+ result.count = n;
+ ModelfieldContract[] newElements = result.elements;
+ for (int i = 0; i < n; i++)
+ newElements[i] = elements[i];
+ return result;
+ }
+ public int Count {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ [Obsolete("Use Count property instead.")]
+ public int Length {
+ get { return this.count; }
+ set { this.count = value; }
+ }
+ public ModelfieldContract this[int index] {
+ get {
+ return this.elements[index];
+ }
+ set {
+ this.elements[index] = value;
+ }
+ }
+ public Enumerator GetEnumerator() {
+ return new Enumerator(this);
+ }
+ public struct Enumerator {
+ private int index;
+ private readonly ModelfieldContractList/*!*/ list;
+ public Enumerator(ModelfieldContractList/*!*/ list) {
+ this.index = -1;
+ this.list = list;
+ }
+ public ModelfieldContract Current {
+ get {
+ return this.list[this.index];
+ }
+ }
+ public bool MoveNext() {
+ return ++this.index < this.list.count;
+ }
+ public void Reset() {
+ this.index = -1;
+ }
+ }
+ }
+
+ public class TypeContract : Node {
+ public TypeNode DeclaringType;
+ protected internal ModelfieldContractList modelfieldContracts;
+
+ /// <summary>
+ /// Deserializes attr.Expressions[i] as expression E.
+ /// requires attr.Expressions.Count > i;
+ /// requires this.DeclaringType != null;
+ /// </summary>
+ /// <returns>E if succesfull, null otherwise.</returns>
+ private Expression getIndexFromAttribute(AttributeNode attr, int i) {
+ IContractDeserializer ds = Cci.ContractDeserializerContainer.ContractDeserializer;
+ if (ds == null) return null;
+ ds.CurrentAssembly = this.DeclaringType.DeclaringModule;
+ Literal l = attr.Expressions[i] as Literal;
+ if (l == null) return null;
+ string s = (string)l.Value;
+ return ds.ParseContract(this, s, null);
+ }
+
+ /// <summary>
+ /// requires attr.Expressions.Count > 0
+ /// ensures if attr.Expressions[0] can be deserialized as modelfield F, then:
+ /// if F key in contractLookup, then returns matching value, else returns new ModelfieldContract mfC for F
+ /// else returns null
+ /// ensures if new mfC created, then (F, mfC) in contractLookup and mfC in this.ModelfieldContracts
+ /// </summary>
+ private ModelfieldContract getContractFor(AttributeNode attr, Dictionary<Field, ModelfieldContract> contractLookup) {
+ Expression mfBinding = this.getIndexFromAttribute(attr, 0);
+
+ //extract modelfield from mfBinding
+ if (!(mfBinding is MemberBinding)) return null;
+ Field modelfield = (mfBinding as MemberBinding).BoundMember as Field;
+ if (modelfield == null) return null;
+
+ //If this modelfield does not yet have a contract, then create one now and add <modelfield,mfC> to createdContracts
+ ModelfieldContract mfC = null;
+ if (!contractLookup.TryGetValue(modelfield, out mfC)) {
+ mfC = new ModelfieldContract(this.DeclaringType, modelfield);
+ this.modelfieldContracts.Add(mfC);
+ contractLookup.Add(modelfield, mfC);
+ }
+
+ return mfC;
+ }
+
+ public ModelfieldContractList/*!*/ ModelfieldContracts {
+ get {
+ if (this.modelfieldContracts == null) {
+ this.modelfieldContracts = new ModelfieldContractList();
+ #region deserialize the modelfieldcontracts if needed
+ Dictionary<Field,ModelfieldContract> createdContracts = new Dictionary<Field,ModelfieldContract>(); //key = modelfield memberbinding, value = contract for that modelfield (if one was created already)
+ if (this.DeclaringType != null) {
+ foreach (AttributeNode attr in this.DeclaringType.Attributes) {
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null || mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType == SystemTypes.ModelfieldContractAttribute) {
+ ModelfieldContract mfC = this.getContractFor(attr, createdContracts);
+ Expression witness = this.getIndexFromAttribute(attr, 1);
+ if (witness == null) continue;
+ witness.SourceContext = MethodContract.GetSourceContext(attr);
+ mfC.Witness = witness;
+ } else if (mb.BoundMember.DeclaringType == SystemTypes.SatisfiesAttribute) {
+ ModelfieldContract mfC = this.getContractFor(attr, createdContracts);
+ Expression satClause = this.getIndexFromAttribute(attr, 1);
+ if (satClause == null) continue;
+ satClause.SourceContext = MethodContract.GetSourceContext(attr);
+ mfC.SatisfiesList.Add(satClause);
+ }
+ }
+ }
+ #endregion
+ }
+ return this.modelfieldContracts;
+ }
+ set { this.modelfieldContracts = value; }
+ }
+
+ public InvariantList InheritedInvariants;
+ protected internal InvariantList invariants;
+ public InvariantList Invariants{
+ get{
+ if (this.invariants != null) return this.invariants;
+ InvariantList invs = this.invariants = new InvariantList();
+ if (this.DeclaringType != null){
+ AttributeList attributes = this.DeclaringType.Attributes;
+ IContractDeserializer ds = Cci.ContractDeserializerContainer.ContractDeserializer;
+ if (ds != null){
+ ds.CurrentAssembly = this.DeclaringType == null ? null : this.DeclaringType.DeclaringModule;
+ for (int i = 0, n = attributes == null || attributes.Count == 0 ? 0 : attributes.Count; i < n; i++){
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null){
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != SystemTypes.InvariantAttribute) continue;
+ if (attr.Expressions == null || !(attr.Expressions.Count > 0)) continue;
+
+ Literal l = attr.Expressions[0] as Literal;
+ if (l == null) continue;
+ string s = (string) l.Value;
+ Expression e = ds.ParseContract(this,s,null);
+ if (e != null){
+ Invariant inv = new Invariant(this.DeclaringType,null,Identifier.For("invariant"+i));
+ SourceContext ctx = MethodContract.GetSourceContext(attr);
+ inv.SourceContext = ctx;
+ inv.Condition = e;
+ invs.Add(inv);
+ }
+ }
+ }
+ // Make the type contract look as it does when the type is compiled from source
+ this.FramePropertyGetter = this.DeclaringType.GetMethod(Identifier.For("get_SpecSharp::FrameGuard"), null);
+ this.InitFrameSetsMethod = this.DeclaringType.GetMethod(Identifier.For("SpecSharp::InitGuardSets"), null);
+ this.InvariantMethod = this.DeclaringType.GetMethod(Identifier.For("SpecSharp::CheckInvariant"), CoreSystemTypes.Boolean);
+ this.FrameProperty = this.DeclaringType.GetProperty(Identifier.For("SpecSharp::FrameGuard"));
+ this.FrameField = this.DeclaringType.GetField(Identifier.For("SpecSharp::frameGuard"));
+ ds.CurrentAssembly = null;
+ }
+ }
+ return this.invariants;
+ }
+ set{
+ this.invariants = value;
+ }
+ }
+
+ // when non-null, points to the method added to the DeclaringType that will have the invariants in its body
+ // needed so when each invariant is visited, the proper environment can be set up for it.
+ // NB: Dont' visit it as part of StandardVisitor
+ public Field FrameField;
+ public Property FrameProperty;
+ public Method FramePropertyGetter;
+ public Method InitFrameSetsMethod;
+ public Method InvariantMethod;// when non-null, points to the method added to the DeclaringType that will have the invariants in its body
+ /// <summary>
+ /// Microsoft.Contracts.FrameGuardGetter implementation for this class.
+ /// </summary>
+ public Method GetFrameGuardMethod;
+ /// <summary>
+ /// When types get constructed via the Reader, we let the Invariants be initialized on demand.
+ /// When the parser creates a type, we want the type contract to contain the empty invariant list
+ /// so that it won't grovel through the attributes on first access to Invariants.
+ /// </summary>
+ /// <param name="containingType"></param>
+ public TypeContract(TypeNode containingType) : this(containingType, false)
+ {
+ }
+ public TypeContract(TypeNode containingType, bool initInvariantList)
+ : base(NodeType.TypeContract) {
+ this.DeclaringType = containingType;
+ if (initInvariantList) {
+ this.invariants = new InvariantList();
+ }
+ }
+ public int InvariantCount { get { return Invariants == null ? 0 : Invariants.Count; } }
+ public int ModelfieldContractCount { get { return ModelfieldContracts == null ? 0 : ModelfieldContracts.Count; } }
+ }
+ public interface IContractDeserializer{
+ // when text is a requires, ensures, or modifies
+ Expression ParseContract(MethodContract mc, string text, ErrorNodeList errors);
+ // when text is an assertion or an assume in code
+ Expression ParseContract(Method m, string text, ErrorNodeList errs);
+ // when text is an invariant
+ Expression ParseContract(TypeContract/*!*/ tc, string text, ErrorNodeList errs);
+ Module CurrentAssembly { get; set; }
+ ErrorNodeList ErrorList { get; set; }
+ }
+#endif
+
+ public class Method : Member
+ {
+#if ExtendedRuntime
+ public MethodContract Contract;
+#endif
+#if !MinimalReader
+ public TypeNodeList ImplementedTypes;
+ public TypeNodeList ImplementedTypeExpressions;
+ public bool HasCompilerGeneratedSignature = true;
+ public TypeNode ReturnTypeExpression;
+ /// <summary>Provides a way to retrieve the parameters and local variables defined in this method given their names.</summary>
+ public MethodScope Scope;
+ public bool HasOutOfBandContract = false;
+ protected TrivialHashtable/*!*/ Locals = new TrivialHashtable();
+#endif
+#if !FxCop
+ public LocalList LocalList;
+ protected SecurityAttributeList securityAttributes;
+ /// <summary>Contains declarative security information associated with the type.</summary>
+ public SecurityAttributeList SecurityAttributes
+ {
+ get
+ {
+ if (this.securityAttributes != null) return this.securityAttributes;
+ if (this.attributes == null)
+ {
+ AttributeList al = this.Attributes; //Getting the type attributes also gets the security attributes, in the case of a type that was read in by the Reader
+ if (al != null) al = null;
+ if (this.securityAttributes != null) return this.securityAttributes;
+ }
+ return this.securityAttributes = new SecurityAttributeList(0);
+ }
+ set
+ {
+ this.securityAttributes = value;
+ }
+ }
+#else
+ internal SecurityAttributeList securityAttributes;
+ public SecurityAttributeList SecurityAttributes{
+ get{return this.securityAttributes;}
+ internal set{this.securityAttributes = value;}
+ }
+ private LocalCollection locals;
+ public LocalCollection Locals{
+ get{
+ if (locals == null) this.Body = this.Body;
+ return this.locals;
+ }
+ internal set {
+ this.locals = value;
+ }
+ }
+ /// <summary>
+ /// Gets a value indicating whether the method is a property or event accessor.
+ /// </summary>
+ /// <value>
+ /// <see langword="true"/> if the <see cref="Method"/> is a property or event
+ /// accessor; otherwise, <see langword="false"/>.
+ /// </value>
+ /// <remarks>
+ /// <see cref="IsAccessor"/> returns <see langword="true"/> if
+ /// <see cref="DeclaringMember"/> is not <see langword="null"/>.
+ /// </remarks>
+ public bool IsAccessor{
+ get{return this.declaringMember != null;}
+ }
+ internal static bool EnforceMethodRepresentationCreationPolicy;
+ internal static int PopulatedBodiesCount;
+ internal static int PopulatedInstructionsCount;
+#endif
+ public delegate void MethodBodyProvider(Method/*!*/ method, object/*!*/ handle, bool asInstructionList);
+ public MethodBodyProvider ProvideBody;
+ public object ProviderHandle; //Opaque information to be used by the method body provider
+ public Method()
+ : base(NodeType.Method)
+ {
+#if ExtendedRuntime
+ this.Contract = new MethodContract(this);
+#endif
+ }
+ public Method(MethodBodyProvider provider, object handle)
+ : base(NodeType.Method)
+ {
+ this.ProvideBody = provider;
+ this.ProviderHandle = handle;
+#if ExtendedRuntime
+ this.Contract = new MethodContract(this);
+#endif
+ }
+ public Method(TypeNode declaringType, AttributeList attributes, Identifier name, ParameterList parameters, TypeNode returnType, Block body)
+ : base(declaringType, attributes, name, NodeType.Method)
+ {
+ this.body = body;
+ this.Parameters = parameters; // important to use setter here.
+ this.returnType = returnType;
+#if ExtendedRuntime
+ this.Contract = new MethodContract(this);
+#endif
+ }
+ private MethodFlags flags;
+ public MethodFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private MethodImplFlags implFlags;
+ public MethodImplFlags ImplFlags
+ {
+ get { return this.implFlags; }
+ set { this.implFlags = value; }
+ }
+ private MethodList implementedInterfaceMethods;
+ public MethodList ImplementedInterfaceMethods
+ {
+ get { return this.implementedInterfaceMethods; }
+ set { this.implementedInterfaceMethods = value; }
+ }
+#if !MinimalReader
+ private MethodList implicitlyImplementedInterfaceMethods;
+ /// <summary>
+ /// Computes the implicitly implemented methods for any method, not necessarily being compiled.
+ /// </summary>
+ public MethodList ImplicitlyImplementedInterfaceMethods
+ {
+ get
+ {
+ if (this.implicitlyImplementedInterfaceMethods == null)
+ {
+ this.implicitlyImplementedInterfaceMethods = new MethodList();
+ // There are several reasons that this method cannot implicitly implement any interface method.
+ if ((this.ImplementedInterfaceMethods == null || this.ImplementedInterfaceMethods.Count == 0) && this.IsPublic && !this.IsStatic)
+ {
+ // It can implicitly implement an interface method for those interfaces that
+ // the method's type explicitly declares it implements
+ if (this.DeclaringType != null && this.DeclaringType.Interfaces != null)
+ {
+ foreach (Interface i in this.DeclaringType.Interfaces)
+ {
+ if (i == null) continue;
+ Method match = i.GetMatchingMethod(this);
+ // But it cannot implicitly implement an interface method if there is
+ // an explicit implementation in the same type.
+ if (match != null && match.ReturnType == this.ReturnType && !this.DeclaringType.ImplementsExplicitly(match))
+ this.implicitlyImplementedInterfaceMethods.Add(match);
+ }
+ }
+ // It can implicitly implement an interface method if it overrides a base class
+ // method and *that* method implicitly implements the interface method.
+ // (Note: if this method's type does *not* explicitly declare that it implements
+ // the interface, then unless the method overrides a method that does, it is *not*
+ // used as an implicit implementation.)
+ if (this.OverriddenMethod != null)
+ {
+ foreach (Method method in this.OverriddenMethod.ImplicitlyImplementedInterfaceMethods)
+ // But it cannot implicitly implement an interface method if there is
+ // an explicit implementation in the same type.
+ if (!this.DeclaringType.ImplementsExplicitly(method))
+ this.implicitlyImplementedInterfaceMethods.Add(method);
+ }
+ }
+ }
+ return this.implicitlyImplementedInterfaceMethods;
+ }
+ set
+ {
+ this.implicitlyImplementedInterfaceMethods = value;
+ }
+ }
+#endif
+ private CallingConventionFlags callingConvention;
+ public CallingConventionFlags CallingConvention
+ {
+ get { return this.callingConvention; }
+ set { this.callingConvention = value; }
+ }
+ private bool initLocals = true;
+ /// <summary>True if all local variables are to be initialized to default values before executing the method body.</summary>
+ public bool InitLocals
+ {
+ get { return this.initLocals; }
+ set { this.initLocals = value; }
+ }
+ private bool isGeneric;
+ /// <summary>True if this method is a template that conforms to the rules for a CLR generic method.</summary>
+ public bool IsGeneric
+ {
+ get { return this.isGeneric; }
+ set { this.isGeneric = value; }
+ }
+ private ParameterList parameters;
+ /// <summary>The parameters this method has to be called with.</summary>
+ public ParameterList Parameters
+ {
+ get { return this.parameters; }
+ set
+ {
+ this.parameters = value;
+ if (value != null)
+ {
+ for (int i = 0, n = value.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null) continue;
+ par.DeclaringMethod = this;
+ }
+ }
+ }
+ }
+ private PInvokeFlags pInvokeFlags = PInvokeFlags.None;
+ public PInvokeFlags PInvokeFlags
+ {
+ get { return this.pInvokeFlags; }
+ set { this.pInvokeFlags = value; }
+ }
+ private Module pInvokeModule;
+ public Module PInvokeModule
+ {
+ get { return this.pInvokeModule; }
+ set { this.pInvokeModule = value; }
+ }
+ private string pInvokeImportName;
+ public string PInvokeImportName
+ {
+ get { return this.pInvokeImportName; }
+ set { this.pInvokeImportName = value; }
+ }
+ private AttributeList returnAttributes;
+ /// <summary>Attributes that apply to the return value of this method.</summary>
+ public AttributeList ReturnAttributes
+ {
+ get { return this.returnAttributes; }
+ set { this.returnAttributes = value; }
+ }
+ private MarshallingInformation returnTypeMarshallingInformation;
+ public MarshallingInformation ReturnTypeMarshallingInformation
+ {
+ get { return this.returnTypeMarshallingInformation; }
+ set { this.returnTypeMarshallingInformation = value; }
+ }
+ private TypeNode returnType;
+ /// <summary>The type of value that this method may return.</summary>
+ public TypeNode ReturnType
+ {
+ get { return this.returnType; }
+ set { this.returnType = value; }
+ }
+ private Member declaringMember;
+ /// <summary>Provides the declaring event or property of an accessor.</summary>
+ public Member DeclaringMember
+ {
+ get { return this.declaringMember; }
+ set { this.declaringMember = value; }
+ }
+ private This thisParameter;
+ public This ThisParameter
+ {
+ get
+ {
+ if (this.thisParameter == null && !this.IsStatic && this.DeclaringType != null)
+ {
+ if (this.DeclaringType.IsValueType)
+ this.ThisParameter = new This(this.DeclaringType.GetReferenceType());
+ else
+ this.ThisParameter = new This(this.DeclaringType);
+ }
+ return this.thisParameter;
+ }
+ set
+ {
+ if (value != null) value.DeclaringMethod = this;
+ this.thisParameter = value;
+ }
+ }
+ protected internal Block body;
+ /// <summary>The instructions constituting the body of this method, in the form of a tree.</summary>
+ public virtual Block Body
+ {
+ get
+ {
+ if (this.body != null) return this.body;
+ if (this.ProvideBody != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.body == null)
+ {
+ this.ProvideBody(this, this.ProviderHandle, false);
+#if FxCop
+ if (EnforceMethodRepresentationCreationPolicy && this.body.Statements.Count > 0)
+ System.Threading.Interlocked.Increment(ref Method.PopulatedBodiesCount);
+#endif
+ }
+ }
+ }
+ return this.body;
+ }
+ set
+ {
+#if FxCop
+ if (EnforceMethodRepresentationCreationPolicy && value == null && this.body != null && this.body.Statements.Count > 0)
+ System.Threading.Interlocked.Decrement(ref Method.PopulatedBodiesCount);
+#endif
+ this.body = value;
+ }
+ }
+ /// <summary>
+ /// A delegate that is called the first time Attributes is accessed, if non-null.
+ /// Provides for incremental construction of the type node.
+ /// Must not leave Attributes null.
+ /// </summary>
+ public MethodAttributeProvider ProvideMethodAttributes;
+ /// <summary>
+ /// The type of delegates that fill in the Attributes property of the given method.
+ /// </summary>
+ public delegate void MethodAttributeProvider(Method/*!*/ method, object/*!*/ handle);
+ public override AttributeList Attributes
+ {
+ get
+ {
+ if (this.attributes == null)
+ {
+ if (this.ProvideMethodAttributes != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.attributes == null)
+ this.ProvideMethodAttributes(this, this.ProviderHandle);
+ }
+ }
+ else
+ this.attributes = new AttributeList(0);
+ }
+ return this.attributes;
+ }
+ set
+ {
+ this.attributes = value;
+ }
+ }
+#if FxCop
+ internal void ClearBody(){
+#else
+ public void ClearBody()
+ {
+#endif
+ lock (Module.GlobalLock)
+ {
+ this.Body = null;
+ this.Instructions = null;
+#if !FxCop
+ this.LocalList = null;
+#else
+ this.Locals = null;
+#endif
+ }
+ }
+ protected string conditionalSymbol;
+ protected bool doesNotHaveAConditionalSymbol;
+ public string ConditionalSymbol
+ {
+ get
+ {
+ if (this.doesNotHaveAConditionalSymbol) return null;
+ if (this.conditionalSymbol == null)
+ {
+ lock (this)
+ {
+ if (this.conditionalSymbol != null) return this.conditionalSymbol;
+ AttributeNode condAttr = this.GetAttribute(SystemTypes.ConditionalAttribute);
+ if (condAttr != null && condAttr.Expressions != null && condAttr.Expressions.Count > 0)
+ {
+ Literal lit = condAttr.Expressions[0] as Literal;
+ if (lit != null)
+ {
+ this.conditionalSymbol = lit.Value as string;
+ if (this.conditionalSymbol != null) return this.conditionalSymbol;
+ }
+ }
+ this.doesNotHaveAConditionalSymbol = true;
+ }
+ }
+ return this.conditionalSymbol;
+ }
+ set
+ {
+ this.conditionalSymbol = value;
+ }
+ }
+ protected InstructionList instructions;
+ /// <summary>The instructions constituting the body of this method, in the form of a linear list of Instruction nodes.</summary>
+ public virtual InstructionList Instructions
+ {
+ get
+ {
+ if (this.instructions != null) return this.instructions;
+ if (this.ProvideBody != null && this.ProviderHandle != null)
+ {
+ lock (Module.GlobalLock)
+ {
+ if (this.instructions == null)
+ {
+ this.ProvideBody(this, this.ProviderHandle, true);
+#if FxCop
+ if (EnforceMethodRepresentationCreationPolicy)
+ System.Threading.Interlocked.Increment(ref Method.PopulatedInstructionsCount);
+#endif
+ }
+ }
+ }
+ return this.instructions;
+ }
+ set
+ {
+#if FxCop
+ if (EnforceMethodRepresentationCreationPolicy && this.instructions != null && value == null)
+ System.Threading.Interlocked.Decrement(ref Method.PopulatedInstructionsCount);
+#endif
+ this.instructions = value;
+ }
+ }
+#if !FxCop
+ protected ExceptionHandlerList exceptionHandlers;
+ public virtual ExceptionHandlerList ExceptionHandlers
+ {
+ get
+ {
+ if (this.exceptionHandlers != null) return this.exceptionHandlers;
+ Block dummy = this.Body;
+ if (this.exceptionHandlers == null) this.exceptionHandlers = new ExceptionHandlerList(0);
+ return this.exceptionHandlers;
+ }
+ set
+ {
+ this.exceptionHandlers = value;
+ }
+ }
+#endif
+#if !NoXml
+ protected override Identifier GetDocumentationId()
+ {
+ if (this.Template != null) return this.Template.GetDocumentationId();
+ StringBuilder sb = new StringBuilder(this.DeclaringType.DocumentationId.ToString());
+ sb[0] = 'M';
+ sb.Append('.');
+ if (this.NodeType == NodeType.InstanceInitializer)
+ sb.Append("#ctor");
+ else if (this.Name != null)
+ {
+ sb.Append(this.Name.ToString());
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0 && this.TemplateParameters != null && this.TemplateParameters.Count > 0)
+ {
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(TargetPlatform.GenericTypeNamesMangleChar);
+ sb.Append(this.TemplateParameters.Count);
+ }
+ }
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ par.Type.AppendDocumentIdMangledName(sb, this.TemplateParameters, this.DeclaringType.TemplateParameters);
+ if (i == n - 1)
+ sb.Append(')');
+ }
+ if (this.IsSpecialName && this.ReturnType != null && this.Name != null &&
+ (this.Name.UniqueIdKey == StandardIds.opExplicit.UniqueIdKey || this.Name.UniqueIdKey == StandardIds.opImplicit.UniqueIdKey))
+ {
+ sb.Append('~');
+ this.ReturnType.AppendDocumentIdMangledName(sb, this.TemplateParameters, this.DeclaringType.TemplateParameters);
+ }
+ return Identifier.For(sb.ToString());
+ }
+#endif
+ protected internal string fullName;
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.fullName != null) return this.fullName;
+ StringBuilder sb = new StringBuilder();
+ if (this.DeclaringType != null)
+ {
+ sb.Append(this.DeclaringType.FullName);
+ sb.Append('.');
+ if (this.NodeType == NodeType.InstanceInitializer)
+ sb.Append("#ctor");
+ else if (this.Name != null)
+ sb.Append(this.Name.ToString());
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ sb.Append(par.Type.FullName);
+ if (i == n - 1)
+ sb.Append(')');
+ }
+ }
+ return this.fullName = sb.ToString();
+ }
+ }
+#if ExtendedRuntime
+ public override string HelpText {
+ get {
+ if (this.helpText != null)
+ return this.helpText;
+ StringBuilder sb = new StringBuilder(base.HelpText);
+ // if there is already some help text, start the contract on a new line
+ bool startWithNewLine = (sb.Length != 0);
+ if (this.Contract != null){
+ MethodContract mc = this.Contract;
+ RequiresList rs = mc.Requires;
+ if (rs != null && rs.Count == 0) { mc.Requires = null; rs = mc.Requires; }
+ for (int i = 0, n = rs == null ? 0 : rs.Count; i < n; i++){
+ Requires r = rs[i];
+ Expression e = r.Condition;
+ if (e.SourceContext.StartPos < e.SourceContext.EndPos && e.SourceContext.SourceText != ""){
+ if (startWithNewLine) sb.Append('\n');
+ sb.Append("requires ");
+ sb.Append(e.SourceContext.SourceText);
+ sb.Append(";");
+ startWithNewLine = true;
+ }
+ }
+ EnsuresList es = mc.Ensures;
+ if (es != null && es.Count == 0) { mc.Ensures = null; es = mc.Ensures; }
+ if (es != null)
+ for (int i = 0, n = es.Count; i < n; i++){
+ Ensures e = es[i];
+ Expression cond = e.PostCondition;
+ if (e != null && e.SourceContext.StartPos < e.SourceContext.EndPos && e.SourceContext.SourceText != "") {
+ if (startWithNewLine) sb.Append('\n');
+ sb.Append("ensures ");
+ sb.Append(cond.SourceContext.SourceText);
+ sb.Append(";");
+ startWithNewLine = true;
+ }
+ }
+ ExpressionList exps = mc.Modifies;
+ // Force deserialization in case that is needed
+ if (exps != null && exps.Count == 0) { mc.Modifies = null; exps = mc.Modifies; }
+ if (exps != null) {
+ for (int i = 0, n = exps.Count; i < n; i++) {
+ Expression mod = exps[i];
+ if (mod != null && mod.SourceContext.StartPos < mod.SourceContext.EndPos && mod.SourceContext.SourceText != "") {
+ if (startWithNewLine) sb.Append('\n');
+ sb.Append("modifies ");
+ sb.Append(mod.SourceContext.SourceText);
+ sb.Append(";");
+ startWithNewLine = true;
+ }
+ }
+ }
+ }
+ return this.helpText = sb.ToString();
+ }
+ set {
+ base.HelpText = value;
+ }
+ }
+#endif
+ public virtual string GetUnmangledNameWithoutTypeParameters()
+ {
+ return this.GetUnmangledNameWithoutTypeParameters(false);
+ }
+ public virtual string GetUnmangledNameWithoutTypeParameters(bool omitParameterTypes)
+ {
+ StringBuilder sb = new StringBuilder();
+ if (this.NodeType == NodeType.InstanceInitializer)
+ sb.Append("#ctor");
+ else if (this.Name != null)
+ {
+ string name = this.Name.ToString();
+ int lastDot = name.LastIndexOf('.');
+ int lastMangle = name.LastIndexOf('>');
+ // explicit interface method overrides will have typenames in
+ // their method name, which may also contain type parameters
+ if (lastMangle < lastDot)
+ lastMangle = -1;
+ if (lastMangle > 0)
+ sb.Append(name.Substring(0, lastMangle + 1));
+ else
+ sb.Append(name);
+ }
+ if (omitParameterTypes) return sb.ToString();
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ sb.Append(par.Type.GetFullUnmangledNameWithTypeParameters());
+ if (i == n - 1)
+ {
+#if !MinimalReader
+ if (this.IsVarArg)
+ {
+ sb.Append(", __arglist");
+ }
+#endif
+ sb.Append(')');
+ }
+ }
+ return sb.ToString();
+ }
+ public virtual string GetUnmangledNameWithTypeParameters()
+ {
+ return this.GetUnmangledNameWithTypeParameters(false);
+ }
+ public virtual string GetUnmangledNameWithTypeParameters(bool omitParameterTypes)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(this.GetUnmangledNameWithoutTypeParameters(true));
+ TypeNodeList templateParameters = this.TemplateParameters;
+ for (int i = 0, n = templateParameters == null ? 0 : templateParameters.Count; i < n; i++)
+ {
+ TypeNode tpar = templateParameters[i];
+ if (tpar == null) continue;
+ if (i == 0)
+ sb.Append('<');
+ else
+ sb.Append(',');
+ sb.Append(tpar.Name.ToString());
+ if (i == n - 1)
+ sb.Append('>');
+ }
+ if (omitParameterTypes) return sb.ToString();
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ sb.Append(par.Type.GetFullUnmangledNameWithTypeParameters());
+ if (i == n - 1)
+ sb.Append(')');
+ }
+ return sb.ToString();
+ }
+ public virtual string GetFullUnmangledNameWithTypeParameters()
+ {
+ return this.GetFullUnmangledNameWithTypeParameters(false);
+ }
+ public virtual string GetFullUnmangledNameWithTypeParameters(bool omitParameterTypes)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(this.DeclaringType.GetFullUnmangledNameWithTypeParameters());
+ sb.Append('.');
+ sb.Append(this.GetUnmangledNameWithTypeParameters());
+ return sb.ToString();
+ }
+ public static MethodFlags GetVisibilityUnion(Method m1, Method m2)
+ {
+ if (m1 == null && m2 != null) return m2.Flags & MethodFlags.MethodAccessMask;
+ if (m2 == null && m1 != null) return m1.Flags & MethodFlags.MethodAccessMask;
+ if (m1 == null || m2 == null) return MethodFlags.CompilerControlled;
+ return Method.GetVisibilityUnion(m1.Flags, m2.Flags);
+ }
+ public static MethodFlags GetVisibilityUnion(MethodFlags vis1, MethodFlags vis2)
+ {
+ vis1 &= MethodFlags.MethodAccessMask;
+ vis2 &= MethodFlags.MethodAccessMask;
+ switch (vis1)
+ {
+ case MethodFlags.Public:
+ return MethodFlags.Public;
+ case MethodFlags.Assembly:
+ switch (vis2)
+ {
+ case MethodFlags.Public:
+ return MethodFlags.Public;
+ case MethodFlags.FamORAssem:
+ case MethodFlags.Family:
+ return MethodFlags.FamORAssem;
+ default:
+ return vis1;
+ }
+ case MethodFlags.FamANDAssem:
+ switch (vis2)
+ {
+ case MethodFlags.Public:
+ return MethodFlags.Public;
+ case MethodFlags.Assembly:
+ return MethodFlags.Assembly;
+ case MethodFlags.FamORAssem:
+ return MethodFlags.FamORAssem;
+ case MethodFlags.Family:
+ return MethodFlags.Family;
+ default:
+ return vis1;
+ }
+ case MethodFlags.FamORAssem:
+ switch (vis2)
+ {
+ case MethodFlags.Public:
+ return MethodFlags.Public;
+ default:
+ return vis1;
+ }
+ case MethodFlags.Family:
+ switch (vis2)
+ {
+ case MethodFlags.Public:
+ return MethodFlags.Public;
+ case MethodFlags.FamORAssem:
+ case MethodFlags.Assembly:
+ return MethodFlags.FamORAssem;
+ default:
+ return vis1;
+ }
+ default:
+ return vis2;
+ }
+ }
+#if !NoReflection
+ public virtual object Invoke(object targetObject, params object[] arguments)
+ {
+ System.Reflection.MethodInfo methInfo = this.GetMethodInfo();
+ if (methInfo == null) return null;
+ return methInfo.Invoke(targetObject, arguments);
+ }
+ public virtual Literal Invoke(Literal/*!*/ targetObject, params Literal[] arguments)
+ {
+ int n = arguments == null ? 0 : arguments.Length;
+ object[] args = n == 0 ? null : new object[n];
+ if (args != null && arguments != null)
+ for (int i = 0; i < n; i++)
+ {
+ Literal lit = arguments[i];
+ args[i] = lit == null ? null : lit.Value;
+ }
+ return new Literal(this.Invoke(targetObject.Value, args));
+ }
+#endif
+#if !MinimalReader
+ protected bool isNormalized;
+ public virtual bool IsNormalized
+ {
+ get
+ {
+ if (this.isNormalized) return true;
+ if (this.DeclaringType == null || this.SourceContext.Document != null) return false;
+ return this.isNormalized = this.DeclaringType.IsNormalized;
+ }
+ set
+ {
+ this.isNormalized = value;
+ }
+ }
+#endif
+ public virtual bool IsAbstract
+ {
+ get { return (this.Flags & MethodFlags.Abstract) != 0; }
+ }
+ public override bool IsAssembly
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Assembly; }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.CompilerControlled; }
+ }
+ public virtual bool IsExtern
+ {
+ get { return (this.Flags & MethodFlags.PInvokeImpl) != 0 || (this.ImplFlags & (MethodImplFlags.Runtime | MethodImplFlags.InternalCall)) != 0; }
+ }
+ public override bool IsFamily
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Family; }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.FamANDAssem; }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.FamORAssem; }
+ }
+ public virtual bool IsFinal
+ {
+ get { return (this.Flags & MethodFlags.Final) != 0; }
+ }
+#if !MinimalReader
+ public virtual bool IsInternalCall
+ {
+ get { return (this.ImplFlags & MethodImplFlags.InternalCall) != 0; }
+ }
+#endif
+ public override bool IsPrivate
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Private; }
+ }
+ public override bool IsPublic
+ {
+ get { return (this.Flags & MethodFlags.MethodAccessMask) == MethodFlags.Public; }
+ }
+ public override bool IsSpecialName
+ {
+ get { return (this.Flags & MethodFlags.SpecialName) != 0; }
+ }
+ public override bool IsStatic
+ {
+ get { return (this.Flags & MethodFlags.Static) != 0; }
+ }
+ /// <summary>
+ /// True if this method can in principle be overridden by a method in a derived class.
+ /// </summary>
+ public virtual bool IsVirtual
+ {
+ get { return (this.Flags & MethodFlags.Virtual) != 0; }
+ }
+#if !MinimalReader
+ public virtual bool IsNonSealedVirtual
+ {
+ get
+ {
+ return (this.Flags & MethodFlags.Virtual) != 0 && (this.Flags & MethodFlags.Final) == 0 &&
+ (this.DeclaringType == null || (this.DeclaringType.Flags & TypeFlags.Sealed) == 0);
+ }
+ }
+ public virtual bool IsVirtualAndNotDeclaredInStruct
+ {
+ get
+ {
+ return (this.Flags & MethodFlags.Virtual) != 0 && (this.DeclaringType == null || !(this.DeclaringType is Struct));
+ }
+ }
+#endif
+ public override bool IsVisibleOutsideAssembly
+ {
+ get
+ {
+ if (this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly) return false;
+ switch (this.Flags & MethodFlags.MethodAccessMask)
+ {
+ case MethodFlags.Public:
+ return true;
+ case MethodFlags.Family:
+ case MethodFlags.FamORAssem:
+ if (this.DeclaringType != null && !this.DeclaringType.IsSealed) return true;
+ goto default;
+ default:
+ for (int i = 0, n = this.ImplementedInterfaceMethods == null ? 0 : this.ImplementedInterfaceMethods.Count; i < n; i++)
+ {
+ Method m = this.ImplementedInterfaceMethods[i];
+ if (m == null) continue;
+ if (m.DeclaringType != null && !m.DeclaringType.IsVisibleOutsideAssembly) continue;
+ if (m.IsVisibleOutsideAssembly) return true;
+ }
+ return false;
+ }
+ }
+ }
+#if ExtendedRuntime
+ public bool IsPure{
+ get{
+ return this.GetAttribute(SystemTypes.PureAttribute) != null;
+ }
+ }
+ public bool ApplyDefaultActivity {
+ get {
+ return this.GetAttribute(SystemTypes.NoDefaultActivityAttribute) == null;
+ }
+ }
+ public bool ApplyDefaultContract {
+ get{
+ return this.GetAttribute(SystemTypes.NoDefaultContractAttribute) == null;
+ }
+ }
+ public bool IsPropertyGetter{
+ get{
+ if (this.DeclaringMember == null) return false;
+ Property p = this.DeclaringMember as Property;
+ if (p == null) return false;
+ if (p.Getter == this) return true;
+ if (this.Template != null) {
+ p = this.Template.DeclaringMember as Property;
+ if (p != null) return p.Getter == this.Template;
+ }
+ return false;
+ }
+ }
+ public bool IsPropertySetter {
+ get {
+ if (this.DeclaringMember == null) return false;
+ Property p = this.DeclaringMember as Property;
+ if (p == null) return false;
+ if (p.Setter == this) return true;
+ if (this.Template != null) {
+ p = this.Template.DeclaringMember as Property;
+ if (p != null) return p.Setter == this.Template;
+ }
+ return false;
+ }
+ }
+ public bool IsConfined {
+ get{
+ return this.ApplyDefaultContract && this.IsPropertyGetter && !(this.DeclaringType is Struct) || this.GetAttribute(SystemTypes.ConfinedAttribute) != null;
+ }
+ }
+ public bool IsWriteConfined {
+ get {
+ return this.GetAttribute(SystemTypes.WriteConfinedAttribute) != null
+ || IsConfined || IsStateIndependent;
+ }
+ }
+ public bool IsStateIndependent{
+ get{
+ return this.ApplyDefaultContract && this.IsPropertyGetter && this.DeclaringType is Struct || this.GetAttribute(SystemTypes.StateIndependentAttribute) != null;
+ }
+ }
+#endif
+#if !MinimalReader
+ public bool IsVarArg
+ {
+ get { return (this.CallingConvention & CallingConventionFlags.VarArg) != 0; }
+ }
+ // whether this is a FieldInitializerMethod (declared in Sing#)
+ public virtual bool IsFieldInitializerMethod
+ {
+ get
+ {
+ return false;
+ }
+ }
+#endif
+ public override Member HiddenMember
+ {
+ get
+ {
+ return this.HiddenMethod;
+ }
+ set
+ {
+ this.HiddenMethod = (Method)value;
+ }
+ }
+ public virtual Method HiddenMethod
+ {
+ get
+ {
+ if (this.hiddenMember == Method.NotSpecified) return null;
+ Method hiddenMethod = this.hiddenMember as Method;
+ if (hiddenMethod != null) return hiddenMethod;
+ if (this.ProvideBody == null) return null;
+ if (this.IsVirtual && (this.Flags & MethodFlags.VtableLayoutMask) != MethodFlags.NewSlot) return null;
+ TypeNode baseType = this.DeclaringType.BaseType;
+ while (baseType != null)
+ {
+ MemberList baseMembers = baseType.GetMembersNamed(this.Name);
+ if (baseMembers != null)
+ for (int i = 0, n = baseMembers.Count; i < n; i++)
+ {
+ Method bmeth = baseMembers[i] as Method;
+ if (bmeth == null) continue;
+ if (!bmeth.ParametersMatch(this.Parameters))
+ {
+ if (this.TemplateParameters != null && this.TemplateParametersMatch(bmeth.TemplateParameters))
+ {
+ if (!bmeth.ParametersMatchStructurally(this.Parameters)) continue;
+ }
+ else
+ continue;
+ }
+ hiddenMethod = bmeth;
+ goto done;
+ }
+ baseType = baseType.BaseType;
+ }
+ done:
+ if (hiddenMethod == null)
+ {
+ this.hiddenMember = Method.NotSpecified;
+ return null;
+ }
+ this.hiddenMember = hiddenMethod;
+ return hiddenMethod;
+ }
+ set
+ {
+ this.hiddenMember = value;
+ }
+ }
+ public override Member OverriddenMember
+ {
+ get
+ {
+ return this.OverriddenMethod;
+ }
+ set
+ {
+ this.OverriddenMethod = (Method)value;
+ }
+ }
+ public virtual Method OverriddenMethod
+ {
+ get
+ {
+ if ((this.Flags & MethodFlags.VtableLayoutMask) == MethodFlags.NewSlot) return null;
+ if (this.overriddenMember == Method.NotSpecified) return null;
+ Method overriddenMethod = this.overriddenMember as Method;
+ if (overriddenMethod != null) return overriddenMethod;
+ if (this.ProvideBody == null) return null;
+ if (!this.IsVirtual) return null;
+ TypeNode baseType = this.DeclaringType.BaseType;
+ while (baseType != null)
+ {
+ MemberList baseMembers = baseType.GetMembersNamed(this.Name);
+ if (baseMembers != null)
+ for (int i = 0, n = baseMembers.Count; i < n; i++)
+ {
+ Method bmeth = baseMembers[i] as Method;
+ if (bmeth == null) continue;
+ if (!bmeth.ParametersMatch(this.Parameters))
+ {
+ if (this.TemplateParameters != null && this.TemplateParametersMatch(bmeth.TemplateParameters))
+ {
+ if (!bmeth.ParametersMatchStructurally(this.Parameters)) continue;
+ }
+ else
+ continue;
+ }
+ overriddenMethod = bmeth;
+ goto done;
+ }
+ baseType = baseType.BaseType;
+ }
+ done:
+ if (overriddenMethod == null)
+ {
+ this.overriddenMember = Method.NotSpecified;
+ return null;
+ }
+ this.overriddenMember = overriddenMethod;
+ return overriddenMethod;
+ }
+ set
+ {
+ this.overriddenMember = value;
+ }
+ }
+#if !NoReflection
+ public static Method GetMethod(System.Reflection.MethodInfo methodInfo)
+ {
+ if (methodInfo == null) return null;
+#if WHIDBEY
+ if (methodInfo.IsGenericMethod && !methodInfo.IsGenericMethodDefinition)
+ {
+ try
+ {
+ Method template = Method.GetMethod(methodInfo.GetGenericMethodDefinition());
+ if (template == null) return null;
+ TypeNodeList templateArguments = new TypeNodeList();
+ foreach (Type arg in methodInfo.GetGenericArguments())
+ templateArguments.Add(TypeNode.GetTypeNode(arg));
+ return template.GetTemplateInstance(template.DeclaringType, templateArguments);
+ }
+ catch
+ {
+ //TODO: log error
+ return null;
+ }
+ }
+#endif
+ TypeNode tn = TypeNode.GetTypeNode(methodInfo.DeclaringType);
+ if (tn == null) return null;
+ System.Reflection.ParameterInfo[] paramInfos = methodInfo.GetParameters();
+ int n = paramInfos == null ? 0 : paramInfos.Length;
+ TypeNode[] parameterTypes = new TypeNode[n];
+ for (int i = 0; i < n; i++)
+ {
+ System.Reflection.ParameterInfo param = paramInfos[i];
+ if (param == null) return null;
+ parameterTypes[i] = TypeNode.GetTypeNode(param.ParameterType);
+ }
+ TypeNodeList paramTypes = new TypeNodeList(parameterTypes);
+ TypeNode returnType = TypeNode.GetTypeNode(methodInfo.ReturnType);
+ MemberList members = tn.GetMembersNamed(Identifier.For(methodInfo.Name));
+ for (int i = 0, m = members == null ? 0 : members.Count; i < m; i++)
+ {
+ Method meth = members[i] as Method;
+ if (meth == null) continue;
+ if (!meth.ParameterTypesMatch(paramTypes)) continue;
+ if (meth.ReturnType != returnType) continue;
+ return meth;
+ }
+ return null;
+ }
+#endif
+#if !NoReflection && !MinimalReader && WHIDBEY
+ protected System.Reflection.Emit.DynamicMethod dynamicMethod;
+ public virtual System.Reflection.Emit.DynamicMethod GetDynamicMethod()
+ {
+ return this.GetDynamicMethod(false);
+ }
+ public virtual System.Reflection.Emit.DynamicMethod GetDynamicMethod(bool skipVisibility)
+ //^ requires this.DeclaringType != null && this.DeclaringType.DeclaringModule != null && this.IsNormalized && this.Name != null && this.ReturnType != null;
+ //^ requires (this.CallingConvention & CallingConventionFlags.ArgumentConvention) == CallingConventionFlags.StandardCall;
+ //^ requires !this.IsGeneric;
+ {
+ if (this.dynamicMethod == null)
+ {
+ if (this.DeclaringType == null || this.DeclaringType.DeclaringModule == null || !this.IsNormalized || this.Name == null || this.ReturnType == null)
+ {
+ Debug.Assert(false); return null;
+ }
+ if ((this.CallingConvention & CallingConventionFlags.ArgumentConvention) != CallingConventionFlags.StandardCall || this.IsGeneric)
+ {
+ Debug.Assert(false); return null;
+ }
+ string name = this.Name.Name;
+ System.Reflection.MethodAttributes attrs = (System.Reflection.MethodAttributes)this.Flags;
+ System.Reflection.CallingConventions callConv = System.Reflection.CallingConventions.Standard;
+ callConv |= (System.Reflection.CallingConventions)(this.CallingConvention & ~CallingConventionFlags.ArgumentConvention);
+ System.Type rtype = this.ReturnType.GetRuntimeType();
+ System.Type owner = this.DeclaringType.GetRuntimeType();
+ if (owner == null) { Debug.Fail(""); return null; }
+ System.Reflection.Module module = owner.Module;
+ System.Reflection.Emit.DynamicMethod dmeth;
+ int numPars = this.Parameters == null ? 0 : this.Parameters.Count;
+ System.Type[] paramTypes = new Type[numPars];
+ for (int i = 0; i < numPars; i++)
+ {
+ Parameter par = this.Parameters[i];
+ if (par == null || par.Type == null) { Debug.Assert(false); return null; }
+ paramTypes[i] = par.Type.GetRuntimeType();
+ }
+ if (this.DeclaringType == this.DeclaringType.DeclaringModule.Types[0])
+ dmeth = new System.Reflection.Emit.DynamicMethod(name, attrs, callConv, rtype, paramTypes, module, skipVisibility);
+ else
+ dmeth = new System.Reflection.Emit.DynamicMethod(name, attrs, callConv, rtype, paramTypes, owner, skipVisibility);
+ dmeth.InitLocals = true;
+ ReGenerator reGenerator = new ReGenerator(dmeth.GetILGenerator());
+ reGenerator.VisitMethod(this);
+ }
+ return this.dynamicMethod;
+ }
+#endif
+#if !NoReflection
+ protected System.Reflection.MethodInfo methodInfo;
+ public virtual System.Reflection.MethodInfo GetMethodInfo()
+ {
+ if (this.methodInfo == null)
+ {
+ if (this.DeclaringType == null) return null;
+#if WHIDBEY
+ if (this.IsGeneric && this.Template != null)
+ {
+ try
+ {
+ System.Reflection.MethodInfo templateInfo = this.Template.GetMethodInfo();
+ if (templateInfo == null) return null;
+ TypeNodeList args = this.TemplateArguments;
+ Type[] arguments = new Type[args.Count];
+ for (int i = 0; i < args.Count; i++) arguments[i] = args[i].GetRuntimeType();
+ return templateInfo.MakeGenericMethod(arguments);
+ }
+ catch
+ {
+ //TODO: log error
+ return null;
+ }
+ }
+#endif
+ Type t = this.DeclaringType.GetRuntimeType();
+ if (t == null) return null;
+ Type retType = typeof(object);
+ if (!this.isGeneric)
+ {
+ //Can't do this for generic methods since it may involve a method type parameter
+ retType = this.ReturnType.GetRuntimeType();
+ if (retType == null) return null;
+ }
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Type[] types = new Type[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null || p.Type == null) return null;
+ Type pt;
+ if (this.isGeneric)
+ pt = types[i] = typeof(object); //Have to cheat here since the type might involve a type parameter of the method and getting the runtime type for that is a problem
+ //unless we already have the method info in hand
+ else
+ pt = types[i] = p.Type.GetRuntimeType();
+ if (pt == null) return null;
+ }
+ System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Method,
+ BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+ foreach (System.Reflection.MethodInfo meth in members)
+ {
+ if (meth == null) continue;
+ if (meth.IsStatic != this.IsStatic) continue;
+ if (meth.ReturnType != retType) continue;
+#if WHIDBEY
+ if (meth.IsGenericMethodDefinition)
+ {
+ TypeNodeList templateParams = this.TemplateParameters;
+ Type[] genericArgs = meth.GetGenericArguments();
+ if (templateParams == null || genericArgs == null || templateParameters.Count != genericArgs.Length) goto tryNext;
+ for (int i = 0, m = genericArgs.Length; i < m; i++)
+ {
+ TypeNode t1 = templateParameters[i];
+ Type t2 = genericArgs[i];
+ if (t1 == null || t2 == null || t1.Name == null || t1.Name.Name != t2.Name) goto tryNext;
+ }
+ }
+#endif
+ System.Reflection.ParameterInfo[] parameters = meth.GetParameters();
+ int parCount = parameters == null ? 0 : parameters.Length;
+ if (parCount != n) continue;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert parameters != null;
+ System.Reflection.ParameterInfo par = parameters[i];
+ if (par == null) goto tryNext;
+ if (this.isGeneric)
+ {
+ //We don't have the runtime type for the parameter, so just check that the name is the same
+ Parameter p = pars[i];
+ if (par.Name != p.Name.Name) goto tryNext;
+ }
+ else
+ {
+ if (par.ParameterType != types[i]) goto tryNext;
+ }
+ }
+ return this.methodInfo = meth;
+ tryNext: ;
+ }
+ }
+ return this.methodInfo;
+ }
+#endif
+#if !MinimalReader
+ protected TypeNode[] parameterTypes;
+ public virtual TypeNode[]/*!*/ GetParameterTypes()
+ {
+ if (this.parameterTypes != null) return this.parameterTypes;
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ TypeNode[] types = this.parameterTypes = new TypeNode[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null) continue;
+ types[i] = p.Type;
+ }
+ return types;
+ }
+#endif
+ public virtual bool ParametersMatch(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type != par2.Type) return false;
+ }
+ return true;
+ }
+#if !MinimalReader
+ public virtual bool ParametersMatchExceptLast(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n - 1; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type != par2.Type) return false;
+ }
+ return true;
+ }
+#endif
+ public virtual bool ParametersMatchStructurally(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type == null || par2.Type == null) return false;
+ if (par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type)) return false;
+ }
+ return true;
+ }
+#if !MinimalReader
+ public virtual bool ParametersMatchStructurallyIncludingOutFlag(ParameterList parameters)
+ {
+ return this.ParametersMatchStructurallyIncludingOutFlag(parameters, false);
+ }
+ public virtual bool ParametersMatchStructurallyIncludingOutFlag(ParameterList parameters, bool allowCoVariance)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type == null || par2.Type == null) return false;
+ if ((par1.Flags & ParameterFlags.Out) != (par2.Flags & ParameterFlags.Out)) return false;
+ if (par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type))
+ {
+ if (allowCoVariance && !par2.Type.IsValueType) return par2.Type.IsAssignableTo(par1.Type);
+ return false;
+ }
+ }
+ return true;
+ }
+ public virtual bool ParametersMatchStructurallyExceptLast(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n - 1; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type == null || par2.Type == null) return false;
+ if (par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type)) return false;
+ }
+ return true;
+ }
+ public virtual bool ParametersMatchIncludingOutFlag(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1.Type != par2.Type) return false;
+ if ((par1.Flags & ParameterFlags.Out) != (par2.Flags & ParameterFlags.Out)) return false;
+ }
+ return true;
+ }
+#endif
+ public virtual bool ParameterTypesMatch(TypeNodeList argumentTypes)
+ {
+ int n = this.Parameters == null ? 0 : this.Parameters.Count;
+ int m = argumentTypes == null ? 0 : argumentTypes.Count;
+ if (n != m) return false;
+ if (argumentTypes == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = this.Parameters[i];
+ if (par == null) return false;
+ TypeNode argType = argumentTypes[i];
+ if (par.Type != argType)
+ {
+ TypeNode pType = TypeNode.StripModifiers(par.Type);
+ argType = TypeNode.StripModifiers(argType);
+ if (pType != argType) return false;
+ }
+ }
+ return true;
+ }
+ public virtual bool ParameterTypesMatchStructurally(TypeNodeList argumentTypes)
+ {
+ int n = this.Parameters == null ? 0 : this.Parameters.Count;
+ int m = argumentTypes == null ? 0 : argumentTypes.Count;
+ if (n != m) return false;
+ if (argumentTypes == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = this.Parameters[i];
+ TypeNode argType = argumentTypes[i];
+ if (par.Type != argType)
+ {
+ TypeNode pType = TypeNode.StripModifiers(par.Type);
+ argType = TypeNode.StripModifiers(argType);
+ if (pType == null || !pType.IsStructurallyEquivalentTo(argType)) return false;
+ }
+ }
+ return true;
+ }
+ public virtual bool TemplateParametersMatch(TypeNodeList templateParameters)
+ {
+ TypeNodeList locPars = this.TemplateParameters;
+ if (locPars == null) return templateParameters == null || templateParameters.Count == 0;
+ if (templateParameters == null) return false;
+ int n = locPars.Count;
+ if (n != templateParameters.Count) return false;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode tp1 = locPars[i];
+ TypeNode tp2 = templateParameters[i];
+ if (tp1 == null || tp2 == null) return false;
+ if (tp1 != tp2 && !tp1.IsStructurallyEquivalentTo(tp2)) return false;
+ }
+ return true;
+ }
+#if UseSingularityPDB
+ internal TrivialHashtable contextForOffset;
+ internal void RecordSequencePoints(PdbFunction methodInfo) {
+ if (methodInfo == null || this.contextForOffset != null) return;
+ this.contextForOffset = new TrivialHashtable();
+ for (int i = 0, n = methodInfo.lines == null ? 0 : methodInfo.lines.Length; i < n; i++) {
+ PdbLines lines = methodInfo.lines[i];
+ PdbDocument doc = new PdbDocument(lines);
+ for (int j = 0, m = lines.lines.Length; j < m; j++) {
+ PdbLine line = lines.lines[j];
+ if (line.line != 0xfeefee)
+ this.contextForOffset[(int)line.offset+1] = new SourceContext(doc, j*2, j*2+1 );
+ }
+ }
+ }
+#elif !ROTOR
+ internal TrivialHashtable contextForOffset;
+ internal void RecordSequencePoints(ISymUnmanagedMethod methodInfo)
+ {
+ if (methodInfo == null || this.contextForOffset != null) return;
+ this.contextForOffset = new TrivialHashtable();
+ uint count = methodInfo.GetSequencePointCount();
+ IntPtr[] docPtrs = new IntPtr[count];
+ uint[] startLines = new uint[count];
+ uint[] startCols = new uint[count];
+ uint[] endLines = new uint[count];
+ uint[] endCols = new uint[count];
+ uint[] offsets = new uint[count];
+ uint numPoints;
+ methodInfo.GetSequencePoints(count, out numPoints, offsets, docPtrs, startLines, startCols, endLines, endCols);
+ Debug.Assert(count == numPoints);
+ for (int i = 0; i < count; i++)
+ {
+ //The magic hex constant below works around weird data reported from GetSequencePoints.
+ //The constant comes from ILDASM's source code, which performs essentially the same test.
+ const uint Magic = 0xFEEFEE;
+ if (startLines[i] >= Magic || endLines[i] >= Magic) continue;
+ UnmanagedDocument doc = new UnmanagedDocument(docPtrs[i]);
+ this.contextForOffset[(int)offsets[i] + 1] =
+#if !FxCop
+ new SourceContext(doc, doc.GetOffset(startLines[i], startCols[i]), doc.GetOffset(endLines[i], endCols[i]));
+#else
+ new SourceContext(doc.Name, startLines[i], endLines[i], startCols[i], endCols[i]);
+#endif
+ }
+ for (int i = 0; i < count; i++)
+ System.Runtime.InteropServices.Marshal.Release(docPtrs[i]);
+ }
+#endif
+ private static Method NotSpecified = new Method();
+ private Method template;
+ /// <summary>The (generic) method template from which this method was instantiated. Null if this is not a (generic) method template instance.</summary>
+ public Method Template
+ {
+ get
+ {
+ Method result = this.template;
+#if ExtendedRuntime
+ if (result == null){
+ AttributeList attributes = this.Attributes;
+ lock(this){
+ if (this.template != null) return this.template;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++){
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null || mb.BoundMember == null || mb.BoundMember.DeclaringType != SystemTypes.TemplateInstanceAttribute) continue;
+ ExpressionList exprs = attr.Expressions;
+ if (exprs == null || exprs.Count != 2) continue;
+ Literal lit = exprs[0] as Literal;
+ if (lit == null) continue;
+ TypeNode templ = lit.Value as TypeNode;
+ if (templ != null){
+ lit = exprs[1] as Literal;
+ if (lit == null) continue;
+ object[] types = lit.Value as object[];
+ if (types == null) continue;
+ int m = types == null ? 0 : types.Length;
+ TypeNodeList templateArguments = new TypeNodeList(m);
+ for (int j = 0; j < m; j++){
+ //^ assert types != null;
+ TypeNode t = types[j] as TypeNode;
+ if (t == null) continue;
+ templateArguments.Add(t);
+ }
+ this.TemplateArguments = templateArguments;
+ MemberList members = templ.GetMembersNamed(this.Name);
+ if (members != null)
+ for (int j = 0, k = members.Count; j < k; j++){
+ Method meth = members[j] as Method;
+ if (meth == null) continue;
+ if (meth.ParametersMatch(this.Parameters)){
+ this.template = result = meth; break;
+ }
+ }
+ }
+ }
+ if (result == null)
+ this.template = Method.NotSpecified;
+ }
+ }else
+#endif
+ if (result == Method.NotSpecified)
+ return null;
+ return result;
+ }
+ set
+ {
+ this.template = value;
+ }
+ }
+ private TypeNodeList templateArguments;
+ /// <summary>
+ /// The arguments used when this (generic) method template instance was instantiated.
+ /// </summary>
+ public TypeNodeList TemplateArguments
+ {
+ get { return this.templateArguments; }
+ set { this.templateArguments = value; }
+ }
+ internal TypeNodeList templateParameters;
+ public virtual TypeNodeList TemplateParameters
+ {
+ get
+ {
+ TypeNodeList result = this.templateParameters;
+#if ExtendedRuntime
+ if (result == null && this.Template == null){
+ this.TemplateParameters = result = new TypeNodeList();
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++){
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null || mb.BoundMember == null || mb.BoundMember.DeclaringType != SystemTypes.TemplateAttribute) continue;
+ ExpressionList exprs = attr.Expressions;
+ if (exprs == null || exprs.Count != 1) continue;
+ Literal lit = exprs[0] as Literal;
+ if (lit == null) continue;
+ object[] types = lit.Value as object[];
+ if (types == null) continue;
+ for (int j = 0, m = types == null ? 0 : types.Length; j < m; j++){
+ TypeNode t = types[j] as TypeNode;
+ if (t == null) continue;
+ if (t.NodeType == NodeType.TypeParameter || t.NodeType == NodeType.ClassParameter)
+ result.Add(t);
+ }
+ attributes[i] = null;
+ }
+ }
+ if (result == null || result.Count == 0) return null;
+#endif
+ return result;
+ }
+ set
+ {
+ this.templateParameters = value;
+ }
+ }
+ public virtual Method/*!*/ GetTemplateInstance(TypeNode referringType, params TypeNode[] typeArguments)
+ {
+ return this.GetTemplateInstance(referringType, new TypeNodeList(typeArguments));
+ }
+ public virtual Method/*!*/ GetTemplateInstance(TypeNode referringType, TypeNodeList typeArguments)
+ {
+ if (referringType == null || this.DeclaringType == null) { Debug.Assert(false); return this; }
+ if (this.IsGeneric) referringType = this.DeclaringType;
+ if (referringType != this.DeclaringType && referringType.DeclaringModule == this.DeclaringType.DeclaringModule)
+ return this.GetTemplateInstance(this.DeclaringType, typeArguments);
+ if (referringType.structurallyEquivalentMethod == null)
+ referringType.structurallyEquivalentMethod = new TrivialHashtableUsingWeakReferences();
+ Module module = referringType.DeclaringModule;
+ if (module == null) return this;
+ int n = typeArguments == null ? 0 : typeArguments.Count;
+ if (n == 0 || typeArguments == null) return this;
+ StringBuilder sb = new StringBuilder(this.Name.ToString());
+ sb.Append('<');
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode ta = typeArguments[i]; if (ta == null) continue;
+ sb.Append(ta.FullName);
+ if (i < n - 1) sb.Append(',');
+ }
+ sb.Append('>');
+ Identifier mangledName = Identifier.For(sb.ToString());
+ lock (this)
+ {
+ Method m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
+ int counter = 1;
+ while (m != null)
+ {
+ if (m.template == this && Method.TypeListsAreEquivalent(m.TemplateArguments, typeArguments))
+ return m;
+ mangledName = Identifier.For(mangledName.ToString() + counter++);
+ m = (Method)referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey];
+ }
+ Duplicator duplicator = new Duplicator(referringType.DeclaringModule, referringType);
+ duplicator.RecordOriginalAsTemplate = true;
+ duplicator.SkipBodies = true;
+ Method result = duplicator.VisitMethod(this);
+ //^ assume result != null;
+ result.Attributes = this.Attributes; //These do not get specialized, but may need to get normalized
+ result.Name = mangledName;
+ result.fullName = null;
+ result.template = this;
+ result.TemplateArguments = typeArguments;
+ TypeNodeList templateParameters = result.TemplateParameters;
+ result.TemplateParameters = null;
+#if !MinimalReader
+ result.IsNormalized = true;
+#endif
+ if (!this.IsGeneric)
+ {
+ ParameterList pars = this.Parameters;
+ ParameterList rpars = result.Parameters;
+ if (pars != null && rpars != null && rpars.Count >= pars.Count)
+ for (int i = 0, count = pars.Count; i < count; i++)
+ {
+ Parameter p = pars[i];
+ Parameter rp = rpars[i];
+ if (p == null || rp == null) continue;
+ rp.Attributes = p.Attributes; //These do not get specialized, but may need to get normalized
+ }
+ }
+ if (!this.IsGeneric && !(result.IsStatic) && this.DeclaringType != referringType)
+ {
+ result.Flags &= ~(MethodFlags.Virtual | MethodFlags.NewSlot);
+ result.Flags |= MethodFlags.Static;
+ result.CallingConvention &= ~CallingConventionFlags.HasThis;
+ result.CallingConvention |= CallingConventionFlags.ExplicitThis;
+ ParameterList pars = result.Parameters;
+ if (pars == null) result.Parameters = pars = new ParameterList(1);
+ Parameter thisPar = new Parameter(StandardIds.This, this.DeclaringType);
+ pars.Add(thisPar);
+ for (int i = pars.Count - 1; i > 0; i--)
+ pars[i] = pars[i - 1];
+ pars[0] = thisPar;
+ }
+ referringType.structurallyEquivalentMethod[mangledName.UniqueIdKey] = result;
+ Specializer specializer = new Specializer(module, templateParameters, typeArguments);
+ specializer.VisitMethod(result);
+ if (this.IsGeneric) { result.DeclaringType = this.DeclaringType; return result; }
+ if (this.IsAbstract) return result;
+ referringType.Members.Add(result);
+ return result;
+ }
+ }
+ private static bool TypeListsAreEquivalent(TypeNodeList list1, TypeNodeList list2)
+ {
+ if (list1 == null || list2 == null) return list1 == list2;
+ int n = list1.Count;
+ if (n != list2.Count) return false;
+ for (int i = 0; i < n; i++)
+ if (list1[i] != list2[i]) return false;
+ return true;
+ }
+#if !MinimalReader
+ /// <summary>
+ /// Returns the local associated with the given field, allocating a new local if necessary.
+ /// </summary>
+ public virtual Local/*!*/ GetLocalForField(Field/*!*/ f)
+ {
+ Local loc = (Local)this.Locals[f.UniqueKey];
+ if (loc == null)
+ {
+ this.Locals[f.UniqueKey] = loc = new Local(f.Name, f.Type);
+ loc.SourceContext = f.Name.SourceContext;
+ }
+ return loc;
+ }
+#endif
+ //TODO: Also need to add a method for allocating locals
+ public Method CreateExplicitImplementation(TypeNode implementingType, ParameterList parameters, StatementList body)
+ {
+ Method m = new Method(implementingType, null, this.Name, parameters, this.ReturnType, new Block(body));
+ m.CallingConvention = CallingConventionFlags.HasThis;
+ m.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot | MethodFlags.Final;
+ m.ImplementedInterfaceMethods = new MethodList(this);
+ //m.ImplementedTypes = new TypeNodeList(this.DeclaringType);
+ return m;
+ }
+
+ public virtual bool TypeParameterCountsMatch(Method meth2)
+ {
+ if (meth2 == null) return false;
+ int n = this.TemplateParameters == null ? 0 : this.TemplateParameters.Count;
+ int m = meth2.TemplateParameters == null ? 0 : meth2.TemplateParameters.Count;
+ return n == m;
+ }
+ public override string ToString()
+ {
+ return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
+ }
+#if !MinimalReader
+ public bool GetIsCompilerGenerated()
+ {
+ InstanceInitializer ii = this as InstanceInitializer;
+ return this.HasCompilerGeneratedSignature || (ii != null && ii.IsCompilerGenerated);
+ }
+#endif
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ base.GetName(options, name);
+ AppendTypeParameters(options, name);
+ AppendParametersAndReturnType(options, this.Parameters, '(', ')', this.ReturnType, name);
+ }
+ private void AppendTypeParameters(MemberFormat options, StringBuilder name)
+ {
+ if (options.ShowGenericMethodTypeParameterNames == false
+ || this.templateParameters == null
+ || this.templateParameters.Count == 0)
+ return;
+
+ name.Append('<');
+ TypeNodeList templateParameters = this.TemplateParameters;
+ for (int i = 0; i < templateParameters.Count; i++)
+ {
+ TypeNode templateParameter = templateParameters[i];
+ if (i != 0)
+ {
+ name.Append(',');
+ if (options.InsertSpacesBetweenMethodTypeParameters)
+ name.Append(' ');
+ }
+ name.Append(templateParameter.Name.Name);
+ }
+ name.Append('>');
+ }
+
+ internal static void AppendParametersAndReturnType(MemberFormat options, ParameterCollection parameters, char parametersPrefix, char parametersSuffix, TypeNode returnType, StringBuilder name)
+ {
+ AppendParameters(options.Parameters, parameters, parametersPrefix, parametersSuffix, name);
+ AppendReturnType(options.ReturnType, returnType, name);
+ }
+
+ internal static void AppendParameters(ParameterFormat options, ParameterCollection parameters, char prefix, char suffix, StringBuilder name)
+ {
+ if (parameters == null)
+ return;
+
+ if (options.TypeName == TypeNameFormat.None && options.ShowParameterNames == false)
+ return;
+
+ name.Append(prefix);
+ for (int i = 0; i < parameters.Count; ++i)
+ {
+ Parameter parameter = parameters[i];
+ if (i > 0)
+ {
+ name.Append(',');
+ if (options.InsertSpacesBetweenParameters)
+ name.Append(' ');
+ }
+ if (options.TypeName != TypeNameFormat.None)
+ {
+ parameter.Type.GetName(options, name);
+ if (options.ShowParameterNames) name.Append(' ');
+ }
+ if (options.ShowParameterNames)
+ name.Append(parameter.Name.Name);
+ }
+ name.Append(suffix);
+ }
+
+ internal static void AppendReturnType(TypeFormat options, TypeNode returnType, StringBuilder name)
+ {
+ if (options.TypeName == TypeNameFormat.None)
+ return;
+
+ name.Append(':');
+ returnType.GetName(options, name);
+ }
+#endif
+ }
+#if !MinimalReader
+ public class ProxyMethod : Method
+ {
+ public Method ProxyFor;
+ public ProxyMethod(TypeNode declaringType, AttributeList attributes, Identifier name, ParameterList parameters, TypeNode returnType, Block body)
+ : base(declaringType, attributes, name, parameters, returnType, body) { }
+ }
+#endif
+ public class InstanceInitializer : Method
+ {
+#if !MinimalReader
+ /// <summary>
+ /// True if this constructor calls a constructor declared in the same class, as opposed to the base class.
+ /// </summary>
+ public bool IsDeferringConstructor;
+ /// <summary>
+ /// When the source uses the C# compatibility mode, base calls cannot be put after non-null
+ /// field initialization, but must be put before the body. But the user can specify where
+ /// the base ctor call should be performed by using "base;" as a marker. During parsing
+ /// this flag is set so the right code transformations can be performed at code generation.
+ /// </summary>
+ public bool ContainsBaseMarkerBecauseOfNonNullFields;
+ public Block BaseOrDefferingCallBlock;
+ public bool IsCompilerGenerated = false;
+#endif
+ public InstanceInitializer()
+ : base()
+ {
+ this.NodeType = NodeType.InstanceInitializer;
+ this.CallingConvention = CallingConventionFlags.HasThis;
+ this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName;
+ this.Name = StandardIds.Ctor;
+ this.ReturnType = CoreSystemTypes.Void;
+ }
+ public InstanceInitializer(MethodBodyProvider provider, object handle)
+ : base(provider, handle)
+ {
+ this.NodeType = NodeType.InstanceInitializer;
+ }
+#if !MinimalReader
+ public InstanceInitializer(TypeNode declaringType, AttributeList attributes, ParameterList parameters, Block body)
+ : this(declaringType, attributes, parameters, body, CoreSystemTypes.Void)
+ {
+ }
+ public InstanceInitializer(TypeNode declaringType, AttributeList attributes, ParameterList parameters, Block body, TypeNode returnType)
+ : base(declaringType, attributes, StandardIds.Ctor, parameters, null, body)
+ {
+ this.NodeType = NodeType.InstanceInitializer;
+ this.CallingConvention = CallingConventionFlags.HasThis;
+ this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName;
+ this.Name = StandardIds.Ctor;
+ this.ReturnType = returnType;
+ }
+#endif
+#if !NoReflection
+ protected System.Reflection.ConstructorInfo constructorInfo;
+ public virtual System.Reflection.ConstructorInfo GetConstructorInfo()
+ {
+ if (this.constructorInfo == null)
+ {
+ if (this.DeclaringType == null) return null;
+ Type t = this.DeclaringType.GetRuntimeType();
+ if (t == null) return null;
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Type[] types = new Type[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null || p.Type == null) return null;
+ Type pt = types[i] = p.Type.GetRuntimeType();
+ if (pt == null) return null;
+ }
+ System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Constructor,
+ BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ foreach (System.Reflection.ConstructorInfo cons in members)
+ {
+ if (cons == null) continue;
+ System.Reflection.ParameterInfo[] parameters = cons.GetParameters();
+ if (parameters != null)
+ {
+ if (parameters.Length != n) continue;
+ for (int i = 0; i < n; i++)
+ {
+ System.Reflection.ParameterInfo par = parameters[i];
+ if (par == null || par.ParameterType != types[i]) goto tryNext;
+ }
+ }
+ return this.constructorInfo = cons;
+ tryNext: ;
+ }
+ }
+ return this.constructorInfo;
+ }
+#endif
+#if !NoReflection
+ public override System.Reflection.MethodInfo GetMethodInfo()
+ {
+ return null;
+ }
+ public virtual object Invoke(params object[] arguments)
+ {
+ System.Reflection.ConstructorInfo constr = this.GetConstructorInfo();
+ if (constr == null) return null;
+ return constr.Invoke(arguments);
+ }
+ public virtual Literal Invoke(params Literal[] arguments)
+ {
+ int n = arguments == null ? 0 : arguments.Length;
+ object[] args = n == 0 ? null : new object[n];
+ if (args != null && arguments != null)
+ for (int i = 0; i < n; i++)
+ {
+ Literal lit = arguments[i];
+ args[i] = lit == null ? null : lit.Value;
+ }
+ return new Literal(this.Invoke(args));
+ }
+#endif
+ //initializers never override a base class initializer
+ public override bool OverridesBaseClassMember
+ {
+ get { return false; }
+ set { }
+ }
+ public override Member OverriddenMember
+ {
+ get { return null; }
+ set { }
+ }
+ public override Method OverriddenMethod
+ {
+ get { return null; }
+ set { }
+ }
+ public override string ToString()
+ {
+ return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "(" + this.Parameters + ")";
+ }
+#if !MinimalReader
+ public virtual MemberList GetAttributeConstructorNamedParameters()
+ {
+ TypeNode type = this.DeclaringType;
+ if (type == null || !type.IsAssignableTo(SystemTypes.Attribute) || type.Members == null)
+ return null;
+ MemberList memList = type.Members;
+ int n = memList.Count;
+ MemberList ml = new MemberList(memList.Count);
+ for (int i = 0; i < n; ++i)
+ {
+ Property p = memList[i] as Property;
+ if (p != null && p.IsPublic)
+ {
+ if (p.Setter != null && p.Getter != null)
+ ml.Add(p);
+ continue;
+ }
+ Field f = memList[i] as Field;
+ if (f != null && !f.IsInitOnly && f.IsPublic)
+ {
+ ml.Add(f);
+ }
+ }
+ return ml;
+ }
+#endif
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ GetInitializerName(options, this.DeclaringType, this.Parameters, name, StandardIds.Ctor.Name);
+ }
+ internal static void GetInitializerName(MemberFormat options, TypeNode declaringType, ParameterCollection parameters, StringBuilder name, string methodName)
+ {
+ if (options.Type.TypeName != TypeNameFormat.None)
+ {
+ declaringType.GetName(options, name);
+ name.Append('.');
+ }
+ name.Append(methodName);
+ AppendParameters(options.Parameters, parameters, '(', ')', name);
+ }
+#endif
+ }
+ public class StaticInitializer : Method
+ {
+ public StaticInitializer()
+ : base()
+ {
+ this.NodeType = NodeType.StaticInitializer;
+ this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
+ this.Name = StandardIds.CCtor;
+ this.ReturnType = CoreSystemTypes.Void;
+ }
+ public StaticInitializer(MethodBodyProvider provider, object handle)
+ : base(provider, handle)
+ {
+ this.NodeType = NodeType.StaticInitializer;
+ }
+#if !MinimalReader
+ public StaticInitializer(TypeNode declaringType, AttributeList attributes, Block body)
+ : base(declaringType, attributes, StandardIds.CCtor, null, null, body)
+ {
+ this.NodeType = NodeType.StaticInitializer;
+ this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
+ this.Name = StandardIds.CCtor;
+ this.ReturnType = CoreSystemTypes.Void;
+ }
+ public StaticInitializer(TypeNode declaringType, AttributeList attributes, Block body, TypeNode voidTypeExpression)
+ : base(declaringType, attributes, StandardIds.CCtor, null, null, body)
+ {
+ this.NodeType = NodeType.StaticInitializer;
+ this.Flags = MethodFlags.SpecialName | MethodFlags.RTSpecialName | MethodFlags.Static | MethodFlags.HideBySig | MethodFlags.Private;
+ this.Name = StandardIds.CCtor;
+ this.ReturnType = voidTypeExpression;
+ }
+#endif
+#if !NoReflection
+ protected System.Reflection.ConstructorInfo constructorInfo;
+ public virtual System.Reflection.ConstructorInfo GetConstructorInfo()
+ {
+ if (this.constructorInfo == null)
+ {
+ if (this.DeclaringType == null) return null;
+ Type t = this.DeclaringType.GetRuntimeType();
+ if (t == null) return null;
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Type[] types = new Type[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null || p.Type == null) return null;
+ Type pt = types[i] = p.Type.GetRuntimeType();
+ if (pt == null) return null;
+ }
+ System.Reflection.MemberInfo[] members = t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Constructor,
+ BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+ foreach (System.Reflection.ConstructorInfo cons in members)
+ {
+ if (cons == null) continue;
+ System.Reflection.ParameterInfo[] parameters = cons.GetParameters();
+ int numPars = parameters == null ? 0 : parameters.Length;
+ if (numPars != n) continue;
+ if (parameters != null)
+ for (int i = 0; i < n; i++)
+ {
+ System.Reflection.ParameterInfo par = parameters[i];
+ if (par == null || par.ParameterType != types[i]) goto tryNext;
+ }
+ return this.constructorInfo = cons;
+ tryNext: ;
+ }
+ }
+ return this.constructorInfo;
+ }
+ public override System.Reflection.MethodInfo GetMethodInfo()
+ {
+ return null;
+ }
+#endif
+ //initializers never override a base class initializer
+ public override bool OverridesBaseClassMember
+ {
+ get { return false; }
+ set { }
+ }
+ public override Member OverriddenMember
+ {
+ get { return null; }
+ set { }
+ }
+ public override Method OverriddenMethod
+ {
+ get { return null; }
+ set { }
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ InstanceInitializer.GetInitializerName(options, this.DeclaringType, this.Parameters, name, StandardIds.CCtor.Name);
+ }
+#endif
+ }
+#if !MinimalReader
+ public class FieldInitializerBlock : Block
+ {
+ public TypeNode Type;
+ public bool IsStatic;
+ public FieldInitializerBlock()
+ : base()
+ {
+ this.NodeType = NodeType.FieldInitializerBlock;
+ }
+ public FieldInitializerBlock(TypeNode type, bool isStatic)
+ : base()
+ {
+ this.NodeType = NodeType.FieldInitializerBlock;
+ this.Type = type;
+ this.IsStatic = isStatic;
+ }
+ }
+#endif
+#if !MinimalReader
+ public class ParameterField : Field
+ {
+ protected Parameter parameter;
+ public ParameterField()
+ {
+ }
+ public ParameterField(TypeNode declaringType, AttributeList attributes, FieldFlags flags, Identifier name,
+ TypeNode Type, Literal defaultValue)
+ : base(declaringType, attributes, flags, name, Type, defaultValue)
+ {
+ }
+ public virtual Parameter Parameter
+ {
+ get
+ {
+ return this.parameter;
+ }
+ set
+ {
+ this.parameter = value;
+ }
+ }
+ }
+#endif
+ public class Field : Member
+ {
+#if !MinimalReader
+ /// <summary>Provides a value that is assigned to the field upon initialization.</summary>
+ public Expression Initializer;
+ public TypeNode TypeExpression;
+ public bool HasOutOfBandContract;
+ public InterfaceList ImplementedInterfaces;
+ public InterfaceList ImplementedInterfaceExpressions;
+ // if this is the backing field for some event, then ForEvent is that event
+ public Event ForEvent;
+ public bool IsModelfield = false; //set to true if this field serves as the representation of a modelfield in a class
+#endif
+ public Field()
+ : base(NodeType.Field)
+ {
+ }
+ public Field(Identifier name)
+ : base(NodeType.Field)
+ {
+ this.Name = name;
+ }
+ public Field(TypeNode declaringType, AttributeList attributes, FieldFlags flags, Identifier name,
+ TypeNode type, Literal defaultValue)
+ : base(declaringType, attributes, name, NodeType.Field)
+ {
+ this.defaultValue = defaultValue;
+ this.flags = flags;
+ this.type = type;
+ }
+ private Literal defaultValue;
+ /// <summary>The compile-time value to be substituted for references to this field if it is a literal.</summary>
+ public Literal DefaultValue
+ { //TODO: rename this to LiteralValue
+ get { return this.defaultValue; }
+ set { this.defaultValue = value; }
+ }
+ private FieldFlags flags;
+ public FieldFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private int offset;
+ public int Offset
+ {
+ get { return this.offset; }
+ set { this.offset = value; }
+ }
+ private bool isVolatile;
+ /// <summary>True if the field may not be cached. Used for sharing data between multiple threads.</summary>
+ public bool IsVolatile
+ {
+ get { return this.isVolatile; }
+ set { this.isVolatile = value; }
+ }
+ private TypeNode type;
+ /// <summary>The type of values that may be stored in the field.</summary>
+ public TypeNode Type
+ {
+ get { return this.type; }
+ set { this.type = value; }
+ }
+ private MarshallingInformation marshallingInformation;
+ public MarshallingInformation MarshallingInformation
+ {
+ get { return this.marshallingInformation; }
+ set { this.marshallingInformation = value; }
+ }
+ private byte[] initialData;
+ public byte[] InitialData
+ {
+ get { return this.initialData; }
+ set { this.initialData = value; }
+ }
+ internal PESection section;
+ public PESection Section
+ {
+ get { return this.section; }
+ set { this.section = value; }
+ }
+ protected string fullName;
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ string result = this.fullName;
+ if (result == null)
+ this.fullName = result = this.DeclaringType.FullName + "." + (this.Name == null ? "" : this.Name.ToString());
+ return result;
+ }
+ }
+#if !NoXml
+ protected override Identifier GetDocumentationId()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("F:");
+ if (this.DeclaringType == null) return Identifier.Empty;
+ sb.Append(this.DeclaringType.FullName);
+ sb.Append(".");
+ if (this.Name == null) return Identifier.Empty;
+ sb.Append(this.Name.Name);
+ return Identifier.For(sb.ToString());
+ }
+#endif
+#if !NoReflection
+ public static Field GetField(System.Reflection.FieldInfo fieldInfo)
+ {
+ if (fieldInfo == null) return null;
+ TypeNode tn = TypeNode.GetTypeNode(fieldInfo.DeclaringType);
+ if (tn == null) return null;
+ return tn.GetField(Identifier.For(fieldInfo.Name));
+ }
+#endif
+#if !NoReflection
+ protected System.Reflection.FieldInfo fieldInfo;
+ public virtual System.Reflection.FieldInfo GetFieldInfo()
+ {
+ if (this.fieldInfo == null)
+ {
+ TypeNode tn = this.DeclaringType;
+ if (tn == null) return null;
+ Type t = tn.GetRuntimeType();
+ if (t == null) return null;
+ System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.DeclaredOnly;
+ if (this.IsPublic) flags |= System.Reflection.BindingFlags.Public; else flags |= System.Reflection.BindingFlags.NonPublic;
+ if (this.IsStatic) flags |= System.Reflection.BindingFlags.Static; else flags |= System.Reflection.BindingFlags.Instance;
+ this.fieldInfo = t.GetField(this.Name.ToString(), flags);
+ }
+ return this.fieldInfo;
+ }
+#endif
+ /// <summary>True if all references to the field are replaced with a value that is determined at compile-time.</summary>
+ public virtual bool IsLiteral
+ {
+ get { return (this.Flags & FieldFlags.Literal) != 0; }
+ }
+ public override bool IsAssembly
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Assembly; }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.CompilerControlled; }
+ }
+ public override bool IsFamily
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Family; }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.FamANDAssem; }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.FamORAssem; }
+ }
+ /// <summary>True if the field may only be assigned to inside the constructor.</summary>
+ public virtual bool IsInitOnly
+ {
+ get { return (this.Flags & FieldFlags.InitOnly) != 0; }
+ }
+ public override bool IsPrivate
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Private; }
+ }
+ public override bool IsPublic
+ {
+ get { return (this.Flags & FieldFlags.FieldAccessMask) == FieldFlags.Public; }
+ }
+ public override bool IsSpecialName
+ {
+ get { return (this.Flags & FieldFlags.SpecialName) != 0; }
+ }
+ public override bool IsStatic
+ {
+ get { return (this.Flags & FieldFlags.Static) != 0; }
+ }
+ public override bool IsVisibleOutsideAssembly
+ {
+ get
+ {
+ if (this.DeclaringType != null && !this.DeclaringType.IsVisibleOutsideAssembly) return false;
+ switch (this.Flags & FieldFlags.FieldAccessMask)
+ {
+ case FieldFlags.Public:
+ return true;
+ case FieldFlags.Family:
+ case FieldFlags.FamORAssem:
+ return this.DeclaringType != null && !this.DeclaringType.IsSealed;
+ default:
+ return false;
+ }
+ }
+ }
+#if !NoReflection
+ public virtual object GetValue(object targetObject)
+ {
+ System.Reflection.FieldInfo fieldInfo = this.GetFieldInfo();
+ if (fieldInfo == null) return null;
+ return fieldInfo.GetValue(targetObject);
+ }
+ public virtual Literal GetValue(Literal/*!*/ targetObject)
+ {
+ return new Literal(this.GetValue(targetObject.Value));
+ }
+ public virtual void SetValue(object targetObject, object value)
+ {
+ System.Reflection.FieldInfo fieldInfo = this.GetFieldInfo();
+ if (fieldInfo == null) return;
+ fieldInfo.SetValue(targetObject, value);
+ }
+ public virtual void SetValue(Literal/*!*/ targetObject, Literal/*!*/ value)
+ {
+ this.SetValue(targetObject.Value, value.Value);
+ }
+#endif
+#if ExtendedRuntime
+ ReferenceFieldSemantics referenceSemantics;
+ public ReferenceFieldSemantics ReferenceSemantics{
+ get{
+ if (this.referenceSemantics == ReferenceFieldSemantics.NotComputed){
+ ReferenceFieldSemantics referenceKind;
+ TypeNode t = this.Type;
+ if (t == null) return this.referenceSemantics;
+ if (t is Struct){
+ TypeNodeList args;
+ bool b = t.IsAssignableToInstanceOf(SystemTypes.GenericIEnumerable, out args);
+ if ( b && args!= null && args.Count > 0 && args[0] != null && args[0].IsObjectReferenceType)
+ referenceKind = ReferenceFieldSemantics.EnumerableStructOfReferences;
+ else if (t.IsAssignableTo(SystemTypes.IEnumerable))
+ referenceKind = ReferenceFieldSemantics.EnumerableStructOfReferences;
+ else
+ referenceKind = ReferenceFieldSemantics.NonReference;
+ }else if (t != null && t.IsObjectReferenceType)
+ referenceKind = ReferenceFieldSemantics.Reference;
+ else
+ referenceKind = ReferenceFieldSemantics.NonReference;
+ if (referenceKind == ReferenceFieldSemantics.NonReference)
+ this.referenceSemantics = referenceKind | ReferenceFieldSemantics.None;
+ else{
+ if (this.GetAttribute(SystemTypes.LockProtectedAttribute) != null)
+ this.referenceSemantics = referenceKind | ReferenceFieldSemantics.LockProtected;
+ else if (this.GetAttribute(SystemTypes.ImmutableAttribute) != null)
+ this.referenceSemantics = referenceKind | ReferenceFieldSemantics.Immutable;
+ else if (this.GetAttribute(SystemTypes.RepAttribute) != null)
+ this.referenceSemantics = referenceKind | ReferenceFieldSemantics.Rep;
+ else if (this.GetAttribute(SystemTypes.PeerAttribute) != null)
+ this.referenceSemantics = referenceKind | ReferenceFieldSemantics.Peer;
+ else {
+ bool isRep = false;
+ bool isPeer = false;
+ AttributeNode attr = this.GetAttribute(SystemTypes.OwnedAttribute);
+ if (attr != null) {
+ ExpressionList exprs = attr.Expressions;
+ if (exprs != null && exprs.Count > 0) {
+ Expression arg = exprs[0];
+ Literal lit = arg as Literal;
+ if (lit != null) {
+ if (lit.Value is bool)
+ isRep = (bool)lit.Value;
+ else if (lit.Value is string) {
+ isRep = (string)lit.Value == "this";
+ isPeer = (string)lit.Value == "peer";
+ }
+ }
+ for (int n = attr.Expressions == null ? 0 : attr.Expressions.Count, i = 0; i < n; i++) {
+ Expression e = attr.Expressions[i];
+ AssignmentExpression ae = e as AssignmentExpression;
+ if (ae != null) {
+ AssignmentStatement s = ae.AssignmentStatement as AssignmentStatement;
+ if (s != null) {
+ Literal lit2 = s.Source as Literal;
+ if (lit2 != null && lit2.Value is bool)
+ isRep = (bool)lit2.Value;
+ else if (lit2 != null && lit2.Value is string) {
+ isRep = (string)lit2.Value == "this";
+ isPeer = (string)lit2.Value == "peer";
+
+ }
+
+ }
+ }
+ }
+ } else {
+ // this is the default case: [Owned] without any arguments
+ isRep = true;
+ }
+ }
+ ReferenceFieldSemantics r = ReferenceFieldSemantics.None;
+ if (isRep) r = ReferenceFieldSemantics.Rep;
+ if (isPeer) r = ReferenceFieldSemantics.Peer;
+ this.referenceSemantics = referenceKind | r;
+ }
+ }
+ }
+ return this.referenceSemantics;
+ }
+ set {
+ this.referenceSemantics = value;
+ }
+ }
+ public bool IsOwned{
+ get{
+ return this.IsRep || this.IsPeer;
+ }
+ }
+ public bool IsOnce
+ {
+ get {
+ return this.GetAttribute(SystemTypes.OnceAttribute) != null;
+ }
+ }
+
+ public bool IsRep{
+ get {
+ return this.ReferenceSemantics == (ReferenceFieldSemantics.Rep | ReferenceFieldSemantics.Reference);
+ }
+ }
+ public bool IsPeer {
+ get {
+ return this.ReferenceSemantics == (ReferenceFieldSemantics.Peer | ReferenceFieldSemantics.Reference);
+ }
+ }
+ public bool IsLockProtected {
+ get{
+ return this.ReferenceSemantics == (ReferenceFieldSemantics.LockProtected | ReferenceFieldSemantics.Reference);
+ }
+ }
+ public bool IsStrictReadonly {
+ get {
+ return this.GetAttribute(ExtendedRuntimeTypes.StrictReadonlyAttribute) != null;
+ }
+ }
+#endif
+ public override string ToString()
+ {
+ return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ base.GetName(options, name);
+ Method.AppendReturnType(options.ReturnType, this.Type, name);
+ }
+#endif
+ }
+#if ExtendedRuntime
+ /// <summary>
+ /// The behavior of a field in the Spec# object invariants/ownership/concurrency methodology.
+ /// </summary>
+ public enum ReferenceFieldSemantics{
+ NotComputed,
+ None,
+ Rep,
+ LockProtected,
+ Immutable,
+ Peer,
+ SemanticsMask = 0xff,
+ Reference = 0x100,
+ EnumerableStructOfReferences = 0x200,
+ NonReference = 0x300,
+ ReferenceMask = 0xff00,
+ }
+#endif
+#if FxCop
+ public class PropertyNode : Member{
+#else
+ public class Property : Member
+ {
+#endif
+#if !MinimalReader
+ /// <summary>
+ /// The list of types (just one in C#) that contain abstract or virtual properties that are explicity implemented or overridden by this property.
+ /// </summary>
+ public TypeNodeList ImplementedTypes;
+ public TypeNodeList ImplementedTypeExpressions;
+ public bool IsModelfield = false; //set to true if this property serves as the representation of a modelfield in an interface
+#endif
+#if FxCop
+ public PropertyNode()
+#else
+ public Property()
+#endif
+ : base(NodeType.Property)
+ {
+ }
+#if !MinimalReader
+ public Property(TypeNode declaringType, AttributeList attributes, PropertyFlags flags, Identifier name,
+ Method getter, Method setter)
+ : base(declaringType, attributes, name, NodeType.Property)
+ {
+ this.flags = flags;
+ this.getter = getter;
+ this.setter = setter;
+ if (getter != null) getter.DeclaringMember = this;
+ if (setter != null) setter.DeclaringMember = this;
+ }
+#endif
+ private PropertyFlags flags;
+ public PropertyFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private Method getter;
+ /// <summary>The method that is called to get the value of this property. Corresponds to the get clause in C#.</summary>
+ public Method Getter
+ {
+ get { return this.getter; }
+ set { this.getter = value; }
+ }
+ private Method setter;
+ /// <summary>The method that is called to set the value of this property. Corresponds to the set clause in C#.</summary>
+ public Method Setter
+ {
+ get { return this.setter; }
+ set { this.setter = value; }
+ }
+ private MethodList otherMethods;
+ /// <summary>Other methods associated with the property. No equivalent in C#.</summary>
+ public MethodList OtherMethods
+ {
+ get { return this.otherMethods; }
+ set { this.otherMethods = value; }
+ }
+ protected string fullName;
+ public override string/*!*/ FullName
+ {
+ get
+ {
+ if (this.fullName != null) return this.fullName;
+ StringBuilder sb = new StringBuilder();
+ sb.Append(this.DeclaringType.FullName);
+ sb.Append('.');
+ if (this.Name != null)
+ sb.Append(this.Name.ToString());
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ sb.Append(par.Type.FullName);
+ if (i == n - 1)
+ sb.Append(')');
+ }
+ return this.fullName = sb.ToString();
+ }
+ }
+#if !MinimalReader
+ public virtual Method GetBaseGetter()
+ {
+ TypeNode t = this.DeclaringType;
+ if (t == null) return null;
+ while (t.BaseType != null)
+ {
+ t = t.BaseType;
+ MemberList mems = t.GetMembersNamed(this.Name);
+ for (int i = 0, n = mems == null ? 0 : mems.Count; i < n; i++)
+ {
+ Property bprop = mems[i] as Property;
+ if (bprop == null) continue;
+ if (!bprop.ParametersMatch(this.Parameters)) continue;
+ if (bprop.Getter != null) return bprop.Getter;
+ }
+ }
+ return null;
+ }
+ public virtual Method GetBaseSetter()
+ {
+ TypeNode t = this.DeclaringType;
+ if (t == null) return null;
+ while (t.BaseType != null)
+ {
+ t = t.BaseType;
+ MemberList mems = t.GetMembersNamed(this.Name);
+ for (int i = 0, n = mems == null ? 0 : mems.Count; i < n; i++)
+ {
+ Property bprop = mems[i] as Property;
+ if (bprop == null) continue;
+ if (!bprop.ParametersMatch(this.Parameters)) continue;
+ if (bprop.Setter != null) return bprop.Setter;
+ }
+ }
+ return null;
+ }
+#endif
+#if !NoXml
+ protected override Identifier GetDocumentationId()
+ {
+ StringBuilder sb = new StringBuilder(this.DeclaringType.DocumentationId.ToString());
+ sb[0] = 'P';
+ sb.Append('.');
+ if (this.Name != null)
+ sb.Append(this.Name.ToString());
+ ParameterList parameters = this.Parameters;
+ for (int i = 0, n = parameters == null ? 0 : parameters.Count; i < n; i++)
+ {
+ Parameter par = parameters[i];
+ if (par == null || par.Type == null) continue;
+ if (i == 0)
+ sb.Append('(');
+ else
+ sb.Append(',');
+ par.Type.AppendDocumentIdMangledName(sb, null, this.DeclaringType.TemplateParameters);
+ if (i == n - 1)
+ sb.Append(')');
+ }
+ return Identifier.For(sb.ToString());
+ }
+#endif
+#if !NoReflection
+ public static Property GetProperty(System.Reflection.PropertyInfo propertyInfo)
+ {
+ if (propertyInfo == null) return null;
+ TypeNode tn = TypeNode.GetTypeNode(propertyInfo.DeclaringType);
+ if (tn == null) return null;
+ System.Reflection.ParameterInfo[] paramInfos = propertyInfo.GetIndexParameters();
+ int n = paramInfos == null ? 0 : paramInfos.Length;
+ TypeNode[] parameterTypes = new TypeNode[n];
+ if (paramInfos != null)
+ for (int i = 0; i < n; i++)
+ {
+ System.Reflection.ParameterInfo param = paramInfos[i];
+ if (param == null) return null;
+ parameterTypes[i] = TypeNode.GetTypeNode(param.ParameterType);
+ }
+ return tn.GetProperty(Identifier.For(propertyInfo.Name), parameterTypes);
+ }
+#endif
+
+#if !NoReflection
+ protected System.Reflection.PropertyInfo propertyInfo;
+ public virtual System.Reflection.PropertyInfo GetPropertyInfo()
+ {
+ if (this.propertyInfo == null)
+ {
+ if (this.DeclaringType == null) return null;
+ Type t = this.DeclaringType.GetRuntimeType();
+ if (t == null) return null;
+ if (this.Type == null) return null;
+ Type retType = this.Type.GetRuntimeType();
+ if (retType == null) return null;
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Type[] types = new Type[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null || p.Type == null) return null;
+ Type pt = types[i] = p.Type.GetRuntimeType();
+ if (pt == null) return null;
+ }
+ System.Reflection.MemberInfo[] members =
+ t.GetMember(this.Name.ToString(), System.Reflection.MemberTypes.Property,
+ BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+ foreach (System.Reflection.PropertyInfo prop in members)
+ {
+ if (prop == null || prop.PropertyType != retType) continue;
+ System.Reflection.ParameterInfo[] parameters = prop.GetIndexParameters();
+ if (parameters == null || parameters.Length != n) continue;
+ for (int i = 0; i < n; i++)
+ {
+ System.Reflection.ParameterInfo parInfo = parameters[i];
+ if (parInfo == null || parInfo.ParameterType != types[i]) goto tryNext;
+ }
+ return this.propertyInfo = prop;
+ tryNext: ;
+ }
+ }
+ return this.propertyInfo;
+ }
+ public virtual object GetValue(object targetObject, params object[] indices)
+ {
+ System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
+ if (propInfo == null) throw new InvalidOperationException();
+ return propInfo.GetValue(targetObject, indices);
+ }
+ public virtual Literal GetValue(Literal/*!*/ targetObject, params Literal[] indices)
+ {
+ int n = indices == null ? 0 : indices.Length;
+ object[] inds = n == 0 ? null : new object[n];
+ if (inds != null && indices != null)
+ for (int i = 0; i < n; i++)
+ {
+ Literal lit = indices[i];
+ inds[i] = lit == null ? null : lit.Value;
+ }
+ return new Literal(this.GetValue(targetObject.Value, inds));
+ }
+ public virtual void SetValue(object targetObject, object value, params object[] indices)
+ {
+ System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
+ if (propInfo == null) throw new InvalidOperationException();
+ propInfo.SetValue(targetObject, value, indices);
+ }
+ public virtual void SetValue(Literal/*!*/ targetObject, Literal/*!*/ value, params Literal[] indices)
+ {
+ int n = indices == null ? 0 : indices.Length;
+ object[] inds = n == 0 ? null : new object[n];
+ if (inds != null && indices != null)
+ for (int i = 0; i < n; i++)
+ {
+ Literal lit = indices[i];
+ inds[i] = lit == null ? null : lit.Value;
+ }
+ System.Reflection.PropertyInfo propInfo = this.GetPropertyInfo();
+ if (propInfo == null) throw new InvalidOperationException();
+ propInfo.SetValue(targetObject.Value, value.Value, inds);
+ }
+#endif
+#if !NoXml
+ public override string HelpText
+ {
+ get
+ {
+ if (this.helpText != null)
+ return this.helpText;
+ StringBuilder sb = new StringBuilder(base.HelpText);
+ // if there is already some help text, start the contract on a new line
+ bool startWithNewLine = (sb.Length != 0);
+ if (this.Getter != null && this.Getter.HelpText != null && this.Getter.HelpText.Length > 0)
+ {
+ if (startWithNewLine)
+ {
+ sb.Append("\n");
+ startWithNewLine = false;
+ }
+ sb.Append("get\n");
+ int i = sb.Length;
+ sb.Append(this.Getter.HelpText);
+ if (sb.Length > i)
+ startWithNewLine = true;
+ }
+ if (this.Setter != null && this.Setter.HelpText != null && this.Setter.HelpText.Length > 0)
+ {
+ if (startWithNewLine)
+ {
+ sb.Append("\n");
+ startWithNewLine = false;
+ }
+ sb.Append("set\n");
+ sb.Append(this.Setter.HelpText);
+ }
+ return this.helpText = sb.ToString();
+ }
+ set
+ {
+ base.HelpText = value;
+ }
+ }
+#endif
+ public override bool IsAssembly
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Assembly; }
+ }
+ public override bool IsCompilerControlled
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.CompilerControlled; }
+ }
+ public override bool IsFamily
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Family; }
+ }
+ public override bool IsFamilyAndAssembly
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.FamANDAssem; }
+ }
+ public override bool IsFamilyOrAssembly
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.FamORAssem; }
+ }
+ public bool IsFinal
+ {
+ get { return (this.Getter == null || this.Getter.IsFinal) && (this.Setter == null || this.Setter.IsFinal); }
+ }
+ public override bool IsPrivate
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Private; }
+ }
+ public override bool IsPublic
+ {
+ get { return Method.GetVisibilityUnion(this.Getter, this.Setter) == MethodFlags.Public; }
+ }
+ public override bool IsSpecialName
+ {
+ get { return (this.Flags & PropertyFlags.SpecialName) != 0; }
+ }
+ public override bool IsStatic
+ {
+ get { return (this.Getter == null || this.Getter.IsStatic) && (this.Setter == null || this.Setter.IsStatic); }
+ }
+ /// <summary>
+ /// True if this property can in principle be overridden by a property in a derived class.
+ /// </summary>
+ public bool IsVirtual
+ {
+ get { return (this.Getter == null || this.Getter.IsVirtual) && (this.Setter == null || this.Setter.IsVirtual); }
+ }
+ public override bool IsVisibleOutsideAssembly
+ {
+ get { return (this.Getter != null && this.Getter.IsVisibleOutsideAssembly) || (this.Setter != null && this.Setter.IsVisibleOutsideAssembly); }
+ }
+ public static readonly Property NotSpecified = new Property();
+ public override Member HiddenMember
+ {
+ get
+ {
+ return this.HiddenProperty;
+ }
+ set
+ {
+ this.HiddenProperty = (Property)value;
+ }
+ }
+ protected Property hiddenProperty;
+ public virtual Property HiddenProperty
+ {
+ get
+ {
+ if (this.hiddenMember == Property.NotSpecified) return null;
+ Property hiddenProperty = this.hiddenMember as Property;
+ if (hiddenProperty != null) return hiddenProperty;
+
+ Method hiddenGetter = this.Getter == null ? null : this.Getter.HiddenMethod;
+ Method hiddenSetter = this.Setter == null ? null : this.Setter.HiddenMethod;
+ Property hiddenGetterProperty = hiddenGetter == null ? null : hiddenGetter.DeclaringMember as Property;
+ Property hiddenSetterProperty = hiddenSetter == null ? null : hiddenSetter.DeclaringMember as Property;
+ hiddenProperty = hiddenGetterProperty;
+ if (hiddenSetterProperty != null)
+ {
+ if (hiddenProperty == null ||
+ (hiddenSetterProperty.DeclaringType != null && hiddenSetterProperty.DeclaringType.IsDerivedFrom(hiddenProperty.DeclaringType)))
+ hiddenProperty = hiddenSetterProperty;
+ }
+ this.hiddenMember = hiddenProperty;
+ return hiddenProperty;
+ }
+ set
+ {
+ this.hiddenMember = value;
+ }
+ }
+ public override Member OverriddenMember
+ {
+ get
+ {
+ return this.OverriddenProperty;
+ }
+ set
+ {
+ this.OverriddenProperty = (Property)value;
+ }
+ }
+ protected Property overriddenProperty;
+ public virtual Property OverriddenProperty
+ {
+ get
+ {
+ if (this.overriddenMember == Property.NotSpecified) return null;
+ Property overriddenProperty = this.overriddenMember as Property;
+ if (overriddenProperty != null) return overriddenProperty;
+
+ Method overriddenGetter = this.Getter == null ? null : this.Getter.OverriddenMethod;
+ Method overriddenSetter = this.Setter == null ? null : this.Setter.OverriddenMethod;
+ Property overriddenGetterProperty = overriddenGetter == null ? null : overriddenGetter.DeclaringMember as Property;
+ Property overriddenSetterProperty = overriddenSetter == null ? null : overriddenSetter.DeclaringMember as Property;
+ overriddenProperty = overriddenGetterProperty;
+ if (overriddenSetterProperty != null)
+ {
+ if (overriddenProperty == null ||
+ (overriddenSetterProperty.DeclaringType != null && overriddenSetterProperty.DeclaringType.IsDerivedFrom(overriddenProperty.DeclaringType)))
+ overriddenProperty = overriddenSetterProperty;
+ }
+ this.overriddenMember = overriddenProperty;
+ return overriddenProperty;
+ }
+ set
+ {
+ this.overriddenMember = value;
+ }
+ }
+ private ParameterList parameters;
+ /// <summary>
+ /// The parameters of this property if it is an indexer.
+ /// </summary>
+ public ParameterList Parameters
+ {
+ get
+ {
+ if (this.parameters != null) return this.parameters;
+ if (this.Getter != null) return this.parameters = this.Getter.Parameters;
+ ParameterList setterPars = this.Setter == null ? null : this.Setter.Parameters;
+ int n = setterPars == null ? 0 : setterPars.Count - 1;
+ ParameterList propPars = this.parameters = new ParameterList(n);
+ if (setterPars != null)
+ for (int i = 0; i < n; i++) propPars.Add(setterPars[i]);
+ return propPars;
+ }
+ set
+ {
+ this.parameters = value;
+ }
+ }
+ public virtual bool ParametersMatch(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1.Type != par2.Type) return false;
+ }
+ return true;
+ }
+ public virtual bool ParametersMatchStructurally(ParameterList parameters)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = parameters == null ? 0 : parameters.Count;
+ if (n != m) return false;
+ if (parameters == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par1 = pars[i];
+ Parameter par2 = parameters[i];
+ if (par1 == null || par2 == null) return false;
+ if (par1.Type == null || par2.Type == null) return false;
+ if (par1.Type != par2.Type && !par1.Type.IsStructurallyEquivalentTo(par2.Type)) return false;
+ }
+ return true;
+ }
+ public virtual bool ParameterTypesMatch(TypeNodeList argumentTypes)
+ {
+ ParameterList pars = this.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ int m = argumentTypes == null ? 0 : argumentTypes.Count;
+ if (n != m) return false;
+ if (argumentTypes == null) return true;
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = this.Parameters[i];
+ if (par == null) return false;
+ TypeNode argType = argumentTypes[i];
+ if (par.Type != argType) return false;
+ }
+ return true;
+ }
+ protected TypeNode type;
+ /// <summary>
+ /// The type of value that this property holds.
+ /// </summary>
+ public virtual TypeNode Type
+ {
+ get
+ {
+ if (this.type != null) return this.type;
+ if (this.Getter != null) return this.type = this.Getter.ReturnType;
+ if (this.Setter != null && this.Setter.Parameters != null)
+ return this.type = this.Setter.Parameters[this.Setter.Parameters.Count - 1].Type;
+ return CoreSystemTypes.Object;
+ }
+ set
+ {
+ this.type = value;
+ }
+ }
+#if !MinimalReader
+ public TypeNode TypeExpression;
+#endif
+ public override string ToString()
+ {
+ return this.DeclaringType.GetFullUnmangledNameWithTypeParameters() + "." + this.Name;
+ }
+#if FxCop
+ internal override void GetName(MemberFormat options, StringBuilder name)
+ {
+ base.GetName(options, name);
+ ParameterCollection parameters = this.parameters.Count > 0 ? this.parameters : null;
+ // AppendParametersAndReturnType will not emit the paramters
+ // prefix and suffix if a null ParameterCollection is provided to it.
+ // This prevents a parameterless property from being rendered as MyProperty[]
+ Method.AppendParametersAndReturnType(options, parameters, '[', ']', this.Type, name);
+ }
+#endif
+ }
+ public class Variable : Expression
+ {
+ private Identifier name;
+#if !MinimalReader
+ public TypeNode TypeExpression;
+#endif
+ public Variable(NodeType type)
+ : base(type)
+ {
+ }
+ /// <summary>The name of a stack location. For example the name of a local variable or the name of a method parameter.</summary>
+ public Identifier Name
+ {
+ get { return this.name; }
+ set { this.name = value; }
+ }
+ }
+ public class Parameter : Variable
+ {
+ private AttributeList attributes;
+ /// <summary>The (C# custom) attributes of this parameter.</summary>
+ public AttributeList Attributes
+ {
+ get
+ {
+ if (this.attributes != null) return this.attributes;
+ return this.attributes = new AttributeList();
+ }
+ set { this.attributes = value; }
+ }
+ private Expression defaultValue;
+ /// <summary>The value that should be supplied as the argument value of this optional parameter if the source code omits an explicit argument value.</summary>
+ public Expression DefaultValue
+ {
+ get { return this.defaultValue; }
+ set { this.defaultValue = value; }
+ }
+ private ParameterFlags flags;
+ public ParameterFlags Flags
+ {
+ get { return this.flags; }
+ set { this.flags = value; }
+ }
+ private MarshallingInformation marshallingInformation;
+ public MarshallingInformation MarshallingInformation
+ {
+ get { return this.marshallingInformation; }
+ set { this.marshallingInformation = value; }
+ }
+ private Method declaringMethod;
+ public Method DeclaringMethod
+ {
+ get { return this.declaringMethod; }
+ set { this.declaringMethod = value; }
+ }
+ private int parameterListIndex;
+ /// <summary>
+ /// Zero based index into a parameter list containing this parameter.
+ /// </summary>
+ public int ParameterListIndex
+ {
+ get { return this.parameterListIndex; }
+ set { this.parameterListIndex = value; }
+ }
+ private int argumentListIndex;
+ /// <summary>
+ /// Zero based index into the list of arguments on the evaluation stack.
+ /// Instance methods have the this object as parameter zero, which means that the first parameter will have value 1, not 0.
+ /// </summary>
+ public int ArgumentListIndex
+ {
+ get { return this.argumentListIndex; }
+ set { this.argumentListIndex = value; }
+ }
+ public Parameter()
+ : base(NodeType.Parameter)
+ {
+ }
+ public Parameter(Identifier name, TypeNode type)
+ : base(NodeType.Parameter)
+ {
+ this.Name = name;
+ this.Type = type;
+ }
+#if !MinimalReader
+ public Parameter(AttributeList attributes, ParameterFlags flags, Identifier name, TypeNode type,
+ Literal defaultValue, MarshallingInformation marshallingInformation)
+ : base(NodeType.Parameter)
+ {
+ this.attributes = attributes;
+ this.defaultValue = defaultValue;
+ this.flags = flags;
+ this.marshallingInformation = marshallingInformation;
+ this.Name = name;
+ this.Type = type;
+ }
+#endif
+ /// <summary>
+ /// True if the corresponding argument value is used by the callee. (This need not be the case for a parameter marked as IsOut.)
+ /// </summary>
+ public virtual bool IsIn
+ {
+ get
+ {
+ return (this.Flags & ParameterFlags.In) != 0;
+ }
+ set
+ {
+ if (value)
+ this.Flags |= ParameterFlags.In;
+ else
+ this.Flags &= ~ParameterFlags.In;
+ }
+ }
+ /// <summary>
+ /// True if the caller can omit providing an argument for this parameter.
+ /// </summary>
+ public virtual bool IsOptional
+ {
+ get
+ {
+ return (this.Flags & ParameterFlags.Optional) != 0;
+ }
+ set
+ {
+ if (value)
+ this.Flags |= ParameterFlags.Optional;
+ else
+ this.Flags &= ~ParameterFlags.Optional;
+ }
+ }
+ /// <summary>
+ /// True if the corresponding argument must be a left hand expression and will be updated when the call returns.
+ /// </summary>
+ public virtual bool IsOut
+ {
+ get
+ {
+ return (this.Flags & ParameterFlags.Out) != 0;
+ }
+ set
+ {
+ if (value)
+ this.Flags |= ParameterFlags.Out;
+ else
+ this.Flags &= ~ParameterFlags.Out;
+ }
+ }
+#if !MinimalReader
+ protected TypeNode paramArrayElementType = null;
+ /// <summary>
+ /// If the parameter is a param array, this returns the element type of the array. If not, it returns null.
+ /// </summary>
+ public virtual TypeNode GetParamArrayElementType()
+ {
+ TypeNode result = this.paramArrayElementType;
+ if (result == null)
+ {
+ AttributeNode attr = this.GetParamArrayAttribute();
+ if (attr != null)
+ {
+ TypeNode t = TypeNode.StripModifiers(this.Type);
+ Reference r = t as Reference;
+ if (r != null) t = r.ElementType;
+ ArrayType arr = t as ArrayType;
+ if (arr != null && arr.Rank == 1)
+ return this.paramArrayElementType = arr.ElementType;
+ }
+ this.paramArrayElementType = result = Class.DoesNotExist;
+ }
+ if (result == Class.DoesNotExist) return null;
+ return result;
+ }
+ protected AttributeNode paramArrayAttribute = null;
+ public virtual AttributeNode GetParamArrayAttribute()
+ {
+ AttributeNode result = this.paramArrayAttribute;
+ if (result == null)
+ {
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ TypeNode attrType = null;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ attrType = mb.BoundMember.DeclaringType;
+ else
+ {
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ attrType = lit.Value as TypeNode;
+ }
+ if (attrType == SystemTypes.ParamArrayAttribute)
+ return this.paramArrayAttribute = attr;
+ }
+ result = this.paramArrayAttribute = AttributeNode.DoesNotExist;
+ }
+ if (result == AttributeNode.DoesNotExist) return null;
+ return result;
+ }
+ public override bool Equals(object obj)
+ {
+ ParameterBinding binding = obj as ParameterBinding;
+ return obj == this || binding != null && binding.BoundParameter == this;
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ /// <summary>
+ /// Gets the first attribute of the given type in the attribute list of this parameter. Returns null if none found.
+ /// This should not be called until the AST containing this member has been processed to replace symbolic references
+ /// to members with references to the actual members.
+ /// </summary>
+ public virtual AttributeNode GetAttribute(TypeNode attributeType)
+ {
+ if (attributeType == null) return null;
+ AttributeList attributes = this.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb != null)
+ {
+ if (mb.BoundMember == null) continue;
+ if (mb.BoundMember.DeclaringType != attributeType) continue;
+ return attr;
+ }
+ Literal lit = attr.Constructor as Literal;
+ if (lit == null) continue;
+ if ((lit.Value as TypeNode) != attributeType) continue;
+ return attr;
+ }
+ return null;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual bool IsUniversallyDelayed {
+ get {
+ // Special handling of delegate constructors. Their first argument is delayed.
+ if (this.DeclaringMethod != null && this.DeclaringMethod.DeclaringType is DelegateNode) {
+ if (this.DeclaringMethod.Parameters[0] == this) { // first parameter (not including this)
+ return true;
+ }
+ }
+ return (this.GetAttribute(ExtendedRuntimeTypes.DelayedAttribute) != null);
+ }
+ }
+#endif
+ public override string ToString()
+ {
+ if (this.Name == null) return "";
+ if (this.Type == null) return this.Name.ToString();
+ return this.Type.ToString() + " " + this.Name.ToString();
+ }
+ }
+#if !MinimalReader
+ public class ParameterBinding : Parameter, IUniqueKey
+ {
+ public Parameter/*!*/ BoundParameter;
+
+ public ParameterBinding(Parameter/*!*/ boundParameter, SourceContext sctx)
+ {
+ if (boundParameter == null) throw new ArgumentNullException("boundParameter");
+ this.BoundParameter = boundParameter;
+ this.SourceContext = sctx;
+ this.Type = boundParameter.Type;
+ this.Name = boundParameter.Name;
+ this.TypeExpression = boundParameter.TypeExpression;
+ this.Attributes = boundParameter.Attributes;
+ this.DefaultValue = boundParameter.DefaultValue;
+ this.Flags = boundParameter.Flags;
+ this.MarshallingInformation = boundParameter.MarshallingInformation;
+ this.DeclaringMethod = boundParameter.DeclaringMethod;
+ this.ParameterListIndex = boundParameter.ParameterListIndex;
+ this.ArgumentListIndex = boundParameter.ArgumentListIndex;
+ //^ base();
+ }
+ public override int GetHashCode()
+ {
+ return this.BoundParameter.GetHashCode();
+ }
+ public override bool Equals(object obj)
+ {
+ ParameterBinding pb = obj as ParameterBinding;
+ if (pb != null)
+ return this.BoundParameter.Equals(pb.BoundParameter);
+ else
+ return this.BoundParameter.Equals(obj);
+ }
+ int IUniqueKey.UniqueId
+ {
+ get { return this.BoundParameter.UniqueKey; }
+ }
+ }
+#endif
+ public class Local : Variable
+ {
+#if !MinimalReader
+ public Block DeclaringBlock;
+ public bool InitOnly;
+ public int Index;
+#endif
+ public Local()
+ : base(NodeType.Local)
+ {
+ }
+ public Local(TypeNode type)
+ : base(NodeType.Local)
+ {
+ this.Name = Identifier.Empty;
+ if (type == null) type = CoreSystemTypes.Object;
+ this.Type = type;
+ }
+ public Local(Identifier name, TypeNode type)
+ : this(type)
+ {
+ this.Name = name;
+ }
+#if !MinimalReader
+ public Local(TypeNode type, SourceContext context)
+ : this(Identifier.Empty, type, null)
+ {
+ this.SourceContext = context;
+ }
+ public Local(Identifier name, TypeNode type, SourceContext context)
+ : this(name, type, null)
+ {
+ this.SourceContext = context;
+ }
+ public Local(Identifier name, TypeNode type, Block declaringBlock)
+ : base(NodeType.Local)
+ {
+ this.DeclaringBlock = declaringBlock;
+ this.Name = name;
+ if (type == null) type = CoreSystemTypes.Object;
+ this.Type = type;
+ }
+#endif
+ private bool pinned;
+ public bool Pinned
+ {
+ get { return this.pinned; }
+ set { this.pinned = value; }
+ }
+#if !MinimalReader
+ public override bool Equals(object obj)
+ {
+ LocalBinding binding = obj as LocalBinding;
+ return obj == this || binding != null && binding.BoundLocal == this;
+ }
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ public override string ToString()
+ {
+ if (this.Name == null) return "No name";
+ return this.Name.ToString();
+ }
+#endif
+
+ }
+#if !MinimalReader
+ public class LocalBinding : Local, IUniqueKey
+ {
+ public Local/*!*/ BoundLocal;
+
+ public LocalBinding(Local/*!*/ boundLocal, SourceContext sctx)
+ {
+ if (boundLocal == null) throw new ArgumentNullException("boundLocal");
+ this.BoundLocal = boundLocal;
+ //^ base();
+ this.SourceContext = sctx;
+ this.Type = boundLocal.Type;
+ this.Name = boundLocal.Name;
+ this.TypeExpression = boundLocal.TypeExpression;
+ this.DeclaringBlock = boundLocal.DeclaringBlock;
+ this.Pinned = boundLocal.Pinned;
+ this.InitOnly = boundLocal.InitOnly;
+ this.Index = boundLocal.Index;
+ }
+ public override int GetHashCode()
+ {
+ return this.BoundLocal.GetHashCode();
+ }
+ public override bool Equals(object obj)
+ {
+ LocalBinding lb = obj as LocalBinding;
+ if (lb != null)
+ return this.BoundLocal.Equals(lb.BoundLocal);
+ else
+ return this.BoundLocal.Equals(obj);
+ }
+ int IUniqueKey.UniqueId
+ {
+ get { return this.BoundLocal.UniqueKey; }
+ }
+ }
+#endif
+ /// <summary>
+ /// A named container of types and nested namespaces.
+ /// The name of the container implicitly qualifies the names of the contained types and namespaces.
+ /// </summary>
+ public class Namespace : Member
+ {
+ /// <summary>The FullName of the namespace in the form of an Identifier rather than in the form of a string.</summary>
+ public Identifier FullNameId;
+#if !MinimalReader
+ /// <summary>
+ /// Provides alternative names for types and nested namespaces. Useful for introducing shorter names or for resolving name clashes.
+ /// The names should be added to the scope associated with this namespace.
+ /// </summary>
+ public AliasDefinitionList AliasDefinitions;
+ /// <summary>
+ /// The list of namespaces that are fully contained inside this namespace.
+ /// </summary>
+ public NamespaceList NestedNamespaces;
+ /// <summary>
+ /// The Universal Resource Identifier that should be associated with all declarations inside this namespace.
+ /// Typically used when the types inside the namespace are serialized as an XML Schema Definition. (XSD)
+ /// </summary>
+ public Identifier URI;
+ /// <summary>
+ /// The list of the namespaces of types that should be imported into the scope associated with this namespace.
+ /// </summary>
+ public UsedNamespaceList UsedNamespaces;
+#endif
+ /// <summary>
+ /// A delegate that is called the first time Types is accessed. Provides for incremental construction of the namespace node.
+ /// </summary>
+ public TypeProvider ProvideTypes;
+ /// <summary>
+ /// Opaque information passed as a parameter to the delegate in ProvideTypes. Typically used to associate this namespace
+ /// instance with a helper object.
+ /// </summary>
+ public object ProviderHandle;
+ /// <summary>
+ /// A method that fills in the Types property of the given namespace. Must not leave Types null.
+ /// </summary>
+ public delegate void TypeProvider(Namespace @namespace, object handle);
+
+ protected string fullName;
+ protected TypeNodeList types;
+
+ public Namespace()
+ : base(NodeType.Namespace)
+ {
+ }
+ public Namespace(Identifier name)
+ : base(NodeType.Namespace)
+ {
+ this.Name = name;
+ this.FullNameId = name;
+ if (name != null)
+ this.fullName = name.ToString();
+ }
+#if !MinimalReader
+ public Namespace(Identifier name, TypeProvider provideTypes, object providerHandle)
+ : base(NodeType.Namespace)
+ {
+ this.Name = name;
+ this.FullNameId = name;
+ if (name != null)
+ this.fullName = name.ToString();
+ this.ProvideTypes = provideTypes;
+ this.ProviderHandle = providerHandle;
+ }
+ public Namespace(Identifier name, Identifier fullName, AliasDefinitionList aliasDefinitions, UsedNamespaceList usedNamespaces,
+ NamespaceList nestedNamespaces, TypeNodeList types)
+ : base(NodeType.Namespace)
+ {
+ this.Name = name;
+ this.FullNameId = fullName;
+ if (fullName != null)
+ this.fullName = fullName.ToString();
+ this.AliasDefinitions = aliasDefinitions;
+ this.NestedNamespaces = nestedNamespaces;
+ this.Types = types;
+ this.UsedNamespaces = usedNamespaces;
+ }
+#endif
+ public override string/*!*/ FullName
+ {
+ get { return this.fullName == null ? "" : this.fullName; }
+ }
+ public override bool IsAssembly { get { return false; } }
+ public override bool IsCompilerControlled { get { return false; } }
+ public override bool IsFamily { get { return false; } }
+ public override bool IsFamilyAndAssembly { get { return false; } }
+ public override bool IsFamilyOrAssembly { get { return false; } }
+ public override bool IsPrivate { get { return !this.IsPublic; } }
+ public override bool IsPublic { get { return this.isPublic; } }
+ protected internal bool isPublic;
+ public override bool IsSpecialName { get { return false; } }
+ public override bool IsStatic { get { return false; } }
+ public override bool IsVisibleOutsideAssembly { get { return false; } }
+ /// <summary>
+ /// The list of types contained inside this namespace. If the value of Types is null and the value of ProvideTypes is not null, the
+ /// TypeProvider delegate is called to fill in the value of this property.
+ /// </summary>
+ public TypeNodeList Types
+ {
+ get
+ {
+ if (this.types == null)
+ if (this.ProvideTypes != null)
+ lock (this)
+ {
+ if (this.types == null)
+ {
+ this.ProvideTypes(this, this.ProviderHandle);
+ }
+ }
+ else
+ this.types = new TypeNodeList();
+ return this.types;
+ }
+ set
+ {
+ this.types = value;
+ }
+ }
+ }
+#if !MinimalReader
+ /// <summary>
+ /// The root node of an Abstract Syntax Tree. Typically corresponds to multiple source files compiled to form a single target.
+ /// </summary>
+ public class Compilation : Node
+ {
+ /// <summary>
+ /// The compilation parameters that are used for this compilation.
+ /// </summary>
+ public System.CodeDom.Compiler.CompilerParameters CompilerParameters;
+ /// <summary>
+ /// The target code object that is produced as a result of this compilation.
+ /// </summary>
+ public Module TargetModule;
+ /// <summary>
+ /// A list of all the compilation units (typically source files) that make up this compilation.
+ /// </summary>
+ public CompilationUnitList CompilationUnits;
+ /// <summary>
+ /// A scope for symbols that belong to the compilation as a whole. No C# equivalent. Null if not applicable.
+ /// </summary>
+ public Scope GlobalScope;
+ /// <summary>
+ /// A list of compilations that produce assemblies and modules that are referenced by this compilation and hence need to be
+ /// compiled before this Compilation is compiled. This list is not intended to include already compiled framework assemblies
+ /// such as system.dll.
+ /// </summary>
+ public CompilationList ReferencedCompilations;
+ public DateTime LastModified = DateTime.Now;
+ public DateTime LastCompiled = DateTime.MinValue;
+
+ public Compilation()
+ : base(NodeType.Compilation)
+ {
+ }
+ public Compilation(Module targetModule, CompilationUnitList compilationUnits, System.CodeDom.Compiler.CompilerParameters compilerParameters, Scope globalScope)
+ : base(NodeType.Compilation)
+ {
+ this.CompilationUnits = compilationUnits;
+ this.TargetModule = targetModule;
+ this.CompilerParameters = compilerParameters;
+ this.GlobalScope = globalScope;
+ }
+ public virtual Compilation CloneCompilationUnits()
+ {
+ Compilation clone = (Compilation)base.Clone();
+ CompilationUnitList cus = this.CompilationUnits;
+ if (cus != null)
+ {
+ clone.CompilationUnits = cus = cus.Clone();
+ for (int i = 0, n = cus.Count; i < n; i++)
+ {
+ CompilationUnit cu = cus[i];
+ if (cu == null) continue;
+ cus[i] = cu = (CompilationUnit)cu.Clone();
+ cu.Compilation = clone;
+ cu.Nodes = null;
+ }
+ }
+ return clone;
+ }
+ }
+ /// <summary>
+ /// The root node of an Abstract Syntax Tree. Corresponds to the starting production of the syntax. Equivalent to C# compilation-unit.
+ /// Typically a compilation unit corresponds to a single source file.
+ /// </summary>
+ public class CompilationUnit : Node
+ {
+ /// <summary>
+ /// An identifier that can be used to retrieve the source text of the compilation unit.
+ /// </summary>
+ public Identifier Name;
+ /// <summary>
+ /// An anonymous (name is Identifier.Empty) namespace holding types and nested namespaces.
+ /// </summary>
+ public NodeList Nodes;
+ /// <summary>
+ /// The preprocessor symbols that are to treated as defined when compiling this CompilationUnit into the TargetModule.
+ /// </summary>
+ public Hashtable PreprocessorDefinedSymbols;
+ /// <summary>
+ /// Pragma warning information.
+ /// </summary>
+ public TrivialHashtable PragmaWarnInformation;
+ /// <summary>
+ /// The compilation of which this unit forms a part.
+ /// </summary>
+ public Compilation Compilation;
+
+ public CompilationUnit()
+ : base(NodeType.CompilationUnit)
+ {
+ }
+ public CompilationUnit(Identifier name)
+ : base(NodeType.CompilationUnit)
+ {
+ this.Name = name;
+ }
+ }
+ public class CompilationUnitSnippet : CompilationUnit
+ {
+ public DateTime LastModified = DateTime.Now;
+ public IParserFactory ParserFactory;
+ public Method ChangedMethod;
+ public int OriginalEndPosOfChangedMethod;
+
+ public CompilationUnitSnippet()
+ {
+ this.NodeType = NodeType.CompilationUnitSnippet;
+ }
+ public CompilationUnitSnippet(Identifier name, IParserFactory parserFactory, SourceContext sctx)
+ {
+ this.NodeType = NodeType.CompilationUnitSnippet;
+ this.Name = name;
+ this.ParserFactory = parserFactory;
+ this.SourceContext = sctx;
+ }
+ }
+ public abstract class Composer
+ {
+ public abstract Node Compose(Node node, Composer context, bool hasContextReference, Class scope);
+ private class NullComposer : Composer
+ {
+ public override Node Compose(Node node, Composer context, bool hasContextReference, Class scope)
+ {
+ return node;
+ }
+ }
+ public static readonly Composer Null = new NullComposer();
+ }
+ public class Composition : Expression
+ {
+ public Expression Expression;
+ public Composer Composer;
+ public Class Scope;
+ public Composition(Expression exp, Composer composer, Class scope)
+ : base(NodeType.Composition)
+ {
+ this.Expression = exp;
+ this.Composer = composer;
+ this.Scope = scope;
+ if (exp != null) this.Type = exp.Type;
+ }
+ }
+#endif
+#if ExtendedRuntime
+ // query nodes
+ public class QueryAlias: QueryExpression{
+ public Identifier Name;
+ public Expression Expression;
+ public QueryAlias(): base(NodeType.QueryAlias){
+ }
+ }
+ public abstract class Accessor{
+ }
+ public class MemberAccessor: Accessor{
+ public Member Member;
+ public TypeNode Type;
+ public bool Yield;
+ public Accessor Next;
+ public MemberAccessor(Member member){
+ this.Member = member;
+ }
+ }
+ public class SequenceAccessor: Accessor{
+ public ArrayList Accessors; // member accessors only
+ public SequenceAccessor(){
+ this.Accessors = new ArrayList();
+ }
+ }
+ public class SwitchAccessor: Accessor{
+ public TypeUnion Type;
+ public Hashtable Accessors; // key == type
+ public SwitchAccessor(){
+ this.Accessors = new Hashtable();
+ }
+ }
+ public enum Cardinality{
+ None, // reference type
+ One, // !
+ ZeroOrOne, // ?
+ OneOrMore, // +
+ ZeroOrMore // *
+ }
+ public class QueryAxis: QueryExpression{
+ public Expression Source;
+ public bool IsDescendant;
+ public Identifier Name;
+ public Identifier Namespace;
+ public TypeNode TypeTest;
+ public Accessor AccessPlan;
+ public Cardinality Cardinality;
+ public int YieldCount;
+ public TypeNodeList YieldTypes;
+ public bool IsCyclic;
+ public bool IsIterative;
+ public QueryAxis (Expression source, bool isDescendant, Identifier name, TypeNode typeTest)
+ : base(NodeType.QueryAxis){
+ this.Source = source;
+ this.IsDescendant = isDescendant;
+ this.Name = name;
+ this.TypeTest = typeTest;
+ }
+ }
+ public class QueryAggregate: QueryExpression{
+ public Identifier Name;
+ public TypeNode AggregateType;
+ public Expression Expression;
+ public ContextScope Context;
+ public QueryGroupBy Group;
+ public QueryAggregate(): base(NodeType.QueryAggregate){
+ }
+ }
+ public class ContextScope{
+ public ContextScope Previous;
+ public TypeNode Type;
+ public Expression Target;
+ public Expression Position;
+ public Block PreFilter;
+ public Block PostFilter;
+ public ContextScope(ContextScope previous, TypeNode type){
+ this.Previous = previous;
+ this.Type = type;
+ }
+ }
+ public class QueryContext: QueryExpression{
+ public ContextScope Scope;
+ public QueryContext()
+ : base(NodeType.QueryContext){
+ }
+ public QueryContext(ContextScope scope): base(NodeType.QueryContext){
+ this.Scope = scope;
+ if (scope != null) this.Type = scope.Type;
+ }
+ }
+ public class QueryDelete: QueryExpression{
+ public Expression Source;
+ public Expression Target;
+ public ContextScope Context;
+ public Expression SourceEnumerable;
+ public QueryDelete(): base(NodeType.QueryDelete){
+ }
+ }
+ public class QueryDistinct: QueryExpression{
+ public Expression Source;
+ public ContextScope Context;
+ public QueryGroupBy Group;
+ public Expression GroupTarget;
+ public QueryDistinct(): base(NodeType.QueryDistinct){
+ }
+ }
+ public class QueryDifference: QueryExpression{
+ public Expression LeftSource;
+ public Expression RightSource;
+ public QueryDifference() : base(NodeType.QueryDifference){
+ }
+ }
+ public class QueryExists: QueryExpression{
+ public Expression Source;
+ public QueryExists() : base(NodeType.QueryExists){
+ }
+ }
+ public abstract class QueryExpression: Expression{
+ protected QueryExpression(NodeType nt): base(nt){
+ }
+ }
+ public class QueryFilter: QueryExpression{
+ public Expression Source;
+ public Expression Expression;
+ public ContextScope Context;
+ public QueryFilter(): base(NodeType.QueryFilter){
+ }
+ public QueryFilter (Expression source, Expression filter): this(){
+ this.Source = source;
+ this.Expression = filter;
+ }
+ }
+ public class QueryYielder: Statement{
+ public Expression Source;
+ public Expression Target;
+ public Expression State;
+ public Block Body;
+ public QueryYielder(): base(NodeType.QueryYielder){
+ }
+ }
+ public class QueryGeneratedType: Statement{
+ public TypeNode Type;
+ public QueryGeneratedType(TypeNode type): base(NodeType.QueryGeneratedType){
+ this.Type = type;
+ }
+ }
+ public class QueryGroupBy: QueryExpression{
+ public Expression Source;
+ public ContextScope GroupContext;
+ public ExpressionList GroupList;
+ public ExpressionList AggregateList;
+ public Expression Having;
+ public ContextScope HavingContext;
+ public QueryGroupBy(): base(NodeType.QueryGroupBy){
+ this.GroupList = new ExpressionList();
+ this.AggregateList = new ExpressionList();
+ }
+ }
+ public class QueryInsert: QueryExpression{
+ public Expression Location;
+ public QueryInsertPosition Position;
+ public ExpressionList InsertList;
+ public ExpressionList HintList;
+ public ContextScope Context;
+ public bool IsBracket;
+ public QueryInsert(): base(NodeType.QueryInsert){
+ this.InsertList = new ExpressionList();
+ this.HintList = new ExpressionList();
+ }
+ }
+ public enum QueryInsertPosition{
+ After,
+ At,
+ Before,
+ First,
+ In,
+ Last
+ }
+ public class QueryIntersection: QueryExpression{
+ public Expression LeftSource;
+ public Expression RightSource;
+ public QueryIntersection(): base(NodeType.QueryIntersection){
+ }
+ }
+ public class QueryScope: BlockScope{
+ public QueryScope(Scope/*!*/ parentScope)
+ : base(parentScope, null) {
+ }
+ }
+ public class QueryIterator: QueryAlias{
+ public TypeNode ElementType;
+ public TypeNode TypeExpression;
+ public ExpressionList HintList;
+ public QueryIterator(): base(){
+ this.NodeType = NodeType.QueryIterator;
+ this.HintList = new ExpressionList();
+ }
+ }
+ public class QueryJoin: QueryExpression{
+ public Expression LeftOperand;
+ public Expression RightOperand;
+ public QueryJoinType JoinType;
+ public Expression JoinExpression;
+ public ContextScope JoinContext;
+ public QueryJoin(): base(NodeType.QueryJoin){
+ }
+ }
+ public enum QueryJoinType{
+ Inner,
+ LeftOuter,
+ RightOuter,
+ FullOuter
+ }
+ public class QueryLimit: QueryExpression{
+ public Expression Source;
+ public Expression Expression;
+ public bool IsPercent;
+ public bool IsWithTies;
+ public QueryLimit(): base(NodeType.QueryLimit){
+ }
+ }
+ public class QueryOrderBy: QueryExpression{
+ public Expression Source;
+ public ContextScope Context;
+ public ExpressionList OrderList;
+ public QueryOrderBy(): base(NodeType.QueryOrderBy){
+ this.OrderList = new ExpressionList();
+ }
+ }
+ public enum QueryOrderType{
+ Ascending,
+ Descending,
+ Document
+ }
+ public class QueryOrderItem: QueryExpression{
+ public Expression Expression;
+ public QueryOrderType OrderType = QueryOrderType.Ascending;
+ public QueryOrderItem(): base(NodeType.QueryOrderItem){
+ }
+ }
+ public class QueryPosition: QueryExpression{
+ public ContextScope Context;
+ public QueryPosition(ContextScope context): base(NodeType.QueryPosition){
+ this.Context = context;
+ this.Type = CoreSystemTypes.Int32;
+ }
+ public static readonly Identifier Id = Identifier.For("position");
+ }
+ public class QueryProject: QueryExpression{
+ public Expression Source;
+ public ContextScope Context;
+ public ExpressionList ProjectionList;
+ public TypeNode ProjectedType;
+ public MemberList Members;
+ public QueryProject(): base(NodeType.QueryProject){
+ this.ProjectionList = new ExpressionList();
+ }
+ }
+ public class QueryQuantifiedExpression: QueryExpression{
+ public QueryQuantifier Left;
+ public QueryQuantifier Right;
+ public Expression Expression;
+ public QueryQuantifiedExpression(): base(NodeType.QueryQuantifiedExpression){
+ }
+ }
+ public class QueryQuantifier: QueryExpression{
+ public Expression Expression;
+ public Expression Target;
+ public QueryQuantifier(NodeType nt): base(nt){
+ }
+ }
+ public class QuerySingleton: QueryExpression{
+ public Expression Source;
+ public QuerySingleton(): base(NodeType.QuerySingleton){
+ }
+ }
+ public class QuerySelect: QueryExpression{
+ public Expression Source;
+ public QueryCursorDirection Direction;
+ public QueryCursorAccess Access;
+ public QuerySelect(Expression source): base(NodeType.QuerySelect){
+ if (source != null){
+ this.Source = source;
+ this.Type = source.Type;
+ }
+ }
+ }
+ public enum QueryCursorDirection{
+ ForwardOnly,
+ Scrollable
+ }
+ public enum QueryCursorAccess{
+ ReadOnly,
+ Updatable
+ }
+
+ public abstract class QueryStatement: Statement{
+ protected QueryStatement(NodeType nt): base(nt){
+ }
+ }
+ public class QueryTypeFilter: QueryExpression{
+ public Expression Source;
+ public TypeNode Constraint;
+ public QueryTypeFilter(): base(NodeType.QueryTypeFilter){
+ }
+ }
+ public class QueryUnion: QueryExpression{
+ public Expression LeftSource;
+ public Expression RightSource;
+ public QueryUnion() : base(NodeType.QueryUnion){
+ }
+ }
+ public class QueryUpdate: QueryExpression{
+ public Expression Source;
+ public ExpressionList UpdateList;
+ public ContextScope Context;
+ public QueryUpdate() : base(NodeType.QueryUpdate){
+ this.UpdateList = new ExpressionList();
+ }
+ }
+ public class QueryTransact: Statement{
+ public Expression Source;
+ public Expression Isolation;
+ public Block Body;
+ public Block CommitBody;
+ public Block RollbackBody;
+ public Expression Transaction;
+ public QueryTransact(): base(NodeType.QueryTransact){
+ }
+ }
+ public class QueryCommit: Statement{
+ public QueryCommit(): base(NodeType.QueryCommit){
+ }
+ }
+ public class QueryRollback: Statement{
+ public QueryRollback(): base(NodeType.QueryRollback){
+ }
+ }
+#endif
+#if !MinimalReader
+ /// <summary>
+ /// An object that knows how to produce a particular scope's view of a type.
+ /// </summary>
+ public class TypeViewer
+ {
+ /// <summary>
+ /// Return a scope's view of the argument type, where the scope's view is represented
+ /// by a type viewer.
+ /// [The identity function, except for dialects (e.g. Extensible Sing#) that allow
+ /// extensions and differing views of types].
+ /// Defined as a static method to allow the type viewer to be null,
+ /// meaning an identity-function view.
+ /// </summary>
+ public static TypeNode/*!*/ GetTypeView(TypeViewer typeViewer, TypeNode/*!*/ type)
+ {
+ return typeViewer == null ? type.EffectiveTypeNode : typeViewer.GetTypeView(type);
+ }
+
+ /// <summary>
+ /// Return the typeViewer's view of the argument type. Overridden by subclasses
+ /// that support non-identity-function type viewers, e.g. Extensible Sing#.
+ /// </summary>
+ protected virtual TypeNode/*!*/ GetTypeView(TypeNode/*!*/ type)
+ {
+ return type.EffectiveTypeNode;
+ }
+ }
+#endif
+#if WHIDBEY
+ static
+#endif
+ class PlatformHelpers
+ {
+ internal static bool TryParseInt32(String s, out Int32 result)
+ {
+#if WHIDBEY
+ return Int32.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result);
+#else
+ result = 0;
+ bool succeeded = false;
+ try {
+ result = Int32.Parse(s, NumberFormatInfo.InvariantInfo);
+ succeeded = true;
+ }catch(ArgumentException){
+ }catch(FormatException){
+ }catch(OverflowException){}
+ return succeeded;
+#endif
+ }
+ internal static int StringCompareOrdinalIgnoreCase(string strA, int indexA, string strB, int indexB, int length)
+ {
+#if WHIDBEY
+ return string.Compare(strA, indexA, strB, indexB, length, StringComparison.OrdinalIgnoreCase);
+#else
+ return string.Compare(strA, indexA, strB, indexB, length, true, CultureInfo.InvariantCulture);
+#endif
+ }
+ internal static int StringCompareOrdinalIgnoreCase(string strA, string strB)
+ {
+#if WHIDBEY
+ return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase);
+#else
+ return string.Compare(strA, strB, true, CultureInfo.InvariantCulture);
+#endif
+ }
+ }
+#if FxCop
+ public class CatchNode : Statement{
+ private Block block;
+ private TypeNode type;
+ private Expression variable;
+ private Filter filter;
+ internal int handlerEnd;
+ internal CatchNode()
+ : base(NodeType.Catch){
+ }
+ internal CatchNode(Block block, Expression variable, TypeNode type)
+ : this(block, variable, type, null){
+ }
+ internal CatchNode(Block block, Expression variable, TypeNode type, Filter filter)
+ : base(NodeType.Catch){
+ this.block = block;
+ this.variable = variable;
+ this.type = type;
+ this.filter = filter;
+ }
+ public Block Block{
+ get{return this.block;}
+ internal set{this.block = value;}
+ }
+ public Filter Filter{
+ get{return this.filter;}
+ internal set{this.filter = value;}
+ }
+ public TypeNode Type{
+ get{return this.type;}
+ internal set{this.type = value;}
+ }
+ public Expression Variable{
+ get{return this.variable;}
+ internal set{this.variable = value;}
+ }
+ }
+ public class FinallyNode : Statement{
+ private Block block;
+ internal int handlerEnd;
+ internal FinallyNode()
+ : base(NodeType.Finally){
+ }
+ internal FinallyNode(Block block)
+ : base(NodeType.Finally){
+ this.block = block;
+ }
+ public Block Block{
+ get{return this.block;}
+ internal set{this.block = value;}
+ }
+ }
+ public class TryNode : Statement {
+ private CatchNodeCollection catchers = new CatchNodeCollection();
+ private FaultHandler faultHandler;
+ private FinallyNode finallyClause;
+ private Block block;
+ internal TryNode()
+ : base(NodeType.Try) {
+ }
+ internal TryNode(Block block, CatchNodeCollection catchers, FaultHandler faultHandler, FinallyNode @finally)
+ : base(NodeType.Try) {
+ this.catchers = catchers;
+ this.faultHandler = faultHandler;
+ this.finallyClause = @finally;
+ this.block = block;
+ }
+ internal int tryEnd;
+ internal int handlersEnd;
+ public CatchNodeCollection Catchers {
+ get { return this.catchers; }
+ internal set { this.catchers = value; }
+ }
+ public FaultHandler FaultHandler {
+ get { return this.faultHandler; }
+ internal set { this.faultHandler = value; }
+ }
+ public FinallyNode Finally {
+ get { return this.finallyClause; }
+ internal set { this.finallyClause = value; }
+ }
+ public Block Block {
+ [DebuggerStepThrough] get { return this.block; }
+ [DebuggerStepThrough] internal set { this.block = value; }
+ }
+ }
+ public abstract class FormatOptions
+ {
+ internal Options m_options;
+
+ protected FormatOptions() { }
+
+ internal void SetOptions(Options options, bool enable)
+ {
+ if (enable)
+ {
+ this.m_options |= options;
+ return;
+ }
+ this.m_options &= ~options;
+ }
+
+ internal bool IsSet(Options options)
+ {
+ return (this.m_options & options) == options;
+ }
+
+ [Flags]
+ internal enum Options
+ {
+ None = 0x0,
+ InsertSpacesBetweenParameters = 0x1,
+ InsertSpacesBetweenTypeParameters = 0x2,
+ InsertSpacesBetweenMethodTypeParameters = 0x4,
+ ShowGenericTypeArity = 0x8,
+ ShowGenericMethodTypeParameterNames = 0x10,
+ ShowGenericTypeParameterNames = 0x20,
+ ShowTypeModifiers = 0x40,
+ ShowParameterNames = 0x80
+ }
+ }
+ internal class MemberFormat : FormatOptions
+ {
+ TypeFormat m_declaringTypeFormat;
+ TypeFormat m_returnTypeFormat;
+ ParameterFormat m_parameterFormat;
+
+ public MemberFormat()
+ {
+ this.m_declaringTypeFormat = new TypeFormat();
+ this.m_returnTypeFormat = new TypeFormat();
+ this.m_parameterFormat = new ParameterFormat();
+ }
+
+ public TypeFormat Type
+ {
+ get { return this.m_declaringTypeFormat; }
+ }
+
+ public TypeFormat ReturnType
+ {
+ get { return this.m_returnTypeFormat; }
+ }
+
+ public ParameterFormat Parameters
+ {
+ get { return this.m_parameterFormat; }
+ }
+
+ public bool ShowGenericMethodTypeParameterNames
+ {
+ get { return IsSet(Options.ShowGenericMethodTypeParameterNames); }
+ set { SetOptions(Options.ShowGenericMethodTypeParameterNames, value); }
+ }
+
+ public bool InsertSpacesBetweenMethodTypeParameters
+ {
+ get { return IsSet(Options.InsertSpacesBetweenMethodTypeParameters); }
+ set { SetOptions(Options.InsertSpacesBetweenMethodTypeParameters, value); }
+ }
+ }
+ internal class ParameterFormat : TypeFormat
+ {
+ public ParameterFormat() { }
+
+ public bool InsertSpacesBetweenParameters
+ {
+ get { return IsSet(Options.InsertSpacesBetweenParameters); }
+ set { SetOptions(Options.InsertSpacesBetweenParameters, value); }
+ }
+
+ public bool ShowParameterNames
+ {
+ get { return IsSet(Options.ShowParameterNames); }
+ set { SetOptions(Options.ShowParameterNames, value); }
+ }
+ }
+ internal class TypeFormat : FormatOptions
+ {
+ private TypeNameFormat m_typeName;
+ public TypeFormat() { }
+
+ public TypeFormat Clone()
+ {
+ TypeFormat clone = new TypeFormat();
+ clone.m_typeName = this.m_typeName;
+ clone.m_options = this.m_options;
+ return clone;
+ }
+
+ public bool InsertSpacesBetweenTypeParameters
+ {
+ get { return IsSet(Options.InsertSpacesBetweenTypeParameters); }
+ set { SetOptions(Options.InsertSpacesBetweenTypeParameters, value); }
+ }
+
+ public bool ShowGenericTypeArity
+ {
+ get { return IsSet(Options.ShowGenericTypeArity); }
+ set { SetOptions(Options.ShowGenericTypeArity, value); }
+ }
+
+ public bool ShowGenericTypeParameterNames
+ {
+ get { return IsSet(Options.ShowGenericTypeParameterNames); }
+ set { SetOptions(Options.ShowGenericTypeParameterNames, value); }
+ }
+
+ public bool ShowTypeModifiers
+ {
+ get { return IsSet(Options.ShowTypeModifiers); }
+ set { SetOptions(Options.ShowTypeModifiers, value); }
+ }
+
+ public TypeNameFormat TypeName
+ {
+ get { return this.m_typeName; }
+ set { this.m_typeName = value; }
+ }
+ }
+ internal enum TypeNameFormat
+ {
+ None = 0,
+ InnermostNested,
+ Short,
+ FullyQualified
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/OpCode.cs b/tools/Sandcastle/Source/CCI/OpCode.cs
new file mode 100644
index 0000000..abb5fc6
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/OpCode.cs
@@ -0,0 +1,280 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ public enum OpCode
+ {
+ Nop = 0x00,
+ Break = 0x01,
+ Ldarg_0 = 0x02,
+ Ldarg_1 = 0x03,
+ Ldarg_2 = 0x04,
+ Ldarg_3 = 0x05,
+ Ldloc_0 = 0x06,
+ Ldloc_1 = 0x07,
+ Ldloc_2 = 0x08,
+ Ldloc_3 = 0x09,
+ Stloc_0 = 0x0a,
+ Stloc_1 = 0x0b,
+ Stloc_2 = 0x0c,
+ Stloc_3 = 0x0d,
+ Ldarg_S = 0x0e,
+ Ldarga_S = 0x0f,
+ Starg_S = 0x10,
+ Ldloc_S = 0x11,
+ Ldloca_S = 0x12,
+ Stloc_S = 0x13,
+ Ldnull = 0x14,
+ Ldc_I4_M1 = 0x15,
+ Ldc_I4_0 = 0x16,
+ Ldc_I4_1 = 0x17,
+ Ldc_I4_2 = 0x18,
+ Ldc_I4_3 = 0x19,
+ Ldc_I4_4 = 0x1a,
+ Ldc_I4_5 = 0x1b,
+ Ldc_I4_6 = 0x1c,
+ Ldc_I4_7 = 0x1d,
+ Ldc_I4_8 = 0x1e,
+ Ldc_I4_S = 0x1f,
+ Ldc_I4 = 0x20,
+ Ldc_I8 = 0x21,
+ Ldc_R4 = 0x22,
+ Ldc_R8 = 0x23,
+ Dup = 0x25,
+ Pop = 0x26,
+ Jmp = 0x27,
+ Call = 0x28,
+ Calli = 0x29,
+ Ret = 0x2a,
+ Br_S = 0x2b,
+ Brfalse_S = 0x2c,
+ Brtrue_S = 0x2d,
+ Beq_S = 0x2e,
+ Bge_S = 0x2f,
+ Bgt_S = 0x30,
+ Ble_S = 0x31,
+ Blt_S = 0x32,
+ Bne_Un_S = 0x33,
+ Bge_Un_S = 0x34,
+ Bgt_Un_S = 0x35,
+ Ble_Un_S = 0x36,
+ Blt_Un_S = 0x37,
+ Br = 0x38,
+ Brfalse = 0x39,
+ Brtrue = 0x3a,
+ Beq = 0x3b,
+ Bge = 0x3c,
+ Bgt = 0x3d,
+ Ble = 0x3e,
+ Blt = 0x3f,
+ Bne_Un = 0x40,
+ Bge_Un = 0x41,
+ Bgt_Un = 0x42,
+ Ble_Un = 0x43,
+ Blt_Un = 0x44,
+ @Switch = 0x45,
+ Ldind_I1 = 0x46,
+ Ldind_U1 = 0x47,
+ Ldind_I2 = 0x48,
+ Ldind_U2 = 0x49,
+ Ldind_I4 = 0x4a,
+ Ldind_U4 = 0x4b,
+ Ldind_I8 = 0x4c,
+ Ldind_I = 0x4d,
+ Ldind_R4 = 0x4e,
+ Ldind_R8 = 0x4f,
+ Ldind_Ref = 0x50,
+ Stind_Ref = 0x51,
+ Stind_I1 = 0x52,
+ Stind_I2 = 0x53,
+ Stind_I4 = 0x54,
+ Stind_I8 = 0x55,
+ Stind_R4 = 0x56,
+ Stind_R8 = 0x57,
+ Add = 0x58,
+ Sub = 0x59,
+ Mul = 0x5a,
+ Div = 0x5b,
+ Div_Un = 0x5c,
+ Rem = 0x5d,
+ Rem_Un = 0x5e,
+ And = 0x5f,
+ Or = 0x60,
+ Xor = 0x61,
+ Shl = 0x62,
+ Shr = 0x63,
+ Shr_Un = 0x64,
+ Neg = 0x65,
+ Not = 0x66,
+ Conv_I1 = 0x67,
+ Conv_I2 = 0x68,
+ Conv_I4 = 0x69,
+ Conv_I8 = 0x6a,
+ Conv_R4 = 0x6b,
+ Conv_R8 = 0x6c,
+ Conv_U4 = 0x6d,
+ Conv_U8 = 0x6e,
+ Callvirt = 0x6f,
+ Cpobj = 0x70,
+ Ldobj = 0x71,
+ Ldstr = 0x72,
+ Newobj = 0x73,
+ Castclass = 0x74,
+ Isinst = 0x75,
+ Conv_R_Un = 0x76,
+ Unbox = 0x79,
+ Throw = 0x7a,
+ Ldfld = 0x7b,
+ Ldflda = 0x7c,
+ Stfld = 0x7d,
+ Ldsfld = 0x7e,
+ Ldsflda = 0x7f,
+ Stsfld = 0x80,
+ Stobj = 0x81,
+ Conv_Ovf_I1_Un = 0x82,
+ Conv_Ovf_I2_Un = 0x83,
+ Conv_Ovf_I4_Un = 0x84,
+ Conv_Ovf_I8_Un = 0x85,
+ Conv_Ovf_U1_Un = 0x86,
+ Conv_Ovf_U2_Un = 0x87,
+ Conv_Ovf_U4_Un = 0x88,
+ Conv_Ovf_U8_Un = 0x89,
+ Conv_Ovf_I_Un = 0x8a,
+ Conv_Ovf_U_Un = 0x8b,
+ Box = 0x8c,
+ Newarr = 0x8d,
+ Ldlen = 0x8e,
+ Ldelema = 0x8f,
+ Ldelem_I1 = 0x90,
+ Ldelem_U1 = 0x91,
+ Ldelem_I2 = 0x92,
+ Ldelem_U2 = 0x93,
+ Ldelem_I4 = 0x94,
+ Ldelem_U4 = 0x95,
+ Ldelem_I8 = 0x96,
+ Ldelem_I = 0x97,
+ Ldelem_R4 = 0x98,
+ Ldelem_R8 = 0x99,
+ Ldelem_Ref = 0x9a,
+ Stelem_I = 0x9b,
+ Stelem_I1 = 0x9c,
+ Stelem_I2 = 0x9d,
+ Stelem_I4 = 0x9e,
+ Stelem_I8 = 0x9f,
+ Stelem_R4 = 0xa0,
+ Stelem_R8 = 0xa1,
+ Stelem_Ref = 0xa2,
+ Ldelem = 0xa3,
+ Stelem = 0xa4,
+ Unbox_Any = 0xa5,
+ Conv_Ovf_I1 = 0xb3,
+ Conv_Ovf_U1 = 0xb4,
+ Conv_Ovf_I2 = 0xb5,
+ Conv_Ovf_U2 = 0xb6,
+ Conv_Ovf_I4 = 0xb7,
+ Conv_Ovf_U4 = 0xb8,
+ Conv_Ovf_I8 = 0xb9,
+ Conv_Ovf_U8 = 0xba,
+ Refanyval = 0xc2,
+ Ckfinite = 0xc3,
+ Mkrefany = 0xc6,
+ Ldtoken = 0xd0,
+ Conv_U2 = 0xd1,
+ Conv_U1 = 0xd2,
+ Conv_I = 0xd3,
+ Conv_Ovf_I = 0xd4,
+ Conv_Ovf_U = 0xd5,
+ Add_Ovf = 0xd6,
+ Add_Ovf_Un = 0xd7,
+ Mul_Ovf = 0xd8,
+ Mul_Ovf_Un = 0xd9,
+ Sub_Ovf = 0xda,
+ Sub_Ovf_Un = 0xdb,
+ Endfinally = 0xdc,
+ Leave = 0xdd,
+ Leave_S = 0xde,
+ Stind_I = 0xdf,
+ Conv_U = 0xe0,
+ Prefix7 = 0xf8,
+ Prefix6 = 0xf9,
+ Prefix5 = 0xfa,
+ Prefix4 = 0xfb,
+ Prefix3 = 0xfc,
+ Prefix2 = 0xfd,
+ Prefix1 = 0xfe,
+ PrefixRef = 0xff,
+ Arglist = 0xfe00,
+ Ceq = 0xfe01,
+ Cgt = 0xfe02,
+ Cgt_Un = 0xfe03,
+ Clt = 0xfe04,
+ Clt_Un = 0xfe05,
+ Ldftn = 0xfe06,
+ Ldvirtftn = 0xfe07,
+ Ldarg = 0xfe09,
+ Ldarga = 0xfe0a,
+ Starg = 0xfe0b,
+ Ldloc = 0xfe0c,
+ Ldloca = 0xfe0d,
+ Stloc = 0xfe0e,
+ Localloc = 0xfe0f,
+ Endfilter = 0xfe11,
+ Unaligned_ = 0xfe12,
+ Volatile_ = 0xfe13,
+ Tail_ = 0xfe14,
+ Initobj = 0xfe15,
+ Constrained_ = 0xfe16,
+ Cpblk = 0xfe17,
+ Initblk = 0xfe18,
+ Rethrow = 0xfe1a,
+ Sizeof = 0xfe1c,
+ Refanytype = 0xfe1d,
+ Readonly_ = 0xfe1e,
+ // fake opcodes
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Locals = 0xfef7,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Try = 0xfef8,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _EndTry = 0xfef9,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Filter = 0xfefa,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _EndFilter = 0xfefb,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Catch = 0xfefc,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Finally = 0xfefd,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _Fault = 0xfefe,
+#if WHIDBEY
+ [CLSCompliant(false)]
+#endif
+ _EndHandler = 0xfeff
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/CCI/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..7027a51
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CCI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CCI")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: CLSCompliant(false)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("74507b34-d122-439a-aab1-a77f889da5f4")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/CCI/Reader.cs b/tools/Sandcastle/Source/CCI/Reader.cs
new file mode 100644
index 0000000..713e9b7
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Reader.cs
@@ -0,0 +1,6074 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+#if FxCop
+using System.Collections.Generic;
+using AssemblyReferenceList = Microsoft.Cci.AssemblyReferenceCollection;
+using AttributeList = Microsoft.Cci.AttributeNodeCollection;
+using BlockList = Microsoft.Cci.BlockCollection;
+using ExpressionList = Microsoft.Cci.ExpressionCollection;
+using InstructionList = Microsoft.Cci.InstructionCollection;
+using Int32List = System.Collections.Generic.List<int>;
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using LocalList = Microsoft.Cci.LocalCollection;
+using MemberList = Microsoft.Cci.MemberCollection;
+using MethodList = Microsoft.Cci.MethodCollection;
+using ModuleReferenceList = Microsoft.Cci.ModuleReferenceCollection;
+using NamespaceList = Microsoft.Cci.NamespaceCollection;
+using ParameterList = Microsoft.Cci.ParameterCollection;
+using ResourceList = Microsoft.Cci.ResourceCollection;
+using SecurityAttributeList = Microsoft.Cci.SecurityAttributeCollection;
+using StatementList = Microsoft.Cci.StatementCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Win32ResourceList = Microsoft.Cci.Win32ResourceCollection;
+using Property = Microsoft.Cci.PropertyNode;
+using Module = Microsoft.Cci.ModuleNode;
+using Class = Microsoft.Cci.ClassNode;
+using Interface = Microsoft.Cci.InterfaceNode;
+using Event = Microsoft.Cci.EventNode;
+using Return = Microsoft.Cci.ReturnNode;
+using Throw = Microsoft.Cci.ThrowNode;
+#endif
+#if UseSingularityPDB
+using Microsoft.Singularity.PdbInfo;
+using Microsoft.Singularity.PdbInfo.Features;
+#endif
+#if CCINamespace
+using Microsoft.Cci;
+#else
+using System.Compiler;
+#endif
+using System.Diagnostics;
+using System.Globalization;
+using Marshal = System.Runtime.InteropServices.Marshal;
+using System.Runtime.InteropServices;
+using System.IO;
+
+#if CCINamespace
+namespace Microsoft.Cci.Metadata{
+#else
+namespace System.Compiler.Metadata
+{
+#endif
+
+#if !ROTOR && !UseSingularityPDB
+ enum CorOpenFlags : uint
+ {
+ ofRead = 0x00000000, // Open scope for read
+ ofWrite = 0x00000001, // Open scope for write.
+ ofCopyMemory = 0x00000002, // Open scope with memory. Ask metadata to maintain its own copy of memory.
+ ofCacheImage = 0x00000004, // EE maps but does not do relocations or verify image
+ ofNoTypeLib = 0x00000080, // Don't OpenScope on a typelib.
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("809c652e-7396-11d2-9771-00A0C9B4D50C")]
+ interface IMetaDataDispenser
+ {
+ void DefineScope(ref Guid clsid, uint createFlags, [In] ref Guid iid, [MarshalAs(UnmanagedType.IUnknown)] out object retval);
+ [PreserveSig]
+ int OpenScope(string scope, uint openFlags, [In] ref Guid iid, [MarshalAs(UnmanagedType.IUnknown)] out object import);
+ void OpenScopeOnMemory(IntPtr data, uint dataSize, uint openFlags, [In] ref Guid iid, [MarshalAs(UnmanagedType.IUnknown)] out object retval);
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("AA544D42-28CB-11d3-BD22-0000F80849BD")]
+ interface ISymUnmanagedBinder
+ {
+ [PreserveSig]
+ int GetReaderForFile([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath, out ISymUnmanagedReader reader);
+ ISymUnmanagedReader GetReaderForStream([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.IUnknown)] object stream);
+ }
+ [ComImport, Guid("ACCEE350-89AF-4ccb-8B40-1C2C4C6F9434"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)]
+ interface ISymUnmanagedBinder2 : ISymUnmanagedBinder
+ {
+ void GetReaderForFile(IntPtr importer, [MarshalAs(UnmanagedType.LPWStr)] String filename, [MarshalAs(UnmanagedType.LPWStr)] String SearchPath, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
+ void GetReaderFromStream(IntPtr importer, IntPtr stream, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
+ [PreserveSig]
+ int GetReaderForFile2([MarshalAs(UnmanagedType.IUnknown)] object importer, [MarshalAs(UnmanagedType.LPWStr)] String fileName, [MarshalAs(UnmanagedType.LPWStr)] String searchPath, int searchPolicy, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal);
+ // void GetReaderForFile3(IntPtr importer, [MarshalAs(UnmanagedType.LPWStr)] String fileName, [MarshalAs(UnmanagedType.LPWStr)] String searchPath, int searchPolicy, IntPtr callback, [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal);
+ }
+ [ComImport, Guid("AA544D41-28CB-11d3-BD22-0000F80849BD")]
+ class CorSymBinder
+ {
+ }
+ [ComImport, Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931")]
+ class CorSymBinder2
+ {
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5")]
+ interface ISymUnmanagedReader
+ {
+ ISymUnmanagedDocument GetDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType);
+ void GetDocuments(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedDocument[] docs);
+ uint GetUserEntryPoint();
+ [PreserveSig]
+ int GetMethod(uint token, ref ISymUnmanagedMethod method);
+ ISymUnmanagedMethod GetMethodByVersion(uint token, int version);
+ void GetVariables(uint parent, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ISymUnmanagedVariable[] vars);
+ void GetGlobalVariables(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] vars);
+ ISymUnmanagedMethod GetMethodFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column);
+ void GetSymAttribute(uint parent, string name, ulong size, ref uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer);
+ void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
+ void Initialize([MarshalAs(UnmanagedType.IUnknown)] object importer, string filename, string searchPath, [MarshalAs(UnmanagedType.IUnknown)] object stream);
+ void UpdateSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
+ void ReplaceSymbolStore(string filename, [MarshalAs(UnmanagedType.IUnknown)] object stream);
+ void GetSymbolStoreFileName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
+ void GetMethodsFromDocumentPosition(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] ISymUnmanagedMethod[] retval);
+ void GetDocumentVersion(ISymUnmanagedDocument doc, out int version, out bool isLatest);
+ void GetMethodVersion(ISymUnmanagedMethod method, out int version);
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B62B923C-B500-3158-A543-24F307A8B7E1")]
+ interface ISymUnmanagedMethod
+ {
+ uint GetToken();
+ uint GetSequencePointCount();
+ ISymUnmanagedScope GetRootScope();
+ ISymUnmanagedScope GetScopeFromOffset(uint offset);
+ uint Getoffset(ISymUnmanagedDocument document, uint line, uint column);
+ void GetRanges(ISymUnmanagedDocument document, uint line, uint column, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] ranges);
+ void GetParameters(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] parms);
+ IntPtr GetNamespace();
+ bool GetSourceStartEnd([MarshalAs(UnmanagedType.LPArray, SizeConst = 2)] ISymUnmanagedDocument[] docs, [MarshalAs(UnmanagedType.LPArray)] uint[] lines, [MarshalAs(UnmanagedType.LPArray)] uint[] columns);
+ void GetSequencePoints(uint size, out uint length,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] offsets,
+ [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.IUnknown, SizeParamIndex = 0)] IntPtr[] documents,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] lines,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] columns,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endLines,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] uint[] endColumns);
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08")]
+ interface ISymUnmanagedDocument
+ {
+ void GetURL(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] url);
+ void GetDocumentType(out Guid retval);
+ void GetLanguage(out Guid retval);
+ void GetLanguageVendor(out Guid retval);
+ void GetCheckSumAlgorithmId(out Guid retval);
+ void GetCheckSum(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] data);
+ uint FindClosestLine(uint line);
+ bool HasEmbeddedSource();
+ uint GetSourceLength();
+ void GetSourceRange(uint startLine, uint startColumn, uint endLine, uint endColumn, uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] byte[] source);
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB")]
+ interface ISymUnmanagedVariable
+ {
+ void GetName(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] name);
+ uint GetAttributes();
+ void GetSignature(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] name);
+ uint GetAddressKind();
+ uint GetAddressField1();
+ uint GetAddressField2();
+ uint GetAddressField3();
+ uint GetStartOffset();
+ uint GetEndOffset();
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("68005D0F-B8E0-3B01-84D5-A11A94154942")]
+ interface ISymUnmanagedScope
+ {
+ ISymUnmanagedMethod GetMethod();
+ ISymUnmanagedScope GetParent();
+ void GetChildren(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] children);
+ uint GetStartOffset();
+ uint GetEndOffset();
+ uint GetLocalCount();
+ void GetLocals(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] locals);
+ void GetNamespaces(uint size, out uint length, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] namespaces);
+ }
+#endif
+ internal sealed class UnmanagedBuffer : IDisposable
+ {
+ internal IntPtr Pointer;
+ internal UnmanagedBuffer(int length)
+ {
+ this.Pointer = Marshal.AllocHGlobal(length);
+ }
+ public void Dispose()
+ {
+ if (this.Pointer != IntPtr.Zero)
+ Marshal.FreeHGlobal(this.Pointer);
+ this.Pointer = IntPtr.Zero;
+ GC.SuppressFinalize(this);
+ }
+ ~UnmanagedBuffer()
+ {
+ this.Dispose();
+ }
+ }
+ internal unsafe class Reader : IDisposable
+ {
+ private string directory;
+ private string fileName;
+ private bool doNotLockFile;
+ private Module/*!*/ module = new Module();
+ internal TypeNode currentType;
+ private long sortedTablesMask;
+ internal MetadataReader/*!*/ tables;
+ private UnmanagedBuffer unmanagedBuffer;
+ private int bufferLength;
+ private IDictionary/*!*/ localAssemblyCache; //use for simple names
+ internal readonly static IDictionary/*!*/ StaticAssemblyCache = new SynchronizedWeakDictionary(); //use for strong names
+ private bool useStaticCache;
+ //^ [Microsoft.Contracts.SpecInternal]
+ private TrivialHashtable namespaceTable;
+ internal NamespaceList namespaceList;
+#if UseSingularityPDB
+ internal PdbFunction[] pdbFunctions;
+#elif !ROTOR
+ internal ISymUnmanagedReader debugReader;
+#endif
+#if FxCop
+ internal static bool probeGAC = true;
+#endif
+ internal bool getDebugSymbols;
+ private bool getDebugSymbolsFailed;
+ private TypeNodeList currentTypeParameters;
+ private TypeNodeList currentMethodTypeParameters;
+ internal bool preserveShortBranches;
+#if !MinimalReader
+ internal unsafe Reader(byte[]/*!*/ buffer, IDictionary localAssemblyCache, bool doNotLockFile, bool getDebugInfo, bool useStaticCache, bool preserveShortBranches)
+ {
+ Debug.Assert(buffer != null);
+ if (localAssemblyCache == null) localAssemblyCache = new Hashtable();
+ this.localAssemblyCache = localAssemblyCache;
+ this.getDebugSymbols = getDebugInfo;
+ this.doNotLockFile = false;
+ this.useStaticCache = useStaticCache;
+ this.preserveShortBranches = preserveShortBranches;
+ int n = this.bufferLength = buffer.Length;
+ this.unmanagedBuffer = new UnmanagedBuffer(n);
+ //^ base();
+ byte* pb = (byte*)this.unmanagedBuffer.Pointer;
+ for (int i = 0; i < n; i++) *pb++ = buffer[i];
+ }
+#endif
+ internal Reader(string/*!*/ fileName, IDictionary localAssemblyCache, bool doNotLockFile, bool getDebugInfo, bool useStaticCache, bool preserveShortBranches)
+ {
+ if (localAssemblyCache == null) localAssemblyCache = new Hashtable();
+ this.localAssemblyCache = localAssemblyCache;
+ fileName = System.IO.Path.GetFullPath(fileName);
+ this.fileName = fileName;
+ this.directory = System.IO.Path.GetDirectoryName(fileName);
+ this.getDebugSymbols = getDebugInfo;
+ this.doNotLockFile = doNotLockFile;
+ this.useStaticCache = useStaticCache;
+ this.preserveShortBranches = preserveShortBranches;
+ //^ base();
+ }
+ internal Reader(IDictionary localAssemblyCache, bool doNotLockFile, bool getDebugInfo, bool useStaticCache, bool preserveShortBranches)
+ {
+ if (localAssemblyCache == null) localAssemblyCache = new Hashtable();
+ this.localAssemblyCache = localAssemblyCache;
+ this.directory = System.IO.Directory.GetCurrentDirectory();
+ this.getDebugSymbols = getDebugInfo;
+ this.doNotLockFile = doNotLockFile;
+ this.useStaticCache = useStaticCache;
+ this.preserveShortBranches = preserveShortBranches;
+ //^ base();
+ }
+ public void Dispose()
+ {
+ if (this.unmanagedBuffer != null)
+ this.unmanagedBuffer.Dispose();
+ this.unmanagedBuffer = null;
+ if (this.tables != null)
+ this.tables.Dispose();
+ //this.tables = null;
+#if !ROTOR && !UseSingularityPDB
+ if (this.debugReader != null)
+ Marshal.ReleaseComObject(this.debugReader);
+ this.debugReader = null;
+#endif
+ }
+ private unsafe void SetupReader()
+ {
+ Debug.Assert(this.localAssemblyCache != null);
+#if !ROTOR
+ if (this.doNotLockFile)
+ {
+#endif
+ using (System.IO.FileStream inputStream = new System.IO.FileStream(this.fileName,
+ System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
+ {
+ this.ReadFileIntoUnmanagedBuffer(inputStream);
+ }
+#if !ROTOR
+ }
+ if (this.unmanagedBuffer == null)
+ this.tables = new MetadataReader(this.fileName); //Uses a memory map that locks the file
+ else
+#endif
+ this.tables = new MetadataReader((byte*)this.unmanagedBuffer.Pointer, this.bufferLength);
+ //^ assume this.tables.tablesHeader != null;
+ this.sortedTablesMask = this.tables.tablesHeader.maskSorted;
+ }
+#if !ROTOR
+ [DllImport("kernel32", SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ static extern unsafe bool ReadFile(IntPtr FileHandle, byte* Buffer, int NumberOfBytesToRead, int* NumberOfBytesRead, IntPtr Overlapped);
+#endif
+ private unsafe void ReadFileIntoUnmanagedBuffer(System.IO.FileStream/*!*/ inputStream)
+ {
+ long size = inputStream.Seek(0, System.IO.SeekOrigin.End);
+ if (size > int.MaxValue) throw new System.IO.FileLoadException();
+ inputStream.Seek(0, System.IO.SeekOrigin.Begin);
+ int n = (int)size;
+ this.bufferLength = n;
+ this.unmanagedBuffer = new UnmanagedBuffer(n);
+ byte* pb = (byte*)this.unmanagedBuffer.Pointer;
+#if !ROTOR
+#if WHIDBEY && !OldWhidbey
+ if (!Reader.ReadFile(inputStream.SafeFileHandle.DangerousGetHandle(), pb, n, &n, IntPtr.Zero)) throw new System.IO.FileLoadException();
+#else
+ if (!Reader.ReadFile(inputStream.Handle, pb, n, &n, IntPtr.Zero)) throw new System.IO.FileLoadException();
+#endif
+#else
+ //Read a fixed length block at a time, so that the GC does not come under pressure from lots of large byte arrays.
+ int bufferLen = 8096;
+ byte[] buffer = new byte[bufferLen];
+ while (n > 0){
+ if (n < bufferLen) bufferLen = n;
+ inputStream.Read(buffer, 0, bufferLen);
+ for (int i = 0; i < bufferLen; i++) *pb++ = buffer[i];
+ n -= bufferLen;
+ }
+#endif
+ }
+ internal void SetupDebugReader(string filename, string pdbSearchPath)
+ {
+#if UseSingularityPDB
+ string pdbFileName = BetterPath.ChangeExtension(filename, "pdb");
+ this.getDebugSymbolsFailed = true;
+ //TODO: use search path
+ if (System.IO.File.Exists(pdbFileName)) {
+ using (System.IO.FileStream inputStream = new System.IO.FileStream(pdbFileName,
+ System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)) {
+ this.pdbFunctions = PdbFile.LoadFunctions(inputStream, true);
+ this.getDebugSymbolsFailed = false;
+ }
+ }
+#elif !ROTOR
+ if (filename == null) return;
+ CorSymBinder binderObj1 = null;
+ CorSymBinder2 binderObj2 = null;
+ getDebugSymbolsFailed = false;
+ object importer = null;
+ try
+ {
+ int hresult = 0;
+ try
+ {
+ binderObj2 = new CorSymBinder2();
+ ISymUnmanagedBinder2 binder2 = (ISymUnmanagedBinder2)binderObj2;
+#if !NoWriter
+ importer = new Ir2md(new Module());
+#else
+ importer = new EmptyImporter();
+#endif
+ hresult = binder2.GetReaderForFile(importer, filename, pdbSearchPath, out this.debugReader);
+ }
+ catch (COMException e)
+ {
+ // could not instantiate ISymUnmanagedBinder2, fall back to ISymUnmanagedBinder
+ if ((uint)e.ErrorCode == 0x80040111)
+ {
+ binderObj1 = new CorSymBinder();
+ ISymUnmanagedBinder binder = (ISymUnmanagedBinder)binderObj1;
+ hresult = binder.GetReaderForFile(importer, filename, null, out this.debugReader);
+ }
+ else
+ {
+ throw;
+ }
+ }
+ switch ((uint)hresult)
+ {
+ case 0x0: break;
+ case 0x806d0005: // EC_NOT_FOUND
+ case 0x806d0014: // EC_INVALID_EXE_TIMESTAMP
+#if FxCop
+ this.getDebugSymbols = false;
+ this.getDebugSymbolsFailed = true;
+#else
+ // Sometimes GetReaderForFile erroneously reports missing pdb files as being "out of date",
+ // so we check if the file actually exists before reporting the error.
+ // The mere absence of a pdb file is not an error. If not present, do not report.
+ if (System.IO.File.Exists(System.IO.Path.ChangeExtension(filename, ".pdb")))
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExceptionStrings.PdbAssociatedWithFileIsOutOfDate, filename));
+#endif
+ break;
+ default:
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.GetReaderForFileReturnedUnexpectedHResult, hresult.ToString("X")));
+ }
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ this.getDebugSymbols = false;
+ this.getDebugSymbolsFailed = true;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+#endif
+ }
+ finally
+ {
+ if (binderObj1 != null) Marshal.ReleaseComObject(binderObj1);
+ if (binderObj2 != null) Marshal.ReleaseComObject(binderObj2);
+ }
+#endif // !ROTOR
+ }
+ private AssemblyNode ReadAssembly()
+ {
+ try
+ {
+ AssemblyNode assembly = new AssemblyNode(new Module.TypeNodeProvider(this.GetTypeFromName),
+ new Module.TypeNodeListProvider(this.GetTypeList), new Module.CustomAttributeProvider(this.GetCustomAttributesFor),
+ new Module.ResourceProvider(this.GetResources), this.directory);
+ assembly.reader = this;
+ this.ReadModuleProperties(assembly);
+ this.ReadAssemblyProperties(assembly); //Hashvalue, Name, etc.
+ this.module = assembly;
+ this.ReadAssemblyReferences(assembly);
+ this.ReadModuleReferences(assembly);
+ AssemblyNode cachedAssembly = this.GetCachedAssembly(assembly);
+ if (cachedAssembly != null) return cachedAssembly;
+ if (this.getDebugSymbols) assembly.SetupDebugReader(null);
+#if !MinimalReader
+ assembly.AfterAssemblyLoadProcessing();
+#endif
+ return assembly;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return null;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ return this.module as AssemblyNode;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private AssemblyNode GetCachedAssembly(AssemblyNode/*!*/ assembly)
+ {
+ //Always return the one true mscorlib. Things get too weird if more than one mscorlib is being read at the same time.
+ //if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assembly.Name && CoreSystemTypes.SystemAssembly.reader != null) {
+ // if (CoreSystemTypes.SystemAssembly.reader != this) {
+ // if (this.getDebugSymbols && !CoreSystemTypes.SystemAssembly.reader.getDebugSymbols && !CoreSystemTypes.SystemAssembly.reader.getDebugSymbolsFailed)
+ // CoreSystemTypes.SystemAssembly.SetupDebugReader(null);
+ // this.Dispose();
+ // }
+ // return CoreSystemTypes.SystemAssembly;
+ //}
+ if (assembly.PublicKeyOrToken == null || assembly.PublicKeyOrToken.Length == 0)
+ {
+ AssemblyNode cachedAssembly = null;
+ if (assembly.Location != null)
+ cachedAssembly = this.localAssemblyCache[assembly.Location] as AssemblyNode;
+ if (cachedAssembly == null && assembly.Name != null)
+ {
+ cachedAssembly = this.localAssemblyCache[assembly.Name] as AssemblyNode;
+ if (cachedAssembly != null && assembly.Location != null)
+ this.localAssemblyCache[assembly.Location] = cachedAssembly;
+ }
+ if (cachedAssembly != null)
+ {
+ if (cachedAssembly.reader != this && cachedAssembly.reader != null)
+ {
+ if (this.getDebugSymbols && !cachedAssembly.reader.getDebugSymbols && !cachedAssembly.reader.getDebugSymbolsFailed)
+ cachedAssembly.SetupDebugReader(null);
+ this.Dispose();
+ }
+ return cachedAssembly;
+ }
+ lock (Reader.StaticAssemblyCache)
+ {
+ if (assembly.Name != null)
+ this.localAssemblyCache[assembly.Name] = assembly;
+ if (this.fileName != null)
+ this.localAssemblyCache[this.fileName] = assembly;
+ }
+ }
+ else
+ {
+ string assemblyStrongName = assembly.StrongName;
+ AssemblyNode cachedAssembly = null;
+ if (this.useStaticCache)
+ {
+ //See if assembly is a platform assembly (and apply unification)
+ AssemblyReference assemblyReference = new AssemblyReference(assembly);
+ AssemblyReference aRef = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[Identifier.For(assemblyReference.Name).UniqueIdKey];
+ if (aRef != null && assemblyReference.Version != null && aRef.Version >= assemblyReference.Version && aRef.MatchesIgnoringVersion(assemblyReference))
+ {
+ AssemblyNode platformAssembly = aRef.assembly;
+ if (platformAssembly == null)
+ {
+ Debug.Assert(aRef.Location != null);
+ if (Path.GetFullPath(aRef.Location) == assembly.Location)
+ {
+ if (aRef.Version != assemblyReference.Version)
+ {
+ HandleError(assembly, String.Format(CultureInfo.CurrentCulture, ExceptionStrings.BadTargetPlatformLocation, assembly.Name, TargetPlatform.PlatformAssembliesLocation, assembly.Version, aRef.Version));
+ }
+ lock (Reader.StaticAssemblyCache)
+ {
+ Reader.StaticAssemblyCache[assemblyStrongName] = assembly;
+ if (aRef.Location != null)
+ Reader.StaticAssemblyCache[aRef.Location] = assembly;
+ }
+ return null; //Prevents infinite recursion
+ }
+ platformAssembly = AssemblyNode.GetAssembly(aRef.Location, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ }
+ if (platformAssembly != null)
+ {
+ lock (Reader.StaticAssemblyCache)
+ {
+ if (aRef.Location != null)
+ Reader.StaticAssemblyCache[aRef.Location] = platformAssembly;
+ Reader.StaticAssemblyCache[assemblyStrongName] = platformAssembly;
+ }
+ return aRef.assembly = platformAssembly;
+ }
+ }
+ cachedAssembly = Reader.StaticAssemblyCache[assemblyStrongName] as AssemblyNode;
+ if (cachedAssembly != null)
+ {
+ if (aRef == null && assembly.FileLastWriteTimeUtc > cachedAssembly.FileLastWriteTimeUtc &&
+ assembly.Location != null && cachedAssembly.Location != null && assembly.Location == cachedAssembly.Location)
+ {
+ lock (Reader.StaticAssemblyCache)
+ {
+ Reader.StaticAssemblyCache[assemblyStrongName] = assembly;
+ }
+ return null;
+ }
+ if (cachedAssembly.reader != this && cachedAssembly.reader != null)
+ {
+ if (this.getDebugSymbols && !cachedAssembly.reader.getDebugSymbols && !cachedAssembly.reader.getDebugSymbolsFailed)
+ cachedAssembly.SetupDebugReader(null);
+ this.Dispose();
+ }
+ return cachedAssembly;
+ }
+ lock (Reader.StaticAssemblyCache)
+ {
+ Reader.StaticAssemblyCache[assemblyStrongName] = assembly;
+ if (this.fileName != null)
+ {
+ Reader.StaticAssemblyCache[this.fileName] = assembly;
+ }
+ }
+ }
+ else
+ {
+ cachedAssembly = this.localAssemblyCache[assemblyStrongName] as AssemblyNode;
+ if (cachedAssembly != null)
+ {
+ if (assembly.FileLastWriteTimeUtc > cachedAssembly.FileLastWriteTimeUtc &&
+ assembly.Location != null && cachedAssembly.Location != null && assembly.Location == cachedAssembly.Location)
+ {
+ this.localAssemblyCache[assemblyStrongName] = assembly;
+ return null;
+ }
+ if (cachedAssembly.reader != this && cachedAssembly.reader != null)
+ {
+#if UseSingularityPDB
+ if (this.getDebugSymbols && cachedAssembly.reader.pdbFunctions == null && !cachedAssembly.reader.getDebugSymbolsFailed)
+ cachedAssembly.SetupDebugReader(null);
+#elif !ROTOR
+ if (this.getDebugSymbols && cachedAssembly.reader.debugReader == null && !cachedAssembly.reader.getDebugSymbolsFailed)
+ cachedAssembly.SetupDebugReader(null);
+#endif
+ this.Dispose();
+ }
+ return cachedAssembly;
+ }
+ this.localAssemblyCache[assemblyStrongName] = assembly;
+ if (this.fileName != null) this.localAssemblyCache[this.fileName] = assembly;
+ }
+ }
+ return null;
+ }
+ internal Module ReadModule()
+ {
+ try
+ {
+ if (this.fileName != null)
+ {
+ if (!System.IO.File.Exists(this.fileName)) return null;
+ AssemblyNode cachedAssembly;
+ if (this.useStaticCache)
+ {
+ cachedAssembly = Reader.StaticAssemblyCache[this.fileName] as AssemblyNode;
+ if (cachedAssembly != null && cachedAssembly.FileLastWriteTimeUtc == System.IO.File.GetLastWriteTimeUtc(this.fileName))
+ {
+ this.Dispose();
+ return cachedAssembly;
+ }
+ }
+ cachedAssembly = this.localAssemblyCache[this.fileName] as AssemblyNode;
+ if (cachedAssembly != null && cachedAssembly.FileLastWriteTimeUtc == System.IO.File.GetLastWriteTimeUtc(this.fileName))
+ {
+ this.Dispose();
+ return cachedAssembly;
+ }
+ }
+ this.SetupReader();
+ if (this.tables.AssemblyTable.Length > 0) return this.ReadAssembly();
+ Module module = this.module = new Module(new Module.TypeNodeProvider(this.GetTypeFromName),
+ new Module.TypeNodeListProvider(this.GetTypeList), new Module.CustomAttributeProvider(this.GetCustomAttributesFor),
+ new Module.ResourceProvider(this.GetResources));
+ module.reader = this;
+ this.ReadModuleProperties(module);
+ this.module = module;
+ this.ReadAssemblyReferences(module);
+ this.ReadModuleReferences(module);
+ if (this.getDebugSymbols) this.SetupDebugReader(this.fileName, null);
+ return module;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return null;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ return module;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private void ReadModuleProperties(Module/*!*/ module)
+ {
+ ModuleRow[] mods = this.tables.ModuleTable;
+ if (mods.Length != 1) throw new InvalidMetadataException(ExceptionStrings.InvalidModuleTable);
+ ModuleRow mrow = mods[0];
+ module.reader = this;
+ module.FileAlignment = this.tables.fileAlignment;
+ module.HashValue = this.tables.HashValue;
+ module.Kind = this.tables.moduleKind;
+ module.Location = this.fileName;
+ module.TargetRuntimeVersion = this.tables.targetRuntimeVersion;
+ module.LinkerMajorVersion = this.tables.linkerMajorVersion;
+ module.LinkerMinorVersion = this.tables.linkerMinorVersion;
+ module.MetadataFormatMajorVersion = this.tables.metadataFormatMajorVersion;
+ module.MetadataFormatMinorVersion = this.tables.metadataFormatMinorVersion;
+ module.Name = this.tables.GetString(mrow.Name);
+ module.Mvid = this.tables.GetGuid(mrow.Mvid);
+ module.PEKind = this.tables.peKind;
+ module.TrackDebugData = this.tables.TrackDebugData;
+ }
+ private void ReadAssemblyProperties(AssemblyNode/*!*/ assembly)
+ {
+ AssemblyRow assemblyRow = this.tables.AssemblyTable[0];
+ assembly.HashAlgorithm = (AssemblyHashAlgorithm)assemblyRow.HashAlgId;
+ assembly.Version = new System.Version(assemblyRow.MajorVersion, assemblyRow.MinorVersion, assemblyRow.BuildNumber, assemblyRow.RevisionNumber);
+ assembly.Flags = (AssemblyFlags)assemblyRow.Flags;
+ assembly.PublicKeyOrToken = this.tables.GetBlob(assemblyRow.PublicKey);
+ assembly.ModuleName = assembly.Name;
+ assembly.Name = this.tables.GetString(assemblyRow.Name);
+ assembly.Culture = this.tables.GetString(assemblyRow.Culture);
+ if (this.fileName != null)
+ {
+ assembly.FileLastWriteTimeUtc = System.IO.File.GetLastWriteTimeUtc(this.fileName);
+ }
+ assembly.ContainingAssembly = assembly;
+ }
+ private void ReadAssemblyReferences(Module/*!*/ module)
+ {
+ AssemblyRefRow[] assems = this.tables.AssemblyRefTable;
+ int n = assems.Length;
+ AssemblyReferenceList assemblies = module.AssemblyReferences = new AssemblyReferenceList(n);
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyRefRow arr = assems[i];
+ AssemblyReference assemRef = new AssemblyReference();
+ assemRef.Version = new System.Version(arr.MajorVersion, arr.MinorVersion, arr.BuildNumber, arr.RevisionNumber);
+ assemRef.Flags = (AssemblyFlags)arr.Flags;
+ assemRef.PublicKeyOrToken = this.tables.GetBlob(arr.PublicKeyOrToken);
+ assemRef.Name = this.tables.GetString(arr.Name);
+ //if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assemRef.Name &&
+ // assemRef.Version > CoreSystemTypes.SystemAssembly.Version){
+ // HandleError(module, ExceptionStrings.ModuleOrAssemblyDependsOnMoreRecentVersionOfCoreLibrary);
+ //}
+ assemRef.Culture = this.tables.GetString(arr.Culture);
+ if (assemRef.Culture != null && assemRef.Culture.Length == 0) assemRef.Culture = null;
+ assemRef.HashValue = this.tables.GetBlob(arr.HashValue);
+ assemRef.Reader = this;
+ assems[i].AssemblyReference = assemRef;
+ assemblies.Add(assemRef);
+ }
+ }
+ private void ReadModuleReferences(Module/*!*/ module)
+ {
+ FileRow[] files = this.tables.FileTable;
+ ModuleRefRow[] modRefs = this.tables.ModuleRefTable;
+ int n = modRefs.Length;
+ ModuleReferenceList modules = module.ModuleReferences = new ModuleReferenceList(n);
+ for (int i = 0; i < n; i++)
+ {
+ Module mod;
+ int nameIndex = modRefs[i].Name;
+ string name = this.tables.GetString(nameIndex);
+ string dir = BetterPath.GetDirectoryName(this.module.Location);
+ string location = BetterPath.Combine(dir, name);
+ for (int j = 0, m = files == null ? 0 : files.Length; j < m; j++)
+ {
+ if (files[j].Name != nameIndex) continue;
+ if ((files[j].Flags & (int)FileFlags.ContainsNoMetaData) == 0)
+ mod = Module.GetModule(location, this.doNotLockFile, this.getDebugSymbols, false);
+ else
+ mod = null;
+ if (mod == null)
+ {
+ mod = new Module();
+ mod.Name = name;
+ mod.Location = location;
+ mod.Kind = ModuleKindFlags.UnmanagedDynamicallyLinkedLibrary;
+ }
+ mod.HashValue = this.tables.GetBlob(files[j].HashValue);
+ mod.ContainingAssembly = module.ContainingAssembly;
+ modRefs[i].Module = mod;
+ modules.Add(new ModuleReference(name, mod));
+ goto nextModRef;
+ }
+ mod = new Module();
+ mod.Name = name;
+ mod.Kind = ModuleKindFlags.UnmanagedDynamicallyLinkedLibrary;
+ if (System.IO.File.Exists(location)) mod.Location = location;
+ mod.ContainingAssembly = module.ContainingAssembly;
+ modRefs[i].Module = mod;
+ modules.Add(new ModuleReference(name, mod));
+ nextModRef: ;
+ }
+ }
+ private static string ReadSerString(MemoryCursor/*!*/ sigReader)
+ {
+ int n = sigReader.ReadCompressedInt();
+ if (n < 0) return null;
+ return sigReader.ReadUTF8(n);
+ }
+ private void AddFieldsToType(TypeNode/*!*/ type, FieldRow[]/*!*/ fieldDefs, FieldPtrRow[]/*!*/ fieldPtrs, int start, int end)
+ {
+ for (int i = start; i < end; i++)
+ {
+ int ii = i;
+ if (fieldPtrs.Length > 0) ii = fieldPtrs[i - 1].Field;
+ Field field = this.GetFieldFromDef(ii, type);
+ if (field != null) type.Members.Add(field);
+ }
+ }
+ private void GetUnderlyingTypeOfEnumNode(EnumNode /*!*/enumNode, FieldRow[]/*!*/ fieldDefs, FieldPtrRow[]/*!*/ fieldPtrs, int start, int end)
+ {
+ TypeNode underlyingType = null;
+ for (int i = start; i < end; i++)
+ {
+ int ii = i;
+ if (fieldPtrs.Length > 0) ii = fieldPtrs[i - 1].Field;
+ FieldRow fld = fieldDefs[ii - 1];
+ if (fld.Field != null && !fld.Field.IsStatic)
+ {
+ underlyingType = fld.Field.Type;
+ break;
+ }
+ FieldFlags fieldFlags = (FieldFlags)fld.Flags;
+ if ((fieldFlags & FieldFlags.Static) == 0)
+ {
+ this.tables.GetSignatureLength(fld.Signature);
+ MemoryCursor sigReader = this.tables.GetNewCursor();
+ GetAndCheckSignatureToken(6, sigReader);
+ underlyingType = this.ParseTypeSignature(sigReader);
+ break;
+ }
+ }
+ enumNode.underlyingType = underlyingType;
+ }
+ private void AddMethodsToType(TypeNode/*!*/ type, MethodPtrRow[]/*!*/ methodPtrs, int start, int end)
+ //^ requires type.members != null;
+ {
+ for (int i = start; i < end; i++)
+ {
+ int ii = i;
+ if (methodPtrs.Length > 0) ii = methodPtrs[i - 1].Method;
+ Method method = this.GetMethodFromDef(ii, type);
+ if (method != null && ((method.Flags & MethodFlags.RTSpecialName) == 0 || method.Name.UniqueIdKey != StandardIds._Deleted.UniqueIdKey))
+ type.members.Add(method);
+ }
+ }
+ private void AddMoreStuffToParameters(Method method, ParameterList parameters, int start, int end)
+ {
+ ParamRow[] pars = this.tables.ParamTable;
+ int n = parameters == null ? 0 : parameters.Count;
+ for (int i = start; i < end; i++)
+ {
+ ParamRow pr = pars[i - 1];
+ if (pr.Sequence == 0 && method != null)
+ {
+ //The parameter entry with sequence 0 is used as a target for custom attributes that apply to the return value
+ method.ReturnAttributes = this.GetCustomAttributesFor((i << 5) | 4);
+ if ((pr.Flags & (int)ParameterFlags.HasFieldMarshal) != 0)
+ method.ReturnTypeMarshallingInformation = this.GetMarshallingInformation((i << 1) | 1);
+ this.AddMoreStuffToParameters(null, parameters, start + 1, end);
+ return;
+ }
+ int j = pr.Sequence;
+ if (j < 1 || j > n) continue; //Bad metadata, ignore
+ if (parameters == null) continue;
+ Parameter par = parameters[j - 1];
+ par.Attributes = this.GetCustomAttributesFor((i << 5) | 4);
+ par.Flags = (ParameterFlags)pr.Flags;
+ if ((par.Flags & ParameterFlags.HasDefault) != 0)
+ par.DefaultValue = this.GetLiteral((i << 2) | 1, par.Type);
+ if ((par.Flags & ParameterFlags.HasFieldMarshal) != 0)
+ par.MarshallingInformation = this.GetMarshallingInformation((i << 1) | 1);
+ par.Name = tables.GetIdentifier(pr.Name);
+#if ExtendedRuntime
+ for (int k = 0, al = par.Attributes == null ? 0 : par.Attributes.Count; k < al; k++) {
+ if (par.Attributes[k].Type == ExtendedRuntimeTypes.NotNullAttribute) {
+ Reference r = par.Type as Reference;
+ if (r != null){
+ // need to make it a reference to a non-null type and not a non-null wrapper around the reference
+ // also *must* make it a new Reference.
+ OptionalModifier om = OptionalModifier.For(ExtendedRuntimeTypes.NonNullType, r.ElementType);
+ par.Type = om.GetReferenceType();
+ }else{
+ par.Type = OptionalModifier.For(ExtendedRuntimeTypes.NonNullType, par.Type);
+ }
+ // Someone putting an attribute directly on the "real" method is still a
+ // kind of out-of-band contract.
+ // This marking is the way to signal that any override or implementing method being compiled
+ // should not have its non-null annotations persisted as optional modifiers.
+ par.DeclaringMethod.HasOutOfBandContract = true;
+ break;
+ }
+ }
+#endif
+ }
+ }
+ private void AddPropertiesToType(TypeNode/*!*/ type, PropertyRow[]/*!*/ propertyDefs, PropertyPtrRow[]/*!*/ propertyPtrs, int start, int end)
+ //requires type.members != null;
+ {
+ MetadataReader tables = this.tables;
+ for (int i = start; i < end; i++)
+ {
+ int ii = i;
+ if (propertyPtrs.Length > 0) ii = propertyPtrs[i - 1].Property;
+ PropertyRow prop = propertyDefs[ii - 1];
+ Property property = new Property();
+ property.Attributes = this.GetCustomAttributesFor((ii << 5) | 9);
+ property.DeclaringType = type;
+ property.Flags = (PropertyFlags)prop.Flags;
+ property.Name = tables.GetIdentifier(prop.Name);
+ if ((property.Flags & PropertyFlags.RTSpecialName) == 0 || property.Name.UniqueIdKey != StandardIds._Deleted.UniqueIdKey)
+ {
+ this.AddMethodsToProperty(ii, property);
+ type.members.Add(property);
+ }
+ //REVIEW: the signature seems to be redundant. Is there any point in retrieving it?
+ }
+ }
+ private void AddMethodsToProperty(int propIndex, Property/*!*/ property)
+ {
+ int codedPropIndex = (propIndex << 1) | 1;
+ MetadataReader tables = this.tables;
+ MethodRow[] methods = tables.MethodTable;
+ MethodSemanticsRow[] methodSemantics = tables.MethodSemanticsTable;
+ int i = 0, n = methodSemantics.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.MethodSemantics) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (methodSemantics[k].Association < codedPropIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && methodSemantics[i - 1].Association == codedPropIndex) i--;
+ }
+ for (; i < n; i++)
+ {
+ MethodSemanticsRow meth = methodSemantics[i];
+ Method propertyMethod = methods[meth.Method - 1].Method;
+ if (propertyMethod == null) continue;
+ if (meth.Association == codedPropIndex)
+ {
+ propertyMethod.DeclaringMember = property;
+ switch (meth.Semantics)
+ {
+ case 0x0001: property.Setter = propertyMethod; break;
+ case 0x0002: property.Getter = propertyMethod; break;
+ default:
+ if (property.OtherMethods == null) property.OtherMethods = new MethodList();
+ property.OtherMethods.Add(propertyMethod); break;
+ }
+ }
+ else if (sorted)
+ break;
+ }
+ }
+ private void AddEventsToType(TypeNode/*!*/ type, EventRow[]/*!*/ eventDefs, EventPtrRow[]/*!*/ eventPtrs, int start, int end)
+ {
+ MetadataReader tables = this.tables;
+ for (int i = start; i < end; i++)
+ {
+ int ii = i;
+ if (eventPtrs.Length > 0) ii = eventPtrs[i].Event;
+ EventRow ev = eventDefs[ii - 1];
+ Event evnt = new Event();
+ evnt.Attributes = this.GetCustomAttributesFor((ii << 5) | 10);
+ evnt.DeclaringType = type;
+ evnt.Flags = (EventFlags)ev.Flags;
+ evnt.HandlerType = this.DecodeAndGetTypeDefOrRefOrSpec(ev.EventType);
+ evnt.Name = tables.GetIdentifier(ev.Name);
+ if ((evnt.Flags & EventFlags.RTSpecialName) == 0 || evnt.Name.UniqueIdKey != StandardIds._Deleted.UniqueIdKey)
+ {
+ this.AddMethodsToEvent(ii, evnt);
+ type.Members.Add(evnt);
+ }
+ }
+ }
+ private void AddMethodsToEvent(int eventIndex, Event/*!*/ evnt)
+ {
+ int codedEventIndex = eventIndex << 1;
+ MetadataReader tables = this.tables;
+ MethodRow[] methods = tables.MethodTable;
+ MethodSemanticsRow[] methodSemantics = tables.MethodSemanticsTable;
+ int i = 0, n = methodSemantics.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.MethodSemantics) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (methodSemantics[k].Association < codedEventIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && methodSemantics[i - 1].Association == codedEventIndex) i--;
+ }
+ MethodFlags handlerFlags = (MethodFlags)0;
+ for (; i < n; i++)
+ {
+ MethodSemanticsRow meth = methodSemantics[i];
+ Method eventMethod = methods[meth.Method - 1].Method;
+ if (eventMethod == null) continue;
+ if (meth.Association == codedEventIndex)
+ {
+ eventMethod.DeclaringMember = evnt;
+ switch (meth.Semantics)
+ {
+ case 0x0008: evnt.HandlerAdder = eventMethod; handlerFlags = eventMethod.Flags; break;
+ case 0x0010: evnt.HandlerRemover = eventMethod; handlerFlags = eventMethod.Flags; break;
+ case 0x0020: evnt.HandlerCaller = eventMethod; break;
+ default:
+ if (evnt.OtherMethods == null) evnt.OtherMethods = new MethodList();
+ evnt.OtherMethods.Add(eventMethod); break;
+ }
+ }
+ else if (sorted)
+ break;
+ }
+ evnt.HandlerFlags = handlerFlags;
+ }
+ private bool TypeDefOrRefOrSpecIsClass(int codedIndex)
+ {
+ if (codedIndex == 0) return false;
+ switch (codedIndex & 0x3)
+ {
+ case 0x00: return this.TypeDefIsClass(codedIndex >> 2);
+ case 0x01: TypeNode t = this.GetTypeFromRef(codedIndex >> 2); return t is Class;
+ case 0x02: return this.TypeSpecIsClass(codedIndex >> 2);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadTypeDefOrRef);
+ }
+ private bool TypeDefOrRefOrSpecIsClassButNotValueTypeBaseClass(int codedIndex)
+ {
+ if (codedIndex == 0) return false;
+ switch (codedIndex & 0x3)
+ {
+ case 0x00: return this.TypeDefIsClassButNotValueTypeBaseClass(codedIndex >> 2);
+ case 0x01:
+ TypeNode t = this.GetTypeFromRef(codedIndex >> 2);
+ return t != CoreSystemTypes.ValueType && t != CoreSystemTypes.Enum && t is Class;
+ case 0x02: return this.TypeSpecIsClass(codedIndex >> 2);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadTypeDefOrRef);
+ }
+ private TypeNode DecodeAndGetTypeDefOrRefOrSpec(int codedIndex)
+ {
+ if (codedIndex == 0) return null;
+ switch (codedIndex & 0x3)
+ {
+ case 0x00: return this.GetTypeFromDef(codedIndex >> 2);
+ case 0x01: return this.GetTypeFromRef(codedIndex >> 2);
+ case 0x02: return this.GetTypeFromSpec(codedIndex >> 2);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadTypeDefOrRef);
+ }
+ private TypeNode DecodeAndGetTypeDefOrRefOrSpec(int codedIndex, bool expectStruct)
+ {
+ if (codedIndex == 0) return null;
+ switch (codedIndex & 0x3)
+ {
+ case 0x00: return this.GetTypeFromDef(codedIndex >> 2);
+ case 0x01: return this.GetTypeFromRef(codedIndex >> 2, expectStruct);
+ case 0x02: return this.GetTypeFromSpec(codedIndex >> 2);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadTypeDefOrRef);
+ }
+#if ExtendedRuntime
+ private Interface GetInterfaceIfNotGenericInstance(int codedIndex){
+ if (codedIndex == 0) return null;
+ switch(codedIndex & 0x3){
+ case 0x00 : return this.GetTypeFromDef(codedIndex >> 2) as Interface;
+ case 0x01 : return this.GetTypeFromRef(codedIndex >> 2, false) as Interface;
+ }
+ return null;
+ }
+#endif
+ private TypeNode GetTypeIfNotGenericInstance(int codedIndex)
+ {
+ if (codedIndex == 0) return null;
+ switch (codedIndex & 0x3)
+ {
+ case 0x00: return this.GetTypeFromDef(codedIndex >> 2);
+ case 0x01: return this.GetTypeFromRef(codedIndex >> 2, false);
+ }
+ return null;
+ }
+ internal AssemblyNode/*!*/ GetAssemblyFromReference(AssemblyReference/*!*/ assemblyReference)
+ {
+ lock (this)
+ {
+ if (SystemAssemblyLocation.ParsedAssembly != null && (assemblyReference.Name == "mscorlib" || assemblyReference.Name == "basetypes" || assemblyReference.Name == "ioconfig"
+ || assemblyReference.Name == "singularity.v1"))
+ return SystemAssemblyLocation.ParsedAssembly;
+ if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assemblyReference.Name) return CoreSystemTypes.SystemAssembly;
+ string strongName = null;
+ object cachedValue = null;
+ if (assemblyReference.PublicKeyOrToken == null || assemblyReference.PublicKeyOrToken.Length == 0)
+ {
+ if (assemblyReference.Location != null)
+ cachedValue = this.localAssemblyCache[assemblyReference.Location];
+ if (cachedValue == null)
+ {
+ cachedValue = this.localAssemblyCache[assemblyReference.Name];
+ if (cachedValue != null && assemblyReference.Location != null)
+ this.localAssemblyCache[assemblyReference.Location] = cachedValue;
+ }
+ }
+ else
+ {
+ strongName = assemblyReference.StrongName;
+ if (this.useStaticCache)
+ {
+ //See if reference is to an assembly that lives in the GAC.
+ if (assemblyReference.Location != null)
+ cachedValue = Reader.StaticAssemblyCache[assemblyReference.Location];
+ if (cachedValue == null)
+ cachedValue = Reader.StaticAssemblyCache[strongName];
+ }
+ if (cachedValue == null)
+ cachedValue = this.localAssemblyCache[strongName];
+ }
+ if (cachedValue == null)
+ {
+ //See if assembly is a platform assembly (and apply unification)
+ AssemblyReference aRef = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[Identifier.For(assemblyReference.Name).UniqueIdKey];
+ if (aRef != null && assemblyReference.Version != null && aRef.Version >= assemblyReference.Version && aRef.MatchesIgnoringVersion(assemblyReference))
+ {
+ AssemblyNode platformAssembly = aRef.assembly;
+ if (platformAssembly == null)
+ {
+ Debug.Assert(aRef.Location != null);
+ platformAssembly = AssemblyNode.GetAssembly(aRef.Location, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ }
+ if (platformAssembly != null)
+ {
+ if (strongName == null) strongName = assemblyReference.Name;
+ lock (Reader.StaticAssemblyCache)
+ {
+ if (aRef.Location != null)
+ Reader.StaticAssemblyCache[aRef.Location] = platformAssembly;
+ Reader.StaticAssemblyCache[strongName] = platformAssembly;
+ }
+ return aRef.assembly = platformAssembly;
+ }
+ }
+ }
+ AssemblyNode assembly = cachedValue as AssemblyNode;
+ if (assembly != null) goto done;
+
+ //No cached assembly and no cached reader for this assembly. Look for a resolver.
+ if (this.module != null)
+ {
+ assembly = this.module.Resolve(assemblyReference);
+ if (assembly != null)
+ {
+ if (strongName == null)
+ {
+ this.localAssemblyCache[assembly.Name] = assembly;
+ if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly;
+ }
+ else
+ {
+ if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly.Name == assembly.Name) return CoreSystemTypes.SystemAssembly;
+ lock (Reader.StaticAssemblyCache)
+ {
+ if (this.useStaticCache)
+ {
+ if (assembly.Location != null)
+ Reader.StaticAssemblyCache[assembly.Location] = assembly;
+ Reader.StaticAssemblyCache[strongName] = assembly;
+ }
+ else
+ {
+ this.localAssemblyCache[strongName] = assembly;
+ if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly;
+ }
+ }
+ }
+ goto done;
+ }
+ }
+
+ //Look for an assembly with the given name in the same directory as the referencing module
+ if (this.directory != null)
+ {
+ string fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".dll");
+ if (System.IO.File.Exists(fileName))
+ {
+ assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ if (strongName == null) goto cacheIt; //found something
+ //return assembly only if it matches the strong name of the reference
+ if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt;
+ }
+ }
+ fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".exe");
+ if (System.IO.File.Exists(fileName))
+ {
+ assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ if (strongName == null) goto cacheIt; //found something
+ //return assembly only if it matches the strong name of the reference
+ if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt;
+ }
+ }
+ fileName = System.IO.Path.Combine(this.directory, assemblyReference.Name + ".ill");
+ if (System.IO.File.Exists(fileName))
+ {
+ assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ if (strongName == null) goto cacheIt; //found something
+ //return assembly only if it matches the strong name of the reference
+ if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt;
+ }
+ }
+ }
+ //Look for an assembly in the same directory as the application using Reader.
+ {
+ string fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyReference.Name + ".dll");
+ if (System.IO.File.Exists(fileName))
+ {
+ assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ if (strongName == null) goto cacheIt; //found something
+ //return assembly only if it matches the strong name of the reference
+ if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt;
+ }
+ }
+ fileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assemblyReference.Name + ".exe");
+ if (System.IO.File.Exists(fileName))
+ {
+ assembly = AssemblyNode.GetAssembly(fileName, this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ if (strongName == null) goto cacheIt; //found something
+ //return assembly only if it matches the strong name of the reference
+ if (assemblyReference.Matches(assembly.Name, assembly.Version, assembly.Culture, assembly.PublicKeyToken)) goto cacheIt;
+ }
+ }
+ }
+ assembly = null;
+
+ //Probe the GAC
+#if FxCop
+ if(probeGAC){
+#endif
+ string gacLocation = null;
+ if (strongName != null)
+ {
+#if !ROTOR
+ //Look for the assembly in the system's Global Assembly Cache
+ gacLocation = GlobalAssemblyCache.GetLocation(assemblyReference);
+ if (gacLocation != null && gacLocation.Length == 0) gacLocation = null;
+#else
+ //TODO: look in the ROTOR GAC
+#endif
+ if (gacLocation != null)
+ {
+ assembly = AssemblyNode.GetAssembly(gacLocation, this.useStaticCache ? Reader.StaticAssemblyCache : this.localAssemblyCache, this.doNotLockFile, this.getDebugSymbols, this.useStaticCache);
+ if (assembly != null)
+ {
+ lock (Reader.StaticAssemblyCache)
+ {
+ if (this.useStaticCache)
+ {
+ Reader.StaticAssemblyCache[gacLocation] = assembly;
+ Reader.StaticAssemblyCache[strongName] = assembly;
+ }
+ else
+ {
+ this.localAssemblyCache[gacLocation] = assembly;
+ this.localAssemblyCache[strongName] = assembly;
+ }
+ }
+ }
+ }
+ }
+#if FxCop
+ }
+#endif
+ goto done;
+ cacheIt:
+ if (strongName == null)
+ {
+ this.localAssemblyCache[assembly.Name] = assembly;
+ if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly;
+ }
+ else
+ {
+ this.localAssemblyCache[strongName] = assembly;
+ if (assembly.Location != null) this.localAssemblyCache[assembly.Location] = assembly;
+ }
+ done:
+ if (assembly != null)
+ assembly.InitializeAssemblyReferenceResolution(this.module);
+ if (assembly == null)
+ {
+ if (this.module != null)
+ {
+ assembly = this.module.ResolveAfterProbingFailed(assemblyReference);
+ if (assembly != null) goto cacheIt;
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture, ExceptionStrings.AssemblyReferenceNotResolved, assemblyReference.StrongName));
+ }
+ assembly = new AssemblyNode();
+ assembly.Culture = assemblyReference.Culture;
+ assembly.Name = assemblyReference.Name;
+ assembly.PublicKeyOrToken = assemblyReference.PublicKeyOrToken;
+ assembly.Version = assemblyReference.Version;
+ assembly.Location = "unknown:location";
+ goto cacheIt;
+ }
+ return assembly;
+ }
+ }
+ private static void GetAndCheckSignatureToken(int expectedToken, MemoryCursor/*!*/ sigReader)
+ {
+ int tok = sigReader.ReadCompressedInt();
+ if (tok != expectedToken) throw new InvalidMetadataException(ExceptionStrings.MalformedSignature);
+ }
+ private Method GetConstructorDefOrRef(int codedIndex, out TypeNodeList varArgTypes)
+ {
+ varArgTypes = null;
+ switch (codedIndex & 0x7)
+ {
+ case 0x02: return this.GetMethodFromDef(codedIndex >> 3);
+ case 0x03: return (Method)this.GetMemberFromRef(codedIndex >> 3, out varArgTypes);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadCustomAttributeTypeEncodedToken);
+ }
+ private void GetResources(Module/*!*/ module)
+ {
+ ManifestResourceRow[] manifestResourceTable = this.tables.ManifestResourceTable;
+ int n = manifestResourceTable.Length;
+ ResourceList resources = new ResourceList(n);
+ for (int i = 0; i < n; i++)
+ {
+ ManifestResourceRow mrr = manifestResourceTable[i];
+ Resource r = new Resource();
+ r.Name = this.tables.GetString(mrr.Name);
+ r.IsPublic = (mrr.Flags & 7) == 1;
+ int impl = mrr.Implementation;
+ if (impl != 0)
+ {
+ switch (impl & 0x3)
+ {
+ case 0x0:
+ string modName = this.tables.GetString(this.tables.FileTable[(impl >> 2) - 1].Name);
+ if ((this.tables.FileTable[(impl >> 2) - 1].Flags & (int)FileFlags.ContainsNoMetaData) != 0)
+ {
+ r.DefiningModule = new Module();
+ r.DefiningModule.Directory = module.Directory;
+ r.DefiningModule.Location = Path.Combine(module.Directory, modName);
+ r.DefiningModule.Name = modName;
+ r.DefiningModule.Kind = ModuleKindFlags.ManifestResourceFile;
+ r.DefiningModule.ContainingAssembly = module.ContainingAssembly;
+ r.DefiningModule.HashValue = this.tables.GetBlob(this.tables.FileTable[(impl >> 2) - 1].HashValue);
+ }
+ else
+ {
+ string modLocation = modName;
+ r.DefiningModule = GetNestedModule(module, modName, ref modLocation);
+ }
+ break;
+ case 0x1:
+ r.DefiningModule = this.tables.AssemblyRefTable[(impl >> 2) - 1].AssemblyReference.Assembly;
+ break;
+ }
+ }
+ else
+ {
+ r.DefiningModule = module;
+ r.Data = this.tables.GetResourceData(mrr.Offset);
+ }
+ resources.Add(r);
+ }
+ module.Resources = resources;
+ module.Win32Resources = this.tables.ReadWin32Resources();
+ }
+ private SecurityAttribute GetSecurityAttribute(int i)
+ {
+ DeclSecurityRow dsr = this.tables.DeclSecurityTable[i];
+ SecurityAttribute attr = new SecurityAttribute();
+ attr.Action = (System.Security.Permissions.SecurityAction)dsr.Action;
+ if (this.module.MetadataFormatMajorVersion > 1 || this.module.MetadataFormatMinorVersion > 0)
+ {
+ attr.PermissionAttributes = this.GetPermissionAttributes(dsr.PermissionSet, attr.Action);
+ if (attr.PermissionAttributes != null) return attr;
+ }
+ attr.SerializedPermissions = (string)this.tables.GetBlobString(dsr.PermissionSet);
+ return attr;
+ }
+ private AttributeList GetPermissionAttributes(int blobIndex, System.Security.Permissions.SecurityAction action)
+ {
+ AttributeList result = new AttributeList();
+ int blobLength;
+ MemoryCursor sigReader = this.tables.GetBlobCursor(blobIndex, out blobLength);
+ if (blobLength == 0) return null;
+ byte header = sigReader.ReadByte();
+ if (header != (byte)'*')
+ {
+ if (header == (byte)'<') return null;
+ if (header == (byte)'.') return this.GetPermissionAttributes2(blobIndex, action);
+ HandleError(this.module, ExceptionStrings.BadSecurityPermissionSetBlob);
+ return null;
+ }
+ sigReader.ReadInt32(); //Skip over the token for the attribute target
+ sigReader.ReadInt32(); //Skip over the security action
+ int numAttrs = sigReader.ReadInt32();
+ for (int i = 0; i < numAttrs; i++)
+ result.Add(this.GetPermissionAttribute(sigReader));
+ return result;
+ }
+ private AttributeNode GetPermissionAttribute(MemoryCursor/*!*/ sigReader)
+ {
+ sigReader.ReadInt32(); //Skip over index
+ int typeNameLength = sigReader.ReadInt32();
+ sigReader.ReadUTF8(typeNameLength); //Skip over type name
+ int constructorToken = sigReader.ReadInt32();
+ sigReader.ReadInt32(); //Skip over attribute type token
+ sigReader.ReadInt32(); //Skip over assembly ref token
+ int caBlobLength = sigReader.ReadInt32();
+ sigReader.ReadInt32(); //Skip over the number of parameters in the CA blob
+ TypeNodeList varArgTypes; //Ignored because vararg constructors are not allowed in Custom Attributes
+ Method cons = this.GetConstructorDefOrRef(constructorToken, out varArgTypes);
+ if (cons == null) cons = new Method();
+ return this.GetCustomAttribute(cons, sigReader, caBlobLength);
+ }
+ private AttributeList GetPermissionAttributes2(int blobIndex, System.Security.Permissions.SecurityAction action)
+ {
+ AttributeList result = new AttributeList();
+ int blobLength;
+ MemoryCursor sigReader = this.tables.GetBlobCursor(blobIndex, out blobLength);
+ if (blobLength == 0) return null;
+ byte header = sigReader.ReadByte();
+ if (header != (byte)'.')
+ {
+ HandleError(this.module, ExceptionStrings.BadSecurityPermissionSetBlob);
+ return null;
+ }
+ int numAttrs = sigReader.ReadCompressedInt();
+ for (int i = 0; i < numAttrs; i++)
+ result.Add(this.GetPermissionAttribute2(sigReader, action));
+ return result;
+ }
+ private AttributeNode GetPermissionAttribute2(MemoryCursor/*!*/ sigReader, System.Security.Permissions.SecurityAction action)
+ {
+ int typeNameLength = sigReader.ReadCompressedInt();
+ string serializedTypeName = sigReader.ReadUTF8(typeNameLength);
+ TypeNode attrType = null;
+ try
+ {
+ attrType = this.GetTypeFromSerializedName(serializedTypeName);
+ }
+ catch (InvalidMetadataException) { }
+ if (attrType == null)
+ {
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture, ExceptionStrings.CouldNotResolveType, serializedTypeName));
+ return null;
+ }
+ InstanceInitializer cons = attrType.GetConstructor(CoreSystemTypes.SecurityAction);
+ if (cons == null)
+ {
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.SecurityAttributeTypeDoesNotHaveADefaultConstructor, serializedTypeName));
+ return null;
+ }
+ sigReader.ReadCompressedInt(); //caBlobLength
+ int numProps = sigReader.ReadCompressedInt(); //Skip over the number of properties in the CA blob
+ ExpressionList arguments = new ExpressionList(numProps + 1);
+ arguments.Add(new Literal(action, CoreSystemTypes.SecurityAction));
+ this.GetCustomAttributeNamedArguments(arguments, (ushort)numProps, sigReader);
+ return new AttributeNode(new MemberBinding(null, cons), arguments);
+ }
+ private static void HandleError(Module mod, string errorMessage)
+ {
+#if !FxCop
+ if (mod != null)
+ {
+ if (mod.MetadataImportErrors == null) mod.MetadataImportErrors = new ArrayList();
+ mod.MetadataImportErrors.Add(new InvalidMetadataException(errorMessage));
+ }
+#else
+ throw new InvalidMetadataException(String.Format(CultureInfo.CurrentCulture, ExceptionStrings.ModuleError, mod.Name, errorMessage));
+#endif
+ }
+ private AttributeNode GetCustomAttribute(int i)
+ {
+ CustomAttributeRow ca = this.tables.CustomAttributeTable[i];
+ TypeNodeList varArgTypes; //Ignored because vararg constructors are not allowed in Custom Attributes
+ Method cons = this.GetConstructorDefOrRef(ca.Constructor, out varArgTypes);
+ if (cons == null) cons = new Method();
+ int blobLength;
+ MemoryCursor sigReader = this.tables.GetBlobCursor(ca.Value, out blobLength);
+ return this.GetCustomAttribute(cons, sigReader, blobLength);
+ }
+ private AttributeNode GetCustomAttribute(Method/*!*/ cons, MemoryCursor/*!*/ sigReader, int blobLength)
+ {
+ AttributeNode attr = new AttributeNode();
+ attr.Constructor = new MemberBinding(null, cons);
+ int n = cons.Parameters == null ? 0 : cons.Parameters.Count;
+ ExpressionList arguments = attr.Expressions = new ExpressionList(n);
+ int posAtBlobStart = sigReader.Position;
+ sigReader.ReadUInt16(); //Prolog
+ for (int j = 0; j < n; j++)
+ {
+ TypeNode t = TypeNode.StripModifiers(cons.Parameters[j].Type);
+ if (t == null) continue;
+ TypeNode/*!*/ pt = t;
+ object val = null;
+ try
+ {
+ val = this.GetCustomAttributeLiteralValue(sigReader, ref pt);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+#else
+ }finally{}
+#endif
+ Literal lit = val as Literal;
+ if (lit == null) lit = new Literal(val, pt);
+ arguments.Add(lit);
+ }
+ if (sigReader.Position + 1 < posAtBlobStart + blobLength)
+ {
+ ushort numNamed = sigReader.ReadUInt16();
+ this.GetCustomAttributeNamedArguments(arguments, numNamed, sigReader);
+ }
+ return attr;
+ }
+ private void GetCustomAttributeNamedArguments(ExpressionList/*!*/ arguments, ushort numNamed, MemoryCursor/*!*/ sigReader)
+ {
+ for (int j = 0; j < numNamed; j++)
+ {
+ int nameTag = sigReader.ReadByte();
+ bool mustBox = sigReader.Byte(0) == (byte)ElementType.BoxedEnum;
+ TypeNode/*!*/ vType = this.ParseTypeSignature(sigReader);
+ Identifier id = sigReader.ReadIdentifierFromSerString();
+ object val = this.GetCustomAttributeLiteralValue(sigReader, ref vType);
+ Literal lit = val as Literal;
+ if (lit == null) lit = new Literal(val, vType);
+ NamedArgument narg = new NamedArgument(id, lit);
+ narg.Type = vType;
+ narg.IsCustomAttributeProperty = nameTag == 0x54;
+ narg.ValueIsBoxed = mustBox;
+ arguments.Add(narg);
+ }
+ }
+ private object GetCustomAttributeLiteralValue(MemoryCursor/*!*/ sigReader, TypeNode/*!*/ type)
+ {
+ TypeNode/*!*/ t = type;
+ object result = this.GetCustomAttributeLiteralValue(sigReader, ref t);
+ EnumNode enumType = t as EnumNode;
+ if (enumType != null && type == CoreSystemTypes.Object) result = new Literal(result, enumType);
+ return result;
+ }
+ private object GetCustomAttributeLiteralValue(MemoryCursor/*!*/ sigReader, ref TypeNode/*!*/ type)
+ {
+ if (type == null) return sigReader.ReadInt32();
+ switch (type.typeCode)
+ {
+ case ElementType.Boolean: return sigReader.ReadBoolean();
+ case ElementType.Char: return sigReader.ReadChar();
+ case ElementType.Double: return sigReader.ReadDouble();
+ case ElementType.Single: return sigReader.ReadSingle();
+ case ElementType.Int16: return sigReader.ReadInt16();
+ case ElementType.Int32: return sigReader.ReadInt32();
+ case ElementType.Int64: return sigReader.ReadInt64();
+ case ElementType.Int8: return sigReader.ReadSByte();
+ case ElementType.UInt16: return sigReader.ReadUInt16();
+ case ElementType.UInt32: return sigReader.ReadUInt32();
+ case ElementType.UInt64: return sigReader.ReadUInt64();
+ case ElementType.UInt8: return sigReader.ReadByte();
+ case ElementType.String: return ReadSerString(sigReader);
+ case ElementType.ValueType:
+ EnumNode etype = GetCustomAttributeEnumNode(ref type);
+ return this.GetCustomAttributeLiteralValue(sigReader, etype.UnderlyingType);
+ case ElementType.Class: return this.GetTypeFromSerializedName(ReadSerString(sigReader));
+ case ElementType.SzArray:
+ int numElems = sigReader.ReadInt32();
+ TypeNode elemType = ((ArrayType)type).ElementType;
+ return this.GetCustomAttributeLiteralArray(sigReader, numElems, elemType);
+ case ElementType.Object:
+ {
+ type = this.ParseTypeSignature(sigReader);
+ return this.GetCustomAttributeLiteralValue(sigReader, ref type);
+ }
+ }
+ throw new InvalidMetadataException(ExceptionStrings.UnexpectedTypeInCustomAttribute);
+ }
+ private static EnumNode/*!*/ GetCustomAttributeEnumNode(ref TypeNode/*!*/ type)
+ {
+ EnumNode etype = ((TypeNode)type) as EnumNode;
+ if (etype == null || etype.UnderlyingType == null)
+ {
+ //Happens when type is declared in a assembly that has not been resolved. In that case only the type name
+ //and the fact that it is a value type is known. There is no completely safe recovery from it, but at this point we
+ //can fake up an enum with Int32 as underlying type. This works in most situations.
+ etype = new EnumNode();
+ etype.Name = type.Name;
+ etype.Namespace = type.Namespace;
+ etype.DeclaringModule = type.DeclaringModule;
+ etype.UnderlyingType = CoreSystemTypes.Int32;
+ type = etype;
+ }
+ return etype;
+ }
+ private Array GetCustomAttributeLiteralArray(MemoryCursor/*!*/ sigReader, int numElems, TypeNode/*!*/ elemType)
+ {
+ Array array = this.ConstructCustomAttributeLiteralArray(numElems, elemType);
+ for (int i = 0; i < numElems; i++)
+ {
+ object elem = this.GetCustomAttributeLiteralValue(sigReader, elemType);
+ array.SetValue(elem, i);
+ }
+ return array;
+ }
+ private Array ConstructCustomAttributeLiteralArray(int numElems, TypeNode/*!*/ elemType)
+ {
+ if (numElems == -1) return null;
+ if (numElems < 0) throw new InvalidMetadataException(ExceptionStrings.UnexpectedTypeInCustomAttribute);
+ switch (elemType.typeCode)
+ {
+ case ElementType.Boolean: return new Boolean[numElems];
+ case ElementType.Char: return new Char[numElems];
+ case ElementType.Double: return new Double[numElems];
+ case ElementType.Single: return new Single[numElems];
+ case ElementType.Int16: return new Int16[numElems];
+ case ElementType.Int32: return new Int32[numElems];
+ case ElementType.Int64: return new Int64[numElems];
+ case ElementType.Int8: return new SByte[numElems];
+ case ElementType.UInt16: return new UInt16[numElems];
+ case ElementType.UInt32: return new UInt32[numElems];
+ case ElementType.UInt64: return new UInt64[numElems];
+ case ElementType.UInt8: return new Byte[numElems];
+ case ElementType.String: return new String[numElems];
+ // Only enum value types are legal in attribute instances as stated in section 17.1.3 of the C# 1.0 spec
+ case ElementType.ValueType:
+ TypeNode/*!*/ elType = elemType;
+ EnumNode eType = GetCustomAttributeEnumNode(ref elType);
+ return this.ConstructCustomAttributeLiteralArray(numElems, eType.UnderlyingType);
+ // This needs to be a TypeNode since GetCustomAttributeLiteralValue will return a Struct if the Type is a value type
+ case ElementType.Class: return new TypeNode[numElems];
+ // REVIEW: Is this the right exception? Is this the right exception string?
+ // Multi-dimensional arrays are not legal in attribute instances according section 17.1.3 of the C# 1.0 spec
+ case ElementType.SzArray: throw new InvalidMetadataException(ExceptionStrings.BadCustomAttributeTypeEncodedToken);
+ case ElementType.Object: return new Object[numElems];
+ }
+ throw new InvalidMetadataException(ExceptionStrings.UnexpectedTypeInCustomAttribute);
+ }
+ //TODO: rewrite this entire mess using a proper grammar based parser
+ private TypeNode/*!*/ GetTypeFromSerializedName(string serializedName)
+ {
+ if (serializedName == null) return null;
+ string assemblyName = null;
+ string typeName = serializedName;
+ int firstComma = FindFirstCommaOutsideBrackets(serializedName);
+ if (firstComma > 0)
+ {
+ int i = 1;
+ while (firstComma + i < serializedName.Length && serializedName[firstComma + i] == ' ') i++;
+ assemblyName = serializedName.Substring(firstComma + i);
+ typeName = serializedName.Substring(0, firstComma);
+ }
+ return this.GetTypeFromSerializedName(typeName, assemblyName);
+ }
+ private static int FindFirstCommaOutsideBrackets(string/*!*/ serializedName)
+ {
+ int numBrackets = 0;
+ int numAngles = 0;
+ for (int i = 0, n = serializedName == null ? 0 : serializedName.Length; i < n; i++)
+ {
+ char ch = serializedName[i];
+ if (ch == '[')
+ numBrackets++;
+ else if (ch == ']')
+ {
+ if (--numBrackets < 0) return -1;
+ }
+ else if (ch == '<')
+ numAngles++;
+ else if (ch == '>')
+ {
+ if (--numAngles < 0) return -1;
+ }
+ else if (ch == ',' && numBrackets == 0 && numAngles == 0)
+ return i;
+ }
+ return -1;
+ }
+ private TypeNode/*!*/ GetTypeFromSerializedName(string/*!*/ typeName, string assemblyName)
+ {
+ string/*!*/ nspace, name;
+ int i;
+ ParseTypeName(typeName, out nspace, out name, out i);
+ Module tMod = null;
+ TypeNode t = this.LookupType(nspace, name, assemblyName, out tMod);
+ if (t == null)
+ {
+ if (i < typeName.Length && typeName[i] == '!')
+ {
+ int codedIndex = 0;
+ if (PlatformHelpers.TryParseInt32(typeName.Substring(0, i), out codedIndex))
+ {
+ t = this.DecodeAndGetTypeDefOrRefOrSpec(codedIndex);
+ if (t != null) return t;
+ }
+ }
+ t = this.GetDummyTypeNode(Identifier.For(nspace), Identifier.For(name), tMod, null, false);
+ }
+ if (i >= typeName.Length) return t;
+ char ch = typeName[i];
+ if (ch == '+') return this.GetTypeFromSerializedName(typeName.Substring(i + 1), t);
+ if (ch == '&') return t.GetReferenceType();
+ if (ch == '*') return t.GetPointerType();
+ if (ch == '[') return this.ParseArrayOrGenericType(typeName.Substring(i + 1, typeName.Length - 1 - i), t);
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName);
+ }
+ private TypeNode/*!*/ GetTypeFromSerializedName(string/*!*/ typeName, TypeNode/*!*/ nestingType)
+ {
+ string/*!*/ name;
+ int i = 0;
+ ParseSimpleTypeName(typeName, out name, ref i);
+ TypeNode t = nestingType.GetNestedType(Identifier.For(name));
+ if (t == null)
+ t = this.GetDummyTypeNode(Identifier.Empty, Identifier.For(name), nestingType.DeclaringModule, nestingType, false);
+ if (i >= typeName.Length) return t;
+ char ch = typeName[i];
+ if (ch == '+') return this.GetTypeFromSerializedName(typeName.Substring(i + 1), t);
+ if (ch == '&') return t.GetReferenceType();
+ if (ch == '*') return t.GetPointerType();
+ if (ch == '[') return this.ParseArrayOrGenericType(typeName.Substring(i + 1, typeName.Length - 1 - i), t);
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName);
+ }
+ private TypeNode/*!*/ ParseArrayOrGenericType(string typeName, TypeNode/*!*/ rootType)
+ {
+ if (typeName == null || rootType == null) { Debug.Assert(false); return rootType; }
+ //Get here after "rootType[" has been parsed. What follows is either an array type specifier or some generic type arguments.
+ if (typeName.Length == 0)
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName); //Something ought to follow the [
+ if (typeName[0] == ']')
+ { //Single dimensional array with zero lower bound
+ if (typeName.Length == 1) return rootType.GetArrayType(1);
+ if (typeName[1] == '[' && typeName.Length > 2)
+ return this.ParseArrayOrGenericType(typeName.Substring(2), rootType.GetArrayType(1));
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName);
+ }
+ if (typeName[0] == '*')
+ { //Single dimensional array with unknown lower bound
+ if (typeName.Length > 1 && typeName[1] == ']')
+ {
+ if (typeName.Length == 2) return rootType.GetArrayType(1, true);
+ if (typeName[2] == '[' && typeName.Length > 3)
+ return this.ParseArrayOrGenericType(typeName.Substring(3), rootType.GetArrayType(1, true));
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName);
+ }
+ if (typeName[0] == ',')
+ { //Muti dimensional array
+ int rank = 1;
+ while (rank < typeName.Length && typeName[rank] == ',') rank++;
+ if (rank < typeName.Length && typeName[rank] == ']')
+ {
+ if (typeName.Length == rank + 1) return rootType.GetArrayType(rank + 1);
+ if (typeName[rank + 1] == '[' && typeName.Length > rank + 2)
+ return this.ParseArrayOrGenericType(typeName.Substring(rank + 2), rootType.GetArrayType(rank));
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadSerializedTypeName);
+ }
+ //Generic type instance
+ int offset = 0;
+ if (typeName[0] == '[') offset = 1; //Assembly qualified type name forming part of a generic parameter list
+ TypeNodeList arguments = new TypeNodeList();
+ int commaPos = FindFirstCommaOutsideBrackets(typeName);
+ while (commaPos > 1)
+ {
+ arguments.Add(this.GetTypeFromSerializedName(typeName.Substring(offset, commaPos - offset)));
+ typeName = typeName.Substring(commaPos + 1);
+ offset = typeName[0] == '[' ? 1 : 0;
+ commaPos = FindFirstCommaOutsideBrackets(typeName);
+ }
+ //Find the position of the first unbalanced ].
+ int lastCharPos = offset;
+ for (int leftBracketCount = 0; lastCharPos < typeName.Length; lastCharPos++)
+ {
+ char ch = typeName[lastCharPos];
+ if (ch == '[') leftBracketCount++;
+ else if (ch == ']')
+ {
+ leftBracketCount--;
+ if (leftBracketCount < 0) break;
+ }
+ }
+ arguments.Add(this.GetTypeFromSerializedName(typeName.Substring(offset, lastCharPos - offset)));
+ TypeNode retVal = rootType.GetGenericTemplateInstance(this.module, arguments);
+ if (lastCharPos + 1 < typeName.Length && typeName[lastCharPos + 1] == ']')
+ lastCharPos++;
+ if (lastCharPos + 1 < typeName.Length)
+ {
+ //The generic type is complete, but there is yet more to the type
+ char ch = typeName[lastCharPos + 1];
+ if (ch == '+') retVal = this.GetTypeFromSerializedName(typeName.Substring(lastCharPos + 2), retVal);
+ if (ch == '&') retVal = retVal.GetReferenceType();
+ if (ch == '*') retVal = retVal.GetPointerType();
+ if (ch == '[') retVal = this.ParseArrayOrGenericType(typeName.Substring(lastCharPos + 2, typeName.Length - 1 - lastCharPos - 1), retVal);
+ }
+ return retVal;
+ }
+ private static void ParseSimpleTypeName(string/*!*/ source, out string/*!*/ name, ref int i)
+ {
+ int n = source.Length;
+ int start = i;
+ for (; i < n; i++)
+ {
+ char ch = source[i];
+ if (ch == '\\') { i++; continue; }
+ if (ch == '.' || ch == '+' || ch == '&' || ch == '*' || ch == '[' || ch == '!') break;
+ if (ch == '<')
+ {
+ int unmatched = 1;
+ while (unmatched > 0 && ++i < n)
+ {
+ ch = source[i];
+ if (ch == '\\') i++;
+ else if (ch == '<') unmatched++;
+ else if (ch == '>') unmatched--;
+ }
+ }
+ }
+ if (i < n)
+ name = source.Substring(start, i - start);
+ else
+ name = source.Substring(start);
+ }
+ private static void ParseTypeName(string/*!*/ source, out string/*!*/ nspace, out string/*!*/ name, out int i)
+ {
+ i = 0;
+ int n = source.Length;
+ nspace = string.Empty;
+ while (true)
+ {
+ int start = i;
+ ParseSimpleTypeName(source, out name, ref i);
+ if (i < n && source[i] == '.') { i++; continue; }
+ if (start != 0) nspace = source.Substring(0, start - 1);
+ return;
+ }
+ }
+ private TypeNode LookupType(string/*!*/ nameSpace, string/*!*/ name, string assemblyName, out Module module)
+ {
+ Identifier namespaceId = Identifier.For(nameSpace);
+ Identifier nameId = Identifier.For(name);
+ module = this.module;
+ //^ assume module != null;
+ if (assemblyName == null)
+ {
+ TypeNode t = module.GetType(namespaceId, nameId);
+ if (t != null) return t;
+ module = CoreSystemTypes.SystemAssembly;
+ return CoreSystemTypes.SystemAssembly.GetType(namespaceId, nameId);
+ }
+ //See if the type is in one of the assemblies explcitly referenced by the current module
+ AssemblyReferenceList arefs = module.AssemblyReferences;
+ for (int i = 0, n = arefs == null ? 0 : arefs.Count; i < n; i++)
+ {
+ AssemblyReference aref = arefs[i];
+ if (aref != null && aref.StrongName == assemblyName && aref.Assembly != null)
+ {
+ module = aref.Assembly;
+ return aref.Assembly.GetType(namespaceId, nameId);
+ }
+ }
+ //Construct an assembly reference and probe for it
+ AssemblyReference aRef = new AssemblyReference(assemblyName);
+ AssemblyNode referringAssembly = this.module as AssemblyNode;
+ if (referringAssembly != null && (referringAssembly.Flags & AssemblyFlags.Retargetable) != 0)
+ aRef.Flags |= AssemblyFlags.Retargetable;
+ AssemblyNode aNode = this.GetAssemblyFromReference(aRef);
+ if (aNode != null)
+ {
+ module = aNode;
+ TypeNode result = aNode.GetType(namespaceId, nameId);
+ return result;
+ }
+ return null;
+ }
+ private void GetCustomAttributesFor(Module/*!*/ module)
+ {
+ try
+ {
+ if (this.tables.entryPointToken != 0)
+ module.EntryPoint = (Method)this.GetMemberFromToken(this.tables.entryPointToken);
+ else
+ module.EntryPoint = Module.NoSuchMethod;
+ if (module.NodeType == NodeType.Module)
+ {
+ module.Attributes = this.GetCustomAttributesFor((1 << 5) | 7);
+ return;
+ }
+ AssemblyNode assembly = (AssemblyNode)module;
+ assembly.SecurityAttributes = this.GetSecurityAttributesFor((1 << 2) | 2);
+ assembly.Attributes = this.GetCustomAttributesFor((1 << 5) | 14);
+ assembly.ModuleAttributes = this.GetCustomAttributesFor((1 << 5) | 7);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ module.Attributes = new AttributeList(0);
+ }
+#else
+ }finally{}
+#endif
+ }
+ private AttributeList/*!*/ GetCustomAttributesFor(int parentIndex)
+ {
+ CustomAttributeRow[] customAttributes = this.tables.CustomAttributeTable;
+ AttributeList attributes = new AttributeList();
+ try
+ {
+ int i = 0, n = customAttributes.Length, j = n - 1;
+ if (n == 0) return attributes;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.CustomAttribute) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (customAttributes[k].Parent < parentIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && customAttributes[i - 1].Parent == parentIndex) i--;
+ }
+ for (; i < n; i++)
+ if (customAttributes[i].Parent == parentIndex)
+ attributes.Add(this.GetCustomAttribute(i));
+ else if (sorted)
+ break;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return attributes;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+#else
+ }finally{}
+#endif
+ return attributes;
+ }
+ private SecurityAttributeList GetSecurityAttributesFor(int parentIndex)
+ {
+ DeclSecurityRow[] securityAttributes = this.tables.DeclSecurityTable;
+ SecurityAttributeList attributes = new SecurityAttributeList();
+ try
+ {
+ int i = 0, n = securityAttributes.Length, j = n - 1;
+ if (n == 0) return attributes;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.DeclSecurity) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (securityAttributes[k].Parent < parentIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && securityAttributes[i - 1].Parent == parentIndex) i--;
+ }
+ for (; i < n; i++)
+ if (securityAttributes[i].Parent == parentIndex)
+ attributes.Add(this.GetSecurityAttribute(i));
+ else if (sorted)
+ break;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return attributes;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+#else
+ }finally{}
+#endif
+ return attributes;
+ }
+ private void GetTypeParameterConstraints(int parentIndex, TypeNodeList parameters)
+ {
+ if (parameters == null) return;
+ GenericParamRow[] genericParameters = this.tables.GenericParamTable;
+ int i = 0, n = genericParameters.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.GenericParam) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (genericParameters[k].Owner < parentIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && genericParameters[i - 1].Owner == parentIndex) i--;
+ }
+ for (int k = 0; i < n && k < parameters.Count; i++, k++)
+ if (genericParameters[i].Owner == parentIndex)
+ {
+ TypeNode gp = parameters[k];
+ this.GetGenericParameterConstraints(i, ref gp);
+ parameters[k] = gp;
+ }
+ else if (sorted)
+ break;
+ }
+ private TypeNodeList GetTypeParametersFor(int parentIndex, Member parent)
+ {
+ GenericParamRow[] genericParameters = this.tables.GenericParamTable;
+ TypeNodeList types = new TypeNodeList();
+ int i = 0, n = genericParameters.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.GenericParam) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (genericParameters[k].Owner < parentIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && genericParameters[i - 1].Owner == parentIndex) i--;
+ }
+ for (int index = 0; i < n; i++, index++)
+ if (genericParameters[i].Owner == parentIndex)
+ types.Add(this.GetGenericParameter(i, index, parent));
+ else if (sorted)
+ break;
+ if (types.Count == 0) return null;
+ return types;
+ }
+ private TypeNode GetGenericParameter(int index, int parameterListIndex, Member parent)
+ {
+ GenericParamRow[] genericParameters = this.tables.GenericParamTable;
+ GenericParamRow gpr = genericParameters[index++];
+ string name = this.tables.GetString(gpr.Name);
+ GenericParamConstraintRow[] genericParameterConstraints = this.tables.GenericParamConstraintTable;
+ bool isClass = false;
+ int i = 0, n = genericParameterConstraints.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.GenericParamConstraint) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (genericParameterConstraints[k].Param < index)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && genericParameterConstraints[i - 1].Param == index) i--;
+ }
+ for (; i < n && !isClass; i++)
+ {
+ if (genericParameterConstraints[i].Param == index)
+ {
+ isClass = this.TypeDefOrRefOrSpecIsClass(genericParameterConstraints[i].Constraint);
+ }
+ else if (sorted)
+ break;
+ }
+ if (isClass)
+ {
+ ClassParameter cp = parent is Method ? new MethodClassParameter() : new ClassParameter();
+ cp.DeclaringMember = parent;
+ cp.ParameterListIndex = parameterListIndex;
+ cp.Name = Identifier.For(name);
+ cp.DeclaringModule = this.module;
+ cp.TypeParameterFlags = (TypeParameterFlags)gpr.Flags;
+ return cp;
+ }
+ TypeParameter tp = parent is Method ? new MethodTypeParameter() : new TypeParameter();
+ tp.DeclaringMember = parent;
+ tp.ParameterListIndex = parameterListIndex;
+ tp.Name = Identifier.For(name);
+ tp.DeclaringModule = this.module;
+ tp.TypeParameterFlags = (TypeParameterFlags)gpr.Flags;
+ return tp;
+ }
+ private void GetGenericParameterConstraints(int index, ref TypeNode/*!*/ parameter)
+ {
+ Debug.Assert(parameter != null);
+ index++;
+ GenericParamConstraintRow[] genericParameterConstraints = this.tables.GenericParamConstraintTable;
+ TypeNodeList constraints = new TypeNodeList();
+ Class baseClass = null;
+ InterfaceList interfaces = new InterfaceList();
+ int i = 0, n = genericParameterConstraints.Length, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.GenericParamConstraint) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (genericParameterConstraints[k].Param < index)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && genericParameterConstraints[i - 1].Param == index) i--;
+ }
+ for (; i < n; i++)
+ {
+ if (genericParameterConstraints[i].Param == index)
+ {
+ TypeNode t = this.DecodeAndGetTypeDefOrRefOrSpec(genericParameterConstraints[i].Constraint);
+ Class c = t as Class;
+ if (c != null)
+ baseClass = c;
+ else if (t is Interface)
+ interfaces.Add((Interface)t);
+ constraints.Add(t);
+ }
+ else if (sorted)
+ break;
+ }
+ ClassParameter cp = parameter as ClassParameter;
+ if (cp == null && baseClass != null)
+ {
+ cp = ((ITypeParameter)parameter).DeclaringMember is Method ? new MethodClassParameter() : new ClassParameter();
+ cp.Name = parameter.Name;
+ cp.DeclaringMember = ((ITypeParameter)parameter).DeclaringMember;
+ cp.ParameterListIndex = ((ITypeParameter)parameter).ParameterListIndex;
+ cp.DeclaringModule = this.module;
+ cp.TypeParameterFlags = ((ITypeParameter)parameter).TypeParameterFlags;
+ parameter = cp;
+ }
+ if (cp != null)
+ cp.structuralElementTypes = constraints;
+ else
+ ((TypeParameter)parameter).structuralElementTypes = constraints;
+ if (baseClass != null && cp != null) cp.BaseClass = baseClass;
+ parameter.Interfaces = interfaces;
+ }
+ internal static Block/*!*/ GetOrCreateBlock(TrivialHashtable/*!*/ blockMap, int address)
+ {
+ Block block = (Block)blockMap[address + 1];
+ if (block == null)
+ {
+ blockMap[address + 1] = block = new Block(new StatementList());
+#if !FxCop
+ block.SourceContext.StartPos = address;
+#else
+ block.ILOffset = address;
+#endif
+ }
+ return block;
+ }
+ internal Field GetFieldFromDef(int i)
+ {
+ return this.GetFieldFromDef(i, null);
+ }
+ internal Field GetFieldFromDef(int i, TypeNode declaringType)
+ {
+ FieldRow[] fieldDefs = this.tables.FieldTable;
+ FieldRow fld = fieldDefs[i - 1];
+ if (fld.Field != null) return fld.Field;
+ Field field = new Field();
+ fieldDefs[i - 1].Field = field;
+ field.Attributes = this.GetCustomAttributesFor((i << 5) | 1);
+ field.Flags = (FieldFlags)fld.Flags;
+ field.Name = tables.GetIdentifier(fld.Name);
+ if ((field.Flags & FieldFlags.RTSpecialName) != 0 && field.Name.UniqueIdKey == StandardIds._Deleted.UniqueIdKey) return null;
+ tables.GetSignatureLength(fld.Signature); //sigLength
+ MemoryCursor sigReader = this.tables.GetNewCursor();
+ GetAndCheckSignatureToken(6, sigReader);
+ field.Type = this.ParseTypeSignature(sigReader);
+ RequiredModifier reqMod = field.Type as RequiredModifier;
+ if (reqMod != null && reqMod.Modifier == CoreSystemTypes.IsVolatile)
+ {
+ field.IsVolatile = true;
+ field.Type = reqMod.ModifiedType;
+ }
+ if ((field.Flags & FieldFlags.HasDefault) != 0)
+ field.DefaultValue = this.GetLiteral(i << 2, field.Type);
+ if ((field.Flags & FieldFlags.HasFieldMarshal) != 0)
+ field.MarshallingInformation = this.GetMarshallingInformation((i << 1) | 0);
+ if ((field.Flags & FieldFlags.HasFieldRVA) != 0)
+ field.InitialData = this.GetInitialData(i, field.Type, out field.section);
+ if (declaringType == null)
+ {
+ TypeDefRow[] typeDefs = this.tables.TypeDefTable;
+ int indx = i;
+ FieldPtrRow[] fieldPtrs = this.tables.FieldPtrTable;
+ int n = fieldPtrs.Length;
+ for (int j = 0; j < n; j++)
+ {
+ if (fieldPtrs[j].Field == i)
+ {
+ indx = j + 1; break;
+ }
+ }
+ n = typeDefs.Length;
+ for (int j = n - 1; j >= 0; j--)
+ { //TODO: binary search
+ TypeDefRow tdr = typeDefs[j];
+ if (tdr.FieldList <= indx)
+ {
+ declaringType = this.GetTypeFromDef(j + 1);
+ break;
+ }
+ }
+ }
+ field.DeclaringType = declaringType;
+ if (declaringType != null && (declaringType.Flags & TypeFlags.ExplicitLayout) != 0)
+ {
+ FieldLayoutRow[] fieldLayouts = this.tables.FieldLayoutTable;
+ int n = fieldLayouts.Length;
+ for (int j = n - 1; j >= 0; j--)
+ { //TODO: binary search
+ FieldLayoutRow flr = fieldLayouts[j];
+ if (flr.Field == i)
+ {
+ field.Offset = flr.Offset;
+ break;
+ }
+ }
+ }
+ return field;
+ }
+ private byte[] GetInitialData(int fieldIndex, TypeNode fieldType, out PESection targetSection)
+ {
+ targetSection = PESection.Text;
+ FieldRvaRow[] fieldRvaTable = this.tables.FieldRvaTable;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.FieldRva) % 2 == 1;
+ int i = 0, n = fieldRvaTable.Length, j = n - 1;
+ if (n == 0) return null;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (fieldRvaTable[k].Field < fieldIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ }
+ else
+ for (; i < j; i++)
+ if (fieldRvaTable[i].Field == fieldIndex) break;
+ FieldRvaRow frr = fieldRvaTable[i];
+ if (frr.Field != fieldIndex) return null;
+ Field fld = this.tables.FieldTable[fieldIndex - 1].Field;
+ if (fld != null) fld.Offset = frr.RVA;
+ fieldType = TypeNode.StripModifiers(fieldType);
+ EnumNode enumType = fieldType as EnumNode;
+ if (enumType != null) fieldType = TypeNode.StripModifiers(enumType.UnderlyingType);
+ if (fieldType == null) { Debug.Fail(""); return null; }
+ int size = fieldType.ClassSize;
+ if (size <= 0)
+ {
+ switch (fieldType.typeCode)
+ {
+ case ElementType.Boolean: size = 1; break;
+ case ElementType.Char: size = 2; break;
+ case ElementType.Double: size = 8; break;
+ case ElementType.Int16: size = 2; break;
+ case ElementType.Int32: size = 4; break;
+ case ElementType.Int64: size = 8; break;
+ case ElementType.Int8: size = 1; break;
+ case ElementType.Single: size = 4; break;
+ case ElementType.UInt16: size = 2; break;
+ case ElementType.UInt32: size = 4; break;
+ case ElementType.UInt64: size = 8; break;
+ case ElementType.UInt8: size = 1; break;
+ default:
+ if (fieldType is Pointer || fieldType is FunctionPointer)
+ {
+ size = 4; break;
+ }
+ //TODO: this seems wrong
+ if (i < n - 1)
+ size = fieldRvaTable[i + 1].RVA - frr.RVA;
+ else if (targetSection != PESection.Text)
+ size = this.tables.GetOffsetToEndOfSection(frr.RVA);
+ break;
+ }
+ }
+ if (size <= 0) return null;
+ if (this.tables.NoOffsetFor(frr.RVA) || this.tables.NoOffsetFor(frr.RVA + size - 1))
+ return null;
+ MemoryCursor c = this.tables.GetNewCursor(frr.RVA, out targetSection);
+ byte[] result = new byte[size];
+ for (i = 0; i < size; i++)
+ result[i] = c.ReadByte();
+ return result;
+ }
+ private Literal GetLiteral(int parentCodedIndex, TypeNode/*!*/ type)
+ {
+ ConstantRow[] constants = this.tables.ConstantTable;
+ //TODO: do a binary search
+ for (int i = 0, n = constants.Length; i < n; i++)
+ {
+ if (constants[i].Parent != parentCodedIndex) continue;
+ object value = this.tables.GetValueFromBlob(constants[i].Type, constants[i].Value);
+ TypeCode valTypeCode = System.Convert.GetTypeCode(value);
+ TypeNode underlyingType = type;
+ if (type is EnumNode) underlyingType = ((EnumNode)type).UnderlyingType;
+ if (underlyingType.TypeCode != valTypeCode) type = CoreSystemTypes.Object;
+ if (type == CoreSystemTypes.Object && value != null)
+ {
+ switch (valTypeCode)
+ {
+ case TypeCode.Boolean: type = CoreSystemTypes.Boolean; break;
+ case TypeCode.Byte: type = CoreSystemTypes.UInt8; break;
+ case TypeCode.Char: type = CoreSystemTypes.Char; break;
+ case TypeCode.Double: type = CoreSystemTypes.Double; break;
+ case TypeCode.Int16: type = CoreSystemTypes.Int16; break;
+ case TypeCode.Int32: type = CoreSystemTypes.Int32; break;
+ case TypeCode.Int64: type = CoreSystemTypes.Int64; break;
+ case TypeCode.SByte: type = CoreSystemTypes.Int8; break;
+ case TypeCode.Single: type = CoreSystemTypes.Single; break;
+ case TypeCode.String: type = CoreSystemTypes.String; break;
+ case TypeCode.UInt16: type = CoreSystemTypes.UInt16; break;
+ case TypeCode.UInt32: type = CoreSystemTypes.UInt32; break;
+ case TypeCode.UInt64: type = CoreSystemTypes.UInt64; break;
+ case TypeCode.Empty:
+ case TypeCode.Object: type = CoreSystemTypes.Type; break;
+ }
+ }
+ return new Literal(value, type);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadConstantParentIndex);
+ }
+ internal FunctionPointer GetCalliSignature(int ssigToken)
+ {
+#if !FxCop
+ StandAloneSigRow ssr = this.tables.StandAloneSigTable[(ssigToken & 0xFFFFFF) - 1];
+#else
+ int index = (ssigToken & 0xFFFFFF) - 1;
+ if (index < 0 || index >= this.tables.StandAloneSigTable.Length)
+ return null;
+
+ StandAloneSigRow ssr = this.tables.StandAloneSigTable[index];
+#endif
+ MemoryCursor sigReader = this.tables.GetBlobCursor(ssr.Signature);
+ return this.ParseFunctionPointer(sigReader);
+ }
+ internal void GetLocals(int localIndex, LocalList/*!*/ locals, Hashtable/*!*/ localSourceNames)
+ {
+ if (localIndex == 0) return;
+ StandAloneSigRow ssr = this.tables.StandAloneSigTable[(localIndex & 0xFFFFFF) - 1];
+ this.tables.GetSignatureLength(ssr.Signature);
+ MemoryCursor sigReader = this.tables.GetNewCursor();
+ if (sigReader.ReadByte() != 0x7) throw new InvalidMetadataException(ExceptionStrings.InvalidLocalSignature);
+ int count = sigReader.ReadCompressedInt();
+ for (int i = 0; i < count; i++)
+ {
+ string lookupName = (string)localSourceNames[i];
+#if !FxCop
+ string name = lookupName == null ? "local" + i : lookupName;
+#else
+ string name = lookupName == null ? "local$"+i : lookupName;
+#endif
+ bool pinned = false;
+ TypeNode locType = this.ParseTypeSignature(sigReader, ref pinned);
+ Local loc = new Local(Identifier.For(name), locType);
+ loc.Pinned = pinned;
+ locals.Add(loc);
+ }
+ }
+#if !ROTOR && !UseSingularityPDB
+ internal void GetLocalSourceNames(ISymUnmanagedScope/*!*/ scope, Hashtable/*!*/ localSourceNames)
+ {
+ uint numLocals = scope.GetLocalCount();
+ IntPtr[] localPtrs = new IntPtr[numLocals];
+ scope.GetLocals((uint)localPtrs.Length, out numLocals, localPtrs);
+
+ char[] nameBuffer = new char[100];
+ uint nameLen;
+ for (int i = 0; i < numLocals; i++)
+ {
+ ISymUnmanagedVariable local =
+ (ISymUnmanagedVariable)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(localPtrs[i], typeof(ISymUnmanagedVariable));
+ if (local != null)
+ {
+ local.GetName((uint)nameBuffer.Length, out nameLen, nameBuffer);
+ int localIndex = (int)local.GetAddressField1();
+ localSourceNames[localIndex] = new String(nameBuffer, 0, (int)nameLen - 1);
+ System.Runtime.InteropServices.Marshal.ReleaseComObject(local);
+ }
+ System.Runtime.InteropServices.Marshal.Release(localPtrs[i]);
+ }
+
+ IntPtr[] subscopes = new IntPtr[100];
+ uint numScopes;
+ scope.GetChildren((uint)subscopes.Length, out numScopes, subscopes);
+ for (int i = 0; i < numScopes; i++)
+ {
+ ISymUnmanagedScope subscope =
+ (ISymUnmanagedScope)System.Runtime.InteropServices.Marshal.GetTypedObjectForIUnknown(subscopes[i], typeof(ISymUnmanagedScope));
+ if (subscope != null)
+ {
+ this.GetLocalSourceNames(subscope, localSourceNames);
+ System.Runtime.InteropServices.Marshal.ReleaseComObject(subscope);
+ }
+ System.Runtime.InteropServices.Marshal.Release(subscopes[i]);
+ //TODO: need to figure out how map these scope to blocks and set HasLocals on those blocks
+ }
+ }
+#endif
+ private MarshallingInformation GetMarshallingInformation(int parentCodedIndex)
+ {
+ FieldMarshalRow[] mtypes = this.tables.FieldMarshalTable;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.FieldMarshal) % 2 == 1;
+ int i = 0, n = mtypes.Length, j = n - 1;
+ if (n == 0) return null;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (mtypes[k].Parent < parentCodedIndex)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && mtypes[i - 1].Parent == parentCodedIndex) i--;
+ }
+ else
+ for (; i < j; i++)
+ if (mtypes[i].Parent == parentCodedIndex) break;
+ FieldMarshalRow fmr = mtypes[i];
+ if (fmr.Parent != parentCodedIndex) return null;
+ MarshallingInformation result = new MarshallingInformation();
+ int blobSize = 0;
+ MemoryCursor c = this.tables.GetBlobCursor(fmr.NativeType, out blobSize);
+ int initialPosition = c.Position;
+ result.NativeType = (NativeType)c.ReadByte();
+ if (result.NativeType == NativeType.CustomMarshaler)
+ {
+ c.ReadUInt16(); //Skip over 0
+ result.Class = ReadSerString(c);
+ result.Cookie = ReadSerString(c);
+ }
+ else if (blobSize > 1)
+ {
+ if (result.NativeType == NativeType.LPArray)
+ {
+ result.ElementType = (NativeType)c.ReadByte();
+ result.ParamIndex = -1;
+ int bytesRead = 2;
+ if (bytesRead < blobSize)
+ {
+ int pos = c.Position;
+ result.ParamIndex = c.ReadCompressedInt();
+ bytesRead += c.Position - pos;
+ if (bytesRead < blobSize)
+ {
+ pos = c.Position;
+ result.ElementSize = c.ReadCompressedInt();
+ bytesRead += c.Position - pos;
+ if (bytesRead < blobSize)
+ result.NumberOfElements = c.ReadCompressedInt();
+ }
+ }
+ }
+ else if (result.NativeType == NativeType.SafeArray)
+ {
+ result.ElementType = (NativeType)c.ReadByte(); //Actually a variant type. TODO: what about VT_VECTOR VT_ARRAY and VT_BYREF?
+ if (c.Position < initialPosition + blobSize - 1)
+ result.Class = ReadSerString(c);
+ }
+ else
+ {
+ result.Size = c.ReadCompressedInt();
+ if (result.NativeType == NativeType.ByValArray)
+ {
+ if (blobSize > 2)
+ result.ElementType = (NativeType)c.ReadByte();
+ else
+ result.ElementType = NativeType.NotSpecified;
+ }
+ }
+ }
+ return result;
+ }
+ private void GetMethodBody(Method/*!*/ method, object/*!*/ i, bool asInstructionList)
+ {
+ if (asInstructionList) { this.GetMethodInstructions(method, i); return; }
+ TypeNodeList savedCurrentMethodTypeParameters = this.currentMethodTypeParameters;
+ this.currentMethodTypeParameters = method.templateParameters;
+ TypeNode savedCurrentType = this.currentType;
+ this.currentType = method.DeclaringType;
+ try
+ {
+ MethodRow meth = this.tables.MethodTable[((int)i) - 1];
+ StatementList statements;
+ if (meth.RVA != 0 && (((MethodImplFlags)meth.ImplFlags) & MethodImplFlags.ManagedMask) == MethodImplFlags.Managed)
+ {
+ if (this.getDebugSymbols) this.GetMethodDebugSymbols(method, 0x6000000 | (uint)(int)i);
+ statements = this.ParseMethodBody(method, (int)i, meth.RVA);
+ }
+ else
+ statements = new StatementList(0);
+ method.Body = new Block(statements);
+#if FxCop
+ if (statements.Count > 0) {
+ SourceContext context = statements[0].SourceContext;
+ method.SourceContext = context;
+ method.Body.SourceContext = context;
+ }
+#endif
+#if !MinimalReader
+ method.Body.HasLocals = true;
+#endif
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ method.Body = new Block(new StatementList(0));
+#endif
+ }
+ finally
+ {
+ this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
+ this.currentType = savedCurrentType;
+ }
+ }
+ private void GetMethodDebugSymbols(Method/*!*/ method, uint methodToken)
+ //^ requires this.debugReader != null;
+ {
+#if UseSingularityPDB
+ PdbFunction pdbFunc = this.GetPdbFunction(methodToken);
+ if (pdbFunc != null)
+ method.RecordSequencePoints(pdbFunc);
+#elif !ROTOR
+ ISymUnmanagedMethod methodInfo = null;
+ try
+ {
+ try
+ {
+ this.debugReader.GetMethod(methodToken, ref methodInfo);
+ method.RecordSequencePoints(methodInfo);
+ }
+ catch (COMException)
+ {
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (System.Runtime.InteropServices.InvalidComObjectException) { }
+ }
+ finally
+ {
+ if (methodInfo != null)
+ Marshal.ReleaseComObject(methodInfo);
+ }
+#endif
+ }
+#if UseSingularityPDB
+ internal PdbFunction GetPdbFunction(uint methodToken) {
+ PdbFunction[] pdbFunctions = this.pdbFunctions;
+ int i = 0, n = pdbFunctions == null ? 0 : pdbFunctions.Length, j = n-1;
+ while (i < j) {
+ int k = (i+j) / 2;
+ if (pdbFunctions[k].token < methodToken)
+ i = k+1;
+ else
+ j = k;
+ }
+ while (i > 0 && pdbFunctions[i-1].token == methodToken) i--;
+ if (0 <= i && i < n && pdbFunctions[i].token == methodToken)
+ return pdbFunctions[i];
+ return null;
+ }
+#endif
+ private void GetMethodInstructions(Method/*!*/ method, object/*!*/ i)
+ {
+ TypeNodeList savedCurrentMethodTypeParameters = this.currentMethodTypeParameters;
+ this.currentMethodTypeParameters = method.templateParameters;
+ TypeNode savedCurrentType = this.currentType;
+ this.currentType = method.DeclaringType;
+ try
+ {
+ MethodRow meth = this.tables.MethodTable[((int)i) - 1];
+ if (meth.RVA != 0 && (((MethodImplFlags)meth.ImplFlags) & MethodImplFlags.ManagedMask) == MethodImplFlags.Managed)
+ {
+ if (this.getDebugSymbols) this.GetMethodDebugSymbols(method, 0x6000000 | (uint)(int)i);
+ method.Instructions = this.ParseMethodInstructions(method, (int)i, meth.RVA);
+ }
+ else
+ method.Instructions = new InstructionList(0);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ method.Instructions = new InstructionList(0);
+#endif
+ }
+ finally
+ {
+ this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
+ this.currentType = savedCurrentType;
+ }
+ }
+ private Method GetMethodDefOrRef(int codedIndex)
+ {
+ switch (codedIndex & 0x1)
+ {
+ case 0x00: return this.GetMethodFromDef(codedIndex >> 1);
+ case 0x01:
+ TypeNodeList varArgTypes;
+ return (Method)this.GetMemberFromRef(codedIndex >> 1, out varArgTypes);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadCustomAttributeTypeEncodedToken);
+ }
+ private Method GetMethodDefOrRef(int codedIndex, int numberOfGenericArguments)
+ {
+ switch (codedIndex & 0x1)
+ {
+ case 0x00: return this.GetMethodFromDef(codedIndex >> 1);
+ case 0x01:
+ TypeNodeList varArgTypes;
+ return (Method)this.GetMemberFromRef(codedIndex >> 1, out varArgTypes, numberOfGenericArguments);
+ }
+ throw new InvalidMetadataException(ExceptionStrings.BadCustomAttributeTypeEncodedToken);
+ }
+ internal Method/*!*/ GetMethodFromDef(int index)
+ {
+ return this.GetMethodFromDef(index, null);
+ }
+ internal Method/*!*/ GetMethodFromDef(int index, TypeNode declaringType)
+ {
+ TypeNodeList savedCurrentMethodTypeParameters = this.currentMethodTypeParameters;
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ MethodRow[] methodDefs = this.tables.MethodTable;
+ MethodRow meth = methodDefs[index - 1];
+ if (meth.Method != null) return meth.Method;
+ if (declaringType == null)
+ {
+ int indx = index;
+ MethodPtrRow[] methodPtrs = this.tables.MethodPtrTable;
+ int n = methodPtrs.Length, i = 0, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.MethodPtr) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (methodPtrs[k].Method < index)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && methodPtrs[i - 1].Method == index) i--;
+ }
+ for (; i < n; i++)
+ {
+ if (methodPtrs[i].Method == index)
+ {
+ indx = i + 1; break;
+ }
+ }
+ TypeDefRow[] typeDefs = this.tables.TypeDefTable;
+ n = typeDefs.Length; i = 0; j = n - 1;
+ sorted = (this.sortedTablesMask >> (int)TableIndices.TypeDef) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if (typeDefs[k].MethodList < indx)
+ i = k + 1;
+ else
+ j = k;
+ }
+ j = i;
+ while (j < n - 1 && typeDefs[j + 1].MethodList == indx) j++;
+ }
+ for (; j >= 0; j--)
+ {
+ if (typeDefs[j].MethodList <= indx)
+ {
+ declaringType = this.GetTypeFromDef(j + 1);
+ break;
+ }
+ }
+ }
+ Method.MethodBodyProvider provider = new Method.MethodBodyProvider(this.GetMethodBody);
+ Identifier name = tables.GetIdentifier(meth.Name);
+ Method method;
+ if ((((MethodFlags)meth.Flags) & MethodFlags.SpecialName) != 0 &&
+ (((MethodFlags)meth.Flags) & MethodFlags.SpecialName) != 0)
+ {
+ if (name.Name == ".ctor")
+ method = methodDefs[index - 1].Method = new InstanceInitializer(provider, index);
+ else if (name.Name == ".cctor")
+ method = methodDefs[index - 1].Method = new StaticInitializer(provider, index);
+ else
+ method = methodDefs[index - 1].Method = new Method(provider, index);
+ }
+ else
+ method = methodDefs[index - 1].Method = new Method(provider, index);
+ method.ProvideMethodAttributes = new Method.MethodAttributeProvider(this.GetMethodAttributes);
+ //method.Attributes = this.GetCustomAttributesFor((index << 5)|0); //TODO: get attributes lazily
+ method.Flags = (MethodFlags)meth.Flags;
+ method.ImplFlags = (MethodImplFlags)meth.ImplFlags;
+ method.Name = name;
+ if (declaringType != null && declaringType.IsGeneric)
+ {
+ if (declaringType.Template != null)
+ this.currentTypeParameters = declaringType.ConsolidatedTemplateArguments;
+ else
+ this.currentTypeParameters = declaringType.ConsolidatedTemplateParameters;
+ }
+
+ tables.GetSignatureLength(meth.Signature);
+ MemoryCursor sigReader = this.tables.GetNewCursor();
+ method.CallingConvention = (CallingConventionFlags)sigReader.ReadByte();
+ if (method.IsGeneric = (method.CallingConvention & CallingConventionFlags.Generic) != 0)
+ {
+ int numTemplateParameters = sigReader.ReadCompressedInt();
+ this.currentMethodTypeParameters = new TypeNodeList(numTemplateParameters);
+ this.currentMethodTypeParameters = method.TemplateParameters = this.GetTypeParametersFor((index << 1) | 1, method);
+ this.GetTypeParameterConstraints((index << 1) | 1, method.TemplateParameters);
+ }
+ int numParams = sigReader.ReadCompressedInt();
+ method.ReturnType = this.ParseTypeSignature(sigReader);
+ if (declaringType != null && declaringType.IsValueType)
+ method.ThisParameter = new This(declaringType.GetReferenceType());
+ else
+ method.ThisParameter = new This(declaringType);
+ ParameterList paramList = method.Parameters = new ParameterList(numParams);
+ if (numParams > 0)
+ {
+ int offset = method.IsStatic ? 0 : 1;
+ for (int i = 0; i < numParams; i++)
+ {
+ Parameter param = new Parameter();
+ param.ParameterListIndex = i;
+ param.ArgumentListIndex = i + offset;
+ param.Type = this.ParseTypeSignature(sigReader);
+ param.DeclaringMethod = method;
+ paramList.Add(param);
+ }
+ int end = this.tables.ParamTable.Length + 1;
+ if (index < methodDefs.Length) end = methodDefs[index].ParamList;
+ this.AddMoreStuffToParameters(method, paramList, meth.ParamList, end);
+ for (int i = 0; i < numParams; i++)
+ {
+ Parameter param = paramList[i];
+ if (param.Name == null)
+ param.Name = Identifier.For("param" + (i));
+ }
+ }
+ else if (method.ReturnType != CoreSystemTypes.Void)
+ {
+ //check for custom attributes and marshalling information on return value
+ int i = meth.ParamList;
+ ParamPtrRow[] parPtrs = this.tables.ParamPtrTable; //TODO: why use ParamPtrTable in the branch and not the one above? Factor this out.
+ ParamRow[] pars = this.tables.ParamTable;
+ int n = methodDefs.Length;
+ int m = pars.Length;
+ if (index < n) m = methodDefs[index].ParamList - 1;
+ if (parPtrs.Length > 0)
+ {
+ if (pars != null && 0 < i && i <= m)
+ {
+ int j = parPtrs[i - 1].Param;
+ ParamRow pr = pars[j - 1];
+ if (pr.Sequence == 0)
+ this.AddMoreStuffToParameters(method, null, j, j + 1);
+ }
+ }
+ else
+ {
+ if (pars != null && 0 < i && i <= m)
+ {
+ ParamRow pr = pars[i - 1];
+ if (pr.Sequence == 0)
+ this.AddMoreStuffToParameters(method, null, i, i + 1);
+ }
+ }
+ }
+#if ExtendedRuntime
+ for (int k = 0, al = method.ReturnAttributes == null ? 0 : method.ReturnAttributes.Count; k < al; k++) {
+ if (method.ReturnAttributes[k].Type == ExtendedRuntimeTypes.NotNullAttribute) {
+ method.ReturnType = OptionalModifier.For(ExtendedRuntimeTypes.NonNullType, method.ReturnType);
+ // Someone putting an attribute directly on the "real" method is still a
+ // kind of out-of-band contract.
+ // This marking is the way to signal that any override or implementing method being compiled
+ // should not have its non-null annotations persisted as optional modifiers.
+ method.HasOutOfBandContract = true;
+ break;
+ }
+ }
+#endif
+ //if ((method.Flags & MethodFlags.HasSecurity) != 0)
+ // method.SecurityAttributes = this.GetSecurityAttributesFor((index << 2)|1);
+ if ((method.Flags & MethodFlags.PInvokeImpl) != 0)
+ {
+ ImplMapRow[] implMaps = this.tables.ImplMapTable;
+ int n = implMaps.Length, i = 0, j = n - 1;
+ bool sorted = (this.sortedTablesMask >> (int)TableIndices.ImplMap) % 2 == 1;
+ if (sorted)
+ {
+ while (i < j)
+ {
+ int k = (i + j) / 2;
+ if ((implMaps[k].MemberForwarded >> 1) < index)
+ i = k + 1;
+ else
+ j = k;
+ }
+ while (i > 0 && (implMaps[i - 1].MemberForwarded >> 1) == index) i--;
+ }
+ for (; i < n; i++)
+ {
+ ImplMapRow imr = implMaps[i];
+ if (imr.MemberForwarded >> 1 == index)
+ {
+ method.PInvokeFlags = (PInvokeFlags)imr.MappingFlags;
+ method.PInvokeImportName = tables.GetString(imr.ImportName);
+ method.PInvokeModule = this.module.ModuleReferences[imr.ImportScope - 1].Module;
+ break;
+ }
+ }
+ }
+ method.DeclaringType = declaringType;
+ this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return method;
+ }
+ private void GetMethodAttributes(Method/*!*/ method, object/*!*/ handle)
+ {
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ TypeNodeList savedCurrentMethodTypeParameters = this.currentMethodTypeParameters;
+ try
+ {
+ MetadataReader tables = this.tables;
+ int index = (int)handle;
+ MethodRow[] methodDefs = tables.MethodTable;
+ int n = methodDefs.Length;
+ if (index < 1 || index > n)
+ throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ MethodRow md = methodDefs[index - 1];
+ if (method != md.Method) throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ //Get custom attributes
+ method.Attributes = this.GetCustomAttributesFor((index << 5) | 0);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
+ //Get security attributes
+ if ((method.Flags & MethodFlags.HasSecurity) != 0)
+ method.SecurityAttributes = this.GetSecurityAttributesFor((index << 2) | 1);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ method.Attributes = new AttributeList(0);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ this.currentMethodTypeParameters = savedCurrentMethodTypeParameters;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private Method/*!*/ GetMethodFromSpec(int i)
+ {
+ MethodSpecRow[] methodSpecs = this.tables.MethodSpecTable;
+ MethodSpecRow msr = methodSpecs[i - 1];
+ if (msr.InstantiatedMethod != null) return msr.InstantiatedMethod;
+ MemoryCursor sigReader = this.tables.GetBlobCursor(msr.Instantiation);
+ byte header = sigReader.ReadByte(); //skip over redundant header byte
+ Debug.Assert(header == 0x0a);
+ TypeNodeList templateArguments = this.ParseTypeList(sigReader);
+ Method template = this.GetMethodDefOrRef(msr.Method, templateArguments.Count);
+ if (template == null) return new Method();
+ if (template.TemplateParameters == null) return template; //Likely a dummy method
+ return template.GetTemplateInstance(this.currentType, templateArguments);
+ }
+ internal Member/*!*/ GetMemberFromToken(int tok)
+ {
+ TypeNodeList varArgTypes;
+ return this.GetMemberFromToken(tok, out varArgTypes);
+ }
+ internal Member/*!*/ GetMemberFromToken(int tok, out TypeNodeList varArgTypes)
+ {
+ varArgTypes = null;
+ Member member = null;
+ switch ((TableIndices)(tok >> 24))
+ {
+ case TableIndices.Field: member = this.GetFieldFromDef(tok & 0xFFFFFF); break;
+ case TableIndices.Method: member = this.GetMethodFromDef(tok & 0xFFFFFF); break;
+ case TableIndices.MemberRef: member = this.GetMemberFromRef(tok & 0xFFFFFF, out varArgTypes); break;
+ case TableIndices.TypeDef: member = this.GetTypeFromDef(tok & 0xFFFFFF); break;
+ case TableIndices.TypeRef: member = this.GetTypeFromRef(tok & 0xFFFFFF); break;
+ case TableIndices.TypeSpec: member = this.GetTypeFromSpec(tok & 0xFFFFFF); break;
+ case TableIndices.MethodSpec: member = this.GetMethodFromSpec(tok & 0xFFFFFF); break;
+ default: throw new InvalidMetadataException(ExceptionStrings.BadMemberToken);
+ }
+ if (member == null) throw new InvalidMetadataException(ExceptionStrings.BadMemberToken);
+ return member;
+ }
+ internal Member GetMemberFromRef(int i, out TypeNodeList varArgTypes)
+ {
+ return this.GetMemberFromRef(i, out varArgTypes, 0);
+ }
+ internal Member GetMemberFromRef(int i, out TypeNodeList varArgTypes, int numGenericArgs)
+ {
+ MemberRefRow mref = this.tables.MemberRefTable[i - 1];
+ if (mref.Member != null)
+ {
+ varArgTypes = mref.VarargTypes;
+ return mref.Member;
+ }
+ varArgTypes = null;
+ Member result = null;
+ int codedIndex = mref.Class;
+ if (codedIndex == 0) return null;
+ TypeNode parent = null;
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ switch (codedIndex & 0x7)
+ {
+ case 0x00: parent = this.GetTypeFromDef(codedIndex >> 3); break;
+ case 0x01: parent = this.GetTypeFromRef(codedIndex >> 3); break;
+ case 0x02: parent = this.GetTypeGlobalMemberContainerTypeFromModule(codedIndex >> 3); break;
+ case 0x03: result = this.GetMethodFromDef(codedIndex >> 3);
+ if ((((Method)result).CallingConvention & CallingConventionFlags.VarArg) != 0)
+ {
+ MemoryCursor sRdr = this.tables.GetBlobCursor(mref.Signature);
+ sRdr.ReadByte(); //hdr
+ int pCount = sRdr.ReadCompressedInt();
+ this.ParseTypeSignature(sRdr); //rType
+ bool genParameterEncountered = false;
+ this.ParseParameterTypes(out varArgTypes, sRdr, pCount, ref genParameterEncountered);
+ }
+ goto done;
+ case 0x04: parent = this.GetTypeFromSpec(codedIndex >> 3); break;
+ default: throw new InvalidMetadataException("");
+ }
+ if (parent != null && parent.IsGeneric)
+ {
+ if (parent.Template != null)
+ this.currentTypeParameters = parent.ConsolidatedTemplateArguments;
+ else
+ this.currentTypeParameters = parent.ConsolidatedTemplateParameters;
+ }
+ Identifier memberName = this.tables.GetIdentifier(mref.Name);
+ MemoryCursor sigReader = this.tables.GetBlobCursor(mref.Signature);
+ byte header = sigReader.ReadByte();
+ if (header == 0x6)
+ {
+ TypeNode fieldType = this.ParseTypeSignature(sigReader);
+ TypeNode fType = TypeNode.StripModifiers(fieldType);
+ TypeNode parnt = parent;
+ while (parnt != null)
+ {
+ MemberList members = parnt.GetMembersNamed(memberName);
+ for (int j = 0, n = members.Count; j < n; j++)
+ {
+ Field f = members[j] as Field;
+ if (f == null) continue;
+ if (TypeNode.StripModifiers(f.Type) == fType) { result = f; goto done; }
+ }
+ Class c = parnt as Class;
+ if (c != null) parnt = c.BaseClass; else break;
+ }
+ if (result == null)
+ {
+ result = new Field(memberName);
+ result.DeclaringType = parent;
+ ((Field)result).Type = fieldType;
+ goto error;
+ }
+ goto done;
+ }
+ int typeParamCount = int.MinValue;
+ CallingConventionFlags callingConvention = CallingConventionFlags.Default;
+ if ((header & 0x20) != 0) callingConvention |= CallingConventionFlags.HasThis;
+ if ((header & 0x40) != 0) callingConvention |= CallingConventionFlags.ExplicitThis;
+ switch (header & 7)
+ {
+ case 1: callingConvention |= CallingConventionFlags.C; break;
+ case 2: callingConvention |= CallingConventionFlags.StandardCall; break;
+ case 3: callingConvention |= CallingConventionFlags.ThisCall; break;
+ case 4: callingConvention |= CallingConventionFlags.FastCall; break;
+ case 5: callingConvention |= CallingConventionFlags.VarArg; break;
+ }
+ if ((header & 0x10) != 0)
+ {
+ typeParamCount = sigReader.ReadCompressedInt();
+ callingConvention |= CallingConventionFlags.Generic;
+ }
+ int paramCount = sigReader.ReadCompressedInt();
+ TypeNodeList savedMethodTypeParameters = this.currentMethodTypeParameters;
+ this.currentTypeParameters = parent.ConsolidatedTemplateArguments;
+ TypeNode pnt = parent;
+ if (numGenericArgs > 0)
+ {
+ while (pnt != null)
+ {
+ MemberList members = pnt.GetMembersNamed(memberName);
+ for (int k = 0, n = members.Count; k < n; k++)
+ {
+ Method m = members[k] as Method;
+ if (m == null) continue;
+ if (m.TemplateParameters == null || m.TemplateParameters.Count != numGenericArgs) continue;
+ if (m.Parameters == null || m.Parameters.Count != paramCount) continue;
+ this.currentMethodTypeParameters = m.TemplateParameters;
+ this.currentTypeParameters = pnt.ConsolidatedTemplateArguments;
+ goto parseSignature;
+ }
+ Class c = pnt as Class;
+ if (c != null) pnt = c.BaseClass; else break;
+ }
+ }
+ parseSignature:
+ TypeNode returnType = this.ParseTypeSignature(sigReader);
+ if (returnType == null) returnType = CoreSystemTypes.Object;
+ bool genericParameterEncountered = returnType.IsGeneric;
+ TypeNodeList paramTypes = this.ParseParameterTypes(out varArgTypes, sigReader, paramCount, ref genericParameterEncountered);
+ this.currentMethodTypeParameters = savedMethodTypeParameters;
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ pnt = parent;
+ while (pnt != null)
+ {
+ MemberList members = pnt.GetMembersNamed(memberName);
+ for (int k = 0, n = members.Count; k < n; k++)
+ {
+ Method m = members[k] as Method;
+ if (m == null) continue;
+ if (m.ReturnType == null) continue;
+ TypeNode mrtype = TypeNode.StripModifiers(m.ReturnType);
+ //^ assert mrtype != null;
+ if (!mrtype.IsStructurallyEquivalentTo(TypeNode.StripModifiers(returnType))) continue;
+ if (!m.ParameterTypesMatchStructurally(paramTypes)) continue;
+ if (m.CallingConvention != callingConvention) continue;
+ if (typeParamCount != int.MinValue && (!m.IsGeneric || m.TemplateParameters == null || m.TemplateParameters.Count != typeParamCount))
+ continue;
+ result = m;
+ goto done;
+ }
+ if (memberName.UniqueIdKey == StandardIds.Ctor.UniqueIdKey)
+ {
+ //Can't run up the base class chain for constructors.
+ members = pnt.GetConstructors();
+ if (members != null && members.Count == 1 && paramCount == 0)
+ {
+ //Only one constructor. The CLR metadata API's seem to think that this should match the empty signature
+ result = members[0];
+ goto done;
+ }
+ break;
+ }
+ Class c = pnt as Class;
+ if (c != null) pnt = c.BaseClass; else break;
+ }
+ if (result == null)
+ {
+ ParameterList parameters = new ParameterList(paramCount);
+ for (int j = 0; j < paramCount; j++)
+ {
+ Parameter p = new Parameter(Identifier.Empty, paramTypes[j]);
+ parameters.Add(p);
+ }
+ //TODO: let the caller indicate if it expects a constructor
+ Method meth = new Method(parent, null, memberName, parameters, returnType, null);
+ meth.CallingConvention = callingConvention;
+ if ((callingConvention & CallingConventionFlags.HasThis) == 0) meth.Flags |= MethodFlags.Static;
+ result = meth;
+ }
+ error:
+ if (this.module != null)
+ {
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CouldNotResolveMemberReference, parent.FullName + "::" + memberName));
+ if (parent != null) parent.Members.Add(result);
+ }
+ done:
+ if (Reader.CanCacheMember(result))
+ {
+ this.tables.MemberRefTable[i - 1].Member = result;
+ this.tables.MemberRefTable[i - 1].VarargTypes = varArgTypes;
+ }
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return result;
+ }
+ private static bool CanCacheMethodHelper(Method/*!*/ method)
+ {
+ if (method.IsGeneric)
+ {
+ if (method.TemplateArguments == null)
+ return false;
+ for (int i = 0; i < method.TemplateArguments.Count; i++)
+ if (!CanCacheTypeNode(method.TemplateArguments[i]))
+ return false;
+ }
+ return true;
+ }
+ private static bool CanCacheMember(Member/*!*/ member)
+ {
+ return (member.DeclaringType == null || CanCacheTypeNode(member.DeclaringType)) &&
+ (member.NodeType != NodeType.Method || CanCacheMethodHelper((Method)member));
+ }
+
+ private TypeNodeList/*!*/ ParseParameterTypes(out TypeNodeList varArgTypes, MemoryCursor/*!*/ sigReader, int paramCount, ref bool genericParameterEncountered)
+ {
+ varArgTypes = null;
+ TypeNodeList paramTypes = new TypeNodeList(paramCount);
+ for (int j = 0; j < paramCount; j++)
+ {
+ TypeNode paramType = this.ParseTypeSignature(sigReader);
+ if (paramType == null)
+ {
+ //got a sentinel
+ varArgTypes = new TypeNodeList(paramCount - j);
+ j--;
+ continue;
+ }
+ if (varArgTypes != null) { varArgTypes.Add(paramType); continue; }
+ if (paramType.IsGeneric) genericParameterEncountered = true;
+ paramTypes.Add(paramType);
+ }
+ return paramTypes;
+ }
+ private bool TypeDefIsClass(int i)
+ {
+ if (i == 0) return false;
+ TypeDefRow typeDef = this.tables.TypeDefTable[i - 1];
+ if (typeDef.Type != null) return typeDef.Type is Class;
+ if ((typeDef.Flags & (int)TypeFlags.Interface) != 0) return false;
+ return this.TypeDefOrRefOrSpecIsClassButNotValueTypeBaseClass(typeDef.Extends);
+ }
+ private bool TypeDefIsClassButNotValueTypeBaseClass(int i)
+ {
+ if (i == 0) return false;
+ TypeDefRow typeDef = this.tables.TypeDefTable[i - 1];
+ if (typeDef.Type != null) return typeDef.Type != CoreSystemTypes.ValueType && typeDef.Type != CoreSystemTypes.Enum && typeDef.Type is Class;
+ if ((typeDef.Flags & (int)TypeFlags.Interface) != 0) return false;
+ return this.TypeDefOrRefOrSpecIsClassButNotValueTypeBaseClass(typeDef.Extends);
+ }
+ internal TypeNodeList GetInstantiatedTypes()
+ {
+ TypeNodeList result = null;
+ TypeDefRow[] typeDefs = this.tables.TypeDefTable;
+ for (int i = 0, n = typeDefs.Length; i < n; i++)
+ {
+ TypeNode t = typeDefs[i].Type;
+ if (t == null) continue;
+ if (result == null) result = new TypeNodeList();
+ result.Add(t);
+ }
+ return result;
+ }
+ internal TypeNode/*!*/ GetTypeFromDef(int i)
+ {
+ TypeDefRow typeDef = this.tables.TypeDefTable[i - 1];
+ if (typeDef.Type != null) return typeDef.Type;
+ // Save current state because the helper might change it but this method must not.
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ TypeNode savedCurrentType = this.currentType;
+ try
+ {
+ return this.GetTypeFromDefHelper(i);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return new Class();
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ return new Class();
+#endif
+ }
+ finally
+ {
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ this.currentType = savedCurrentType;
+ }
+ }
+ internal TypeNode/*!*/ GetTypeFromDefHelper(int i)
+ {
+ // This is added to prevent loops.
+ // Check the code in GetTypeFromDef which checks != null before callig this function
+ this.tables.TypeDefTable[i - 1].Type = Class.Dummy;
+ TypeDefRow typeDef = this.tables.TypeDefTable[i - 1];
+ Identifier name = this.tables.GetIdentifier(typeDef.Name);
+ Identifier namesp = this.tables.GetIdentifier(typeDef.Namespace);
+ int firstInterfaceIndex;
+ int lastInterfaceIndex;
+ this.GetInterfaceIndices(i, out firstInterfaceIndex, out lastInterfaceIndex);
+ InterfaceList interfaces = new InterfaceList();
+ TypeNode result = this.ConstructCorrectTypeNodeSubclass(i, namesp, firstInterfaceIndex, lastInterfaceIndex,
+ (TypeFlags)typeDef.Flags, interfaces, typeDef.Extends,
+ name.UniqueIdKey == StandardIds.Enum.UniqueIdKey && namesp.UniqueIdKey == StandardIds.System.UniqueIdKey);
+ result.DeclaringModule = this.module;
+ result.Name = name;
+ result.Namespace = namesp;
+ TypeNodeList typeParameters = this.currentTypeParameters = this.GetTypeParametersFor((i << 1) | 0, result);
+ result.TemplateParameters = typeParameters;
+ result.IsGeneric = typeParameters != null;
+ this.tables.TypeDefTable[i - 1].Type = result;
+ this.currentType = result;
+ this.RemoveTypeParametersBelongToDeclaringType(i, ref typeParameters, result);
+ //Now that the type instance has been allocated, it is safe to get hold of things that could refer to this type.
+ if (result is Class && result.BaseType == null)
+ {
+ TypeNode baseType = this.DecodeAndGetTypeDefOrRefOrSpec(typeDef.Extends);
+ ((Class)result).BaseClass = baseType as Class;
+ if (baseType != null && !(baseType is Class) && this.module != null)
+ {
+ HandleError(this.module, ExceptionStrings.InvalidBaseClass);
+ }
+ }
+ if (result.IsGeneric)
+ this.GetTypeParameterConstraints((i << 1) | 0, typeParameters);
+ if (firstInterfaceIndex >= 0)
+ this.GetInterfaces(i, firstInterfaceIndex, interfaces);
+ if ((result.Flags & (TypeFlags.ExplicitLayout | TypeFlags.SequentialLayout)) != 0)
+ this.GetClassSizeAndPackingSize(i, result);
+ return result;
+ }
+
+ private void GetInterfaceIndices(int i, out int firstInterfaceIndex, out int lastInterfaceIndex)
+ {
+ firstInterfaceIndex = -1;
+ lastInterfaceIndex = -1;
+ InterfaceImplRow[] intfaces = this.tables.InterfaceImplTable;
+ //TODO: binary search
+ for (int j = 0, n = intfaces.Length; j < n; j++)
+ {
+ if (intfaces[j].Class != i) continue;
+ if (firstInterfaceIndex == -1)
+ firstInterfaceIndex = j;
+ lastInterfaceIndex = j;
+ }
+ }
+
+ private void GetClassSizeAndPackingSize(int i, TypeNode/*!*/ result)
+ {
+ ClassLayoutRow[] classLayouts = tables.ClassLayoutTable;
+ for (int j = 0, n = classLayouts.Length; j < n; j++)
+ { //TODO: binary search
+ ClassLayoutRow clr = classLayouts[j];
+ if (clr.Parent == i)
+ {
+ result.ClassSize = clr.ClassSize;
+ result.PackingSize = clr.PackingSize;
+ break;
+ }
+ }
+ }
+
+ private void GetInterfaces(int i, int firstInterfaceIndex, InterfaceList/*!*/ interfaces)
+ {
+ InterfaceImplRow[] intfaces = this.tables.InterfaceImplTable;
+ for (int j = firstInterfaceIndex, n = intfaces.Length; j < n; j++)
+ {
+ if (intfaces[j].Class != i) continue; //TODO: break if sorted
+ TypeNode ifaceT = this.DecodeAndGetTypeDefOrRefOrSpec(intfaces[j].Interface);
+ Interface iface = ifaceT as Interface;
+ if (iface == null)
+ {
+ iface = new Interface();
+ if (ifaceT != null)
+ {
+ iface.DeclaringModule = ifaceT.DeclaringModule;
+ iface.Namespace = ifaceT.Namespace;
+ iface.Name = ifaceT.Name;
+ }
+ }
+ interfaces.Add(iface);
+ }
+ }
+
+ private void RemoveTypeParametersBelongToDeclaringType(int i, ref TypeNodeList typeParameters, TypeNode/*!*/ type)
+ {
+ NestedClassRow[] nestedClasses = tables.NestedClassTable;
+ for (int j = 0, n = nestedClasses.Length; j < n; j++)
+ { //TODO: binary search
+ NestedClassRow ncr = nestedClasses[j];
+ if (ncr.NestedClass == i)
+ {
+ type.DeclaringType = this.GetTypeFromDef(ncr.EnclosingClass);
+ if (type.DeclaringType != null && type.DeclaringType.IsGeneric)
+ {
+ //remove type parameters that belong to declaring type from nested type's list
+ if (type.templateParameters != null)
+ {
+ int icount = GetInheritedTypeParameterCount(type);
+ int rcount = type.templateParameters.Count;
+ if (icount >= rcount)
+ type.templateParameters = null;
+ else
+ {
+ TypeNodeList tpars = new TypeNodeList(rcount - icount);
+ for (int k = icount; k < rcount; k++)
+ tpars.Add(type.templateParameters[k]);
+ type.templateParameters = tpars;
+ }
+ this.currentTypeParameters = typeParameters = type.ConsolidatedTemplateParameters;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private TypeNode/*!*/ ConstructCorrectTypeNodeSubclass(int i, Identifier/*!*/ namesp, int firstInterfaceIndex, int lastInterfaceIndex,
+ TypeFlags flags, InterfaceList interfaces, int baseTypeCodedIndex, bool isSystemEnum)
+ {
+ TypeNode result;
+ TypeNode.TypeAttributeProvider attributeProvider = new TypeNode.TypeAttributeProvider(this.GetTypeAttributes);
+ TypeNode.NestedTypeProvider nestedTypeProvider = new TypeNode.NestedTypeProvider(this.GetNestedTypes);
+ TypeNode.TypeMemberProvider memberProvider = new TypeNode.TypeMemberProvider(this.GetTypeMembers);
+ bool isTemplateParameter = false;
+#if ExtendedRuntime
+ InterfaceImplRow[] intfaces = this.tables.InterfaceImplTable;
+ Interface firstInterface = null;
+ Interface lastInterface = null;
+ if (firstInterfaceIndex >= 0){
+ firstInterface = this.GetInterfaceIfNotGenericInstance(intfaces[firstInterfaceIndex].Interface);
+ if (firstInterface != null){
+ lastInterface = this.GetInterfaceIfNotGenericInstance(intfaces[lastInterfaceIndex].Interface);
+ isTemplateParameter = CoreSystemTypes.IsInitialized && lastInterface != null && lastInterface == ExtendedRuntimeTypes.ITemplateParameter;
+ }
+ }
+#endif
+ if ((flags & TypeFlags.Interface) != 0)
+ {
+ if (isTemplateParameter)
+ result = new TypeParameter(interfaces, nestedTypeProvider, attributeProvider, memberProvider, i);
+ else
+ result = new Interface(interfaces, nestedTypeProvider, attributeProvider, memberProvider, i);
+ }
+ else if (isTemplateParameter)
+ {
+ result = new ClassParameter(nestedTypeProvider, attributeProvider, memberProvider, i);
+ }
+ else
+ {
+ result = null;
+ TypeNode baseClass = this.GetTypeIfNotGenericInstance(baseTypeCodedIndex);
+ if (baseClass != null)
+ {
+ if (baseClass == CoreSystemTypes.MulticastDelegate) //TODO: handle single cast delegates
+ result = new DelegateNode(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else if (baseClass == CoreSystemTypes.Enum)
+ result = new EnumNode(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else if (baseClass == CoreSystemTypes.ValueType &&
+ !(isSystemEnum && (flags & TypeFlags.Sealed) == 0))
+ {
+#if ExtendedRuntime
+ Struct st = null;
+ if (firstInterface != null){
+ if (namesp.UniqueIdKey == StandardIds.StructuralTypes.UniqueIdKey){
+ if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.TupleType)
+ st = new TupleType(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.TypeIntersection)
+ st = new TypeIntersection(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.TypeUnion)
+ st = new TypeUnion(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.ConstrainedType)
+ st = new ConstrainedType(nestedTypeProvider, attributeProvider, memberProvider, i);
+ else
+ st = new Struct(nestedTypeProvider, attributeProvider, memberProvider, i);
+ }
+ else if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.TypeAlias)
+ st = new TypeAlias(nestedTypeProvider, attributeProvider, memberProvider, i, false);
+ else if (CoreSystemTypes.IsInitialized && firstInterface == ExtendedRuntimeTypes.TypeDefinition)
+ st = new TypeAlias(nestedTypeProvider, attributeProvider, memberProvider, i, true);
+ }
+ if (st == null && lastInterface != null) {
+ result = this.GetTypeExtensionFromDef(nestedTypeProvider, attributeProvider, memberProvider, i, baseClass, lastInterface);
+ }
+ else {
+ result = st;
+ }
+ if (result == null)
+#endif
+ result = new Struct(nestedTypeProvider, attributeProvider, memberProvider, i);
+ }
+ }
+ if (result == null)
+ {
+#if ExtendedRuntime
+ if (lastInterface != null)
+ result = this.GetTypeExtensionFromDef(nestedTypeProvider, attributeProvider, memberProvider, i, baseClass, lastInterface);
+ if (result == null)
+#endif
+ result = new Class(nestedTypeProvider, attributeProvider, memberProvider, i);
+ }
+ }
+ result.Flags = flags;
+ result.Interfaces = interfaces;
+ return result;
+ }
+#if !MinimalReader
+ private TrivialHashtable/*<Ident,TypeExtensionProvider>*//*!*/ TypeExtensionTable = new TrivialHashtable();
+ delegate TypeNode TypeExtensionProvider(TypeNode.NestedTypeProvider nprovider, TypeNode.TypeAttributeProvider aprovider, TypeNode.TypeMemberProvider mprovider, TypeNode baseType, object handle);
+
+ private static TypeNode DummyTypeExtensionProvider(TypeNode.NestedTypeProvider nprovider, TypeNode.TypeAttributeProvider aprovider, TypeNode.TypeMemberProvider mprovider, TypeNode baseType, object handle)
+ {
+ return null;
+ }
+ private TypeExtensionProvider/*!*/ dummyTEProvider = new TypeExtensionProvider(DummyTypeExtensionProvider);
+
+ private TypeNode GetTypeExtensionFromDef(TypeNode.NestedTypeProvider nestedTypeProvider, TypeNode.TypeAttributeProvider attributeProvider, TypeNode.TypeMemberProvider memberProvider, object handle, TypeNode baseType, Interface/*!*/ lastInterface)
+ {
+ if (lastInterface.Namespace.UniqueIdKey == StandardIds.CciTypeExtensions.UniqueIdKey)
+ {
+ TypeExtensionProvider teprovider = (TypeExtensionProvider)TypeExtensionTable[lastInterface.Name.UniqueIdKey];
+ if (teprovider == null)
+ {
+ string loc = lastInterface.DeclaringModule.Location.ToLower(CultureInfo.InvariantCulture);
+ if (loc.EndsWith(".runtime.dll"))
+ {
+ loc = System.IO.Path.GetFileName(loc);
+ string compilerDllName = loc.Replace(".runtime.dll", "");
+ System.Reflection.Assembly rassem;
+ try
+ {
+ rassem = System.Reflection.Assembly.Load(compilerDllName);
+ }
+ catch
+ {
+ HandleError(this.module, string.Format(CultureInfo.CurrentCulture, ExceptionStrings.CannotLoadTypeExtension, lastInterface.FullName, compilerDllName));
+ goto ExtensionNotFound;
+ }
+ if (rassem == null) goto ExtensionNotFound;
+ System.Type tprov = rassem.GetType(StandardIds.CciTypeExtensions.Name + "." + lastInterface.Name.Name + "Provider");
+ if (tprov == null) goto ExtensionNotFound;
+ System.Reflection.MethodInfo providerMethod = tprov.GetMethod("For");
+ if (providerMethod == null) goto ExtensionNotFound;
+ teprovider = (TypeExtensionProvider)Delegate.CreateDelegate(typeof(TypeExtensionProvider), providerMethod);
+ ExtensionNotFound: ;
+ if (teprovider == null)
+ {
+ // install a not-found dummy provider
+ teprovider = this.dummyTEProvider;
+ }
+ TypeExtensionTable[lastInterface.Name.UniqueIdKey] = teprovider;
+ }
+ }
+ if (teprovider == null) return null;
+ return teprovider(nestedTypeProvider, attributeProvider, memberProvider, baseType, handle);
+ }
+ return null;
+ }
+#endif
+ private static int GetInheritedTypeParameterCount(TypeNode type)
+ {
+ if (type == null) return 0;
+ int n = 0;
+ type = type.DeclaringType;
+ while (type != null)
+ {
+ n += type.templateParameters == null ? 0 : type.templateParameters.Count;
+ type = type.DeclaringType;
+ }
+ return n;
+ }
+ private TypeNode/*!*/ GetTypeGlobalMemberContainerTypeFromModule(int i)
+ {
+ ModuleRefRow mr = this.tables.ModuleRefTable[i - 1];
+ Module mod = mr.Module;
+ TypeNode result = null;
+ if (mod != null && mod.Types != null && mod.Types.Count > 0)
+ result = mod.Types[0];
+ if (result != null) return result;
+ result = this.GetDummyTypeNode(Identifier.Empty, Identifier.For("<Module>"), mod, null, false);
+ if (mod != null) mod.Types = new TypeNodeList(result);
+ return result;
+ }
+ internal void GetNamespaces()
+ //^ ensures this.namespaceTable != null;
+ {
+ TypeDefRow[] typeDefs = this.tables.TypeDefTable;
+ int n = typeDefs.Length;
+ TrivialHashtable nsT = this.namespaceTable = new TrivialHashtable(n * 2);
+ TrivialHashtable nsFor = new TrivialHashtable();
+ NamespaceList nsL = this.namespaceList = new NamespaceList(n);
+ for (int i = 0; i < n; i++)
+ {
+ TypeDefRow typeDef = typeDefs[i];
+ TrivialHashtable ns = (TrivialHashtable)nsT[typeDef.NamespaceKey];
+ Namespace nSpace = (Namespace)nsFor[typeDef.NamespaceKey];
+ if (ns == null)
+ {
+ nsT[typeDef.NamespaceKey] = ns = new TrivialHashtable();
+ nsFor[typeDef.NamespaceKey] = nSpace = new Namespace(typeDef.NamespaceId);
+ nsL.Add(nSpace);
+ }
+ Debug.Assert(nSpace != null);
+ if ((typeDef.Flags & (int)TypeFlags.VisibilityMask) == 0)
+ ns[typeDef.NameKey] = i + 1;
+ else if ((typeDef.Flags & (int)TypeFlags.VisibilityMask) == 1)
+ {
+ nSpace.isPublic = true;
+ ns[typeDef.NameKey] = i + 1;
+ }
+ }
+ }
+ private TypeNode GetTypeFromName(Identifier/*!*/ Namespace, Identifier/*!*/ name)
+ {
+ try
+ {
+ if (this.namespaceTable == null) this.GetNamespaces();
+ //^ assert this.namespaceTable != null;
+ TrivialHashtable nsTable = (TrivialHashtable)this.namespaceTable[Namespace.UniqueIdKey];
+ if (nsTable == null) return this.GetForwardedTypeFromName(Namespace, name);
+ object ti = nsTable[name.UniqueIdKey];
+ if (ti == null) return this.GetForwardedTypeFromName(Namespace, name);
+ TypeNode t = this.GetTypeFromDef((int)ti);
+ return t;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return null;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ return null;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private TypeNode GetForwardedTypeFromName(Identifier/*!*/ Namespace, Identifier/*!*/ name)
+ {
+ ExportedTypeRow[] exportedTypes = this.tables.ExportedTypeTable;
+ for (int i = 0, n = exportedTypes == null ? 0 : exportedTypes.Length; i < n; i++)
+ {
+ ExportedTypeRow etr = exportedTypes[i];
+ if ((etr.Flags & (int)TypeFlags.Forwarder) == 0) continue;
+ if (this.tables.GetString(etr.TypeNamespace) != Namespace.Name ||
+ this.tables.GetString(etr.TypeName) != name.Name) continue;
+ int index = etr.Implementation >> 2;
+ AssemblyRefRow arr = this.tables.AssemblyRefTable[index - 1];
+ return arr.AssemblyReference.Assembly.GetType(Namespace, name);
+ }
+ return null;
+ }
+ internal bool IsValidTypeName(Identifier/*!*/ Namespace, Identifier/*!*/ name)
+ {
+ try
+ {
+ if (this.namespaceTable == null) this.GetNamespaces();
+ //^ assert this.namespaceTable != null;
+ TrivialHashtable nsTable = (TrivialHashtable)this.namespaceTable[Namespace.UniqueIdKey];
+ if (nsTable == null) return false;
+ return nsTable[name.UniqueIdKey] != null;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module == null) return false;
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ return false;
+ }
+#else
+ }finally{}
+#endif
+ }
+ internal TypeNode/*!*/ GetTypeFromRef(int i)
+ {
+ return this.GetTypeFromRef(i, false);
+ }
+ internal TypeNode/*!*/ GetTypeFromRef(int i, bool expectStruct)
+ {
+ TypeRefRow[] trtable = this.tables.TypeRefTable;
+ TypeRefRow trr = trtable[i - 1];
+ TypeNode result = trr.Type;
+ if (result != null) return result;
+ Identifier name = tables.GetIdentifier(trr.Name);
+ Identifier namesp = tables.GetIdentifier(trr.Namespace);
+ int resolutionScope = trr.ResolutionScope;
+ Module declaringModule = null;
+ TypeNode declaringType = null;
+ int index = resolutionScope >> 2;
+ switch (resolutionScope & 0x3)
+ {
+ case 0:
+ declaringModule = this.module;
+ //^ assume declaringModule != null;
+ result = declaringModule.GetType(namesp, name);
+ //REVIEW: deal with case where ref is in same (multi-module) assembly, but not the current module? index == 0
+ break;
+ case 1:
+ declaringModule = this.tables.ModuleRefTable[index - 1].Module;
+ if (declaringModule != null)
+ result = declaringModule.GetType(namesp, name);
+ break;
+ case 2:
+ declaringModule = this.tables.AssemblyRefTable[index - 1].AssemblyReference.Assembly;
+ if (declaringModule != null)
+ result = declaringModule.GetType(namesp, name);
+ break;
+ case 3:
+ declaringType = this.GetTypeFromRef(index);
+ declaringModule = declaringType.DeclaringModule;
+ if (namesp == null || namesp.length == 0)
+ result = (TypeNode)declaringType.GetMembersNamed(name)[0];
+ else
+ result = (TypeNode)declaringType.GetMembersNamed(Identifier.For(namesp.Name + "." + name.Name))[0];
+ break;
+ default:
+ declaringModule = this.module;
+ break;
+ }
+ if (result == null)
+ result = this.GetDummyTypeNode(namesp, name, declaringModule, declaringType, expectStruct);
+ trtable[i - 1].Type = result;
+ if (!Reader.CanCacheTypeNode(result))
+ trtable[i - 1].Type = null;
+ return result;
+ }
+ private TypeNode/*!*/ GetDummyTypeNode(Identifier namesp, Identifier name, Module declaringModule, TypeNode declaringType, bool expectStruct)
+ {
+ TypeNode result = null;
+ if (this.module != null)
+ {
+ string modName = declaringModule == null ? "" : declaringModule.Name == null ? "" : declaringModule.Name.ToString();
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture, ExceptionStrings.CouldNotResolveTypeReference,
+ "[" + modName + "]" + namesp + "." + name));
+ }
+ result = expectStruct ? (TypeNode)new Struct() : (TypeNode)new Class();
+ if (name != null && name.ToString().StartsWith("I") && name.ToString().Length > 1 && char.IsUpper(name.ToString()[1]))
+ result = new Interface();
+ result.Flags |= TypeFlags.Public;
+ result.Name = name;
+ result.Namespace = namesp;
+ if (declaringType != null)
+ {
+ result.DeclaringType = declaringType;
+ result.DeclaringType.DeclaringModule = declaringType.DeclaringModule;
+ declaringType.Members.Add(result);
+ }
+ else
+ {
+ if (declaringModule == null) declaringModule = this.module;
+ //^ assume declaringModule != null;
+ result.DeclaringModule = declaringModule;
+ if (declaringModule.types != null)
+ declaringModule.types.Add(result);
+ }
+ return result;
+ }
+ private bool TypeSpecIsClass(int i)
+ {
+ TypeSpecRow tsr = this.tables.TypeSpecTable[i - 1];
+ if (tsr.Type != null) return tsr.Type is Class;
+ this.tables.GetSignatureLength(tsr.Signature);
+ return this.TypeSignatureIsClass(this.tables.GetNewCursor());
+ }
+ internal TypeNode/*!*/ GetTypeFromSpec(int i)
+ {
+ TypeSpecRow tsr = this.tables.TypeSpecTable[i - 1];
+ if (tsr.Type != null) return tsr.Type;
+ this.tables.GetSignatureLength(tsr.Signature);
+ bool pinned = false;
+ bool isTypeArgument = false;
+ TypeNode result = this.ParseTypeSignature(this.tables.GetNewCursor(), ref pinned, ref isTypeArgument);
+ if (result == null) result = new Class();
+ //Get custom attributes
+ AttributeList attributes = this.GetCustomAttributesFor((i << 5) | 13);
+ if (attributes.Count > 0)
+ {
+ //Append attributes "inherited" from template to metadata attributes
+ AttributeList templAttributes = result.Attributes;
+ for (int j = 0, n = templAttributes == null ? 0 : templAttributes.Count; j < n; j++)
+ {
+ AttributeNode attr = result.Attributes[j];
+ if (attr == null) continue;
+ attributes.Add(attr);
+ }
+ result.Attributes = attributes;
+ }
+#if ExtendedRuntime
+ for (int j = 0, n = attributes.Count; j < n; j++) {
+ if (attributes[j].Type == SystemTypes.NotNullGenericArgumentsAttribute) {
+ Literal l = (Literal)attributes[j].Expressions[0];
+ string s = (string)l.Value;
+ TypeNodeList ts = new TypeNodeList(s.Length);
+ for (int k = 0, m = s.Length; k < m; k++) {
+ if (s[k] == '!')
+ ts.Add(OptionalModifier.For(ExtendedRuntimeTypes.NonNullType, result.ConsolidatedTemplateArguments[k]));
+ else
+ ts.Add(result.ConsolidatedTemplateArguments[k]);
+ }
+ result = result.Template.GetGenericTemplateInstance(this.module, ts);
+ //^ assume result != null;
+ }
+ }
+#endif
+ if (!isTypeArgument && Reader.CanCacheTypeNode(result))
+ this.tables.TypeSpecTable[i - 1].Type = result;
+ return result;
+ }
+ private static bool CanCacheTypeNode(TypeNode/*!*/ type)
+ {
+#if WHIDBEY
+ return !type.IsGeneric && (type.Template == null || !type.IsNotFullySpecialized) &&
+ type.NodeType != NodeType.TypeParameter && type.NodeType != NodeType.ClassParameter &&
+ type.NodeType != NodeType.InterfaceExpression;
+#else
+ return true;
+#endif
+ }
+ private static Module GetNestedModule(Module module, string modName, ref string modLocation)
+ {
+ if (module == null || modName == null) { Debug.Assert(false); return null; }
+ Module mod = module.GetNestedModule(modName);
+ if (mod == null)
+ {
+ if (module.Location != null)
+ modLocation = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(module.Location), modName);
+ if (modLocation != null && System.IO.File.Exists(modLocation))
+ {
+ mod = Module.GetModule(modLocation);
+ if (mod != null)
+ {
+ mod.ContainingAssembly = module.ContainingAssembly;
+ module.ModuleReferences.Add(new ModuleReference(modName, mod));
+ }
+ }
+ }
+ if (mod == null)
+ {
+ HandleError(module, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CouldNotFindReferencedModule, modLocation));
+ mod = new Module();
+ mod.Name = modName;
+ mod.ContainingAssembly = module.ContainingAssembly;
+ mod.Kind = ModuleKindFlags.DynamicallyLinkedLibrary;
+ }
+ return mod;
+ }
+ private void GetTypeList(Module/*!*/ module)
+ {
+ TypeNodeList types = new TypeNodeList();
+ TypeDefRow[] typeDefs = this.tables.TypeDefTable;
+ for (int i = 0, n = typeDefs.Length; i < n; i++)
+ {
+ TypeNode t = this.GetTypeFromDef(i + 1);
+ if (t != null && t.DeclaringType == null) types.Add(t);
+ }
+ module.Types = types;
+ AssemblyNode assem = module as AssemblyNode;
+ if (assem == null) return;
+ types = new TypeNodeList();
+ ExportedTypeRow[] exportedTypes = this.tables.ExportedTypeTable;
+ for (int i = 0, n = exportedTypes.Length; i < n; i++)
+ {
+ ExportedTypeRow etr = exportedTypes[i];
+ Identifier nameSpace = Identifier.For(this.tables.GetString(etr.TypeNamespace));
+ Identifier typeName = Identifier.For(this.tables.GetString(etr.TypeName));
+ TypeNode exportedType = null;
+ switch (etr.Implementation & 0x3)
+ {
+ case 0:
+ string modName = this.tables.GetString(this.tables.FileTable[(etr.Implementation >> 2) - 1].Name);
+ string modLocation = modName;
+ Module mod = GetNestedModule(assem, modName, ref modLocation);
+ if (mod == null) { Debug.Assert(false); break; }
+ exportedType = mod.GetType(nameSpace, typeName);
+ if (exportedType == null)
+ {
+ HandleError(assem, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CouldNotFindExportedTypeInModule, nameSpace + "." + typeName, modLocation));
+ exportedType = new Class();
+ exportedType.Name = typeName;
+ exportedType.Namespace = nameSpace;
+ exportedType.Flags = TypeFlags.Class | TypeFlags.Public;
+ exportedType.DeclaringModule = mod;
+ }
+ break;
+ case 1:
+ AssemblyReference aref = this.tables.AssemblyRefTable[(etr.Implementation >> 2) - 1].AssemblyReference;
+ if (aref == null)
+ {
+ HandleError(assem, ExceptionStrings.BadMetadataInExportTypeTableNoSuchAssemblyReference);
+ aref = new AssemblyReference("dummy assembly for bad reference");
+ }
+ AssemblyNode a = aref.Assembly;
+ if (a == null) { Debug.Assert(false); continue; }
+ exportedType = a.GetType(nameSpace, typeName);
+ if (exportedType == null)
+ {
+ HandleError(assem, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CouldNotFindExportedTypeInAssembly, nameSpace + "." + typeName, a.StrongName));
+ exportedType = new Class();
+ exportedType.Name = typeName;
+ exportedType.Namespace = nameSpace;
+ exportedType.Flags = TypeFlags.Class | TypeFlags.Public;
+ exportedType.DeclaringModule = a;
+ }
+ break;
+ case 2:
+ TypeNode parentType = types[(etr.Implementation >> 2) - 1];
+ if (parentType == null)
+ {
+ HandleError(assem, ExceptionStrings.BadMetadataInExportTypeTableNoSuchParentType);
+ parentType = new Class();
+ parentType.DeclaringModule = this.module;
+ parentType.Name = Identifier.For("Missing parent type");
+ }
+ exportedType = parentType.GetNestedType(typeName);
+ if (exportedType == null)
+ {
+ HandleError(assem, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CouldNotFindExportedNestedTypeInType, typeName, parentType.FullName));
+ exportedType = new Class();
+ exportedType.Name = typeName;
+ exportedType.Flags = TypeFlags.Class | TypeFlags.NestedPublic;
+ exportedType.DeclaringType = parentType;
+ exportedType.DeclaringModule = parentType.DeclaringModule;
+ }
+ break;
+ }
+ types.Add(exportedType);
+ }
+ assem.ExportedTypes = types;
+ }
+ private void GetNestedTypes(TypeNode/*!*/ type, object/*!*/ handle)
+ {
+ type.nestedTypes = null;
+ TypeNodeList result = new TypeNodeList();
+#if !FxCop
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+#endif
+ try
+ {
+ if (type.IsGeneric)
+ {
+ if (type.templateParameters == null) type.templateParameters = new TypeNodeList(0);
+ this.currentTypeParameters = type.ConsolidatedTemplateParameters;
+ }
+ this.currentType = type;
+ TypeNode declaringType = type.DeclaringType;
+ while (this.currentTypeParameters == null && declaringType != null)
+ {
+ if (declaringType.IsGeneric)
+ {
+ if (declaringType.templateParameters == null) declaringType.templateParameters = new TypeNodeList(0);
+ this.currentTypeParameters = declaringType.ConsolidatedTemplateParameters;
+ }
+ declaringType = declaringType.DeclaringType;
+ }
+ MetadataReader tables = this.tables;
+ int typeTableIndex = (int)handle;
+ TypeDefRow[] typeDefs = tables.TypeDefTable;
+ int n = typeDefs.Length;
+ if (typeTableIndex < 1 || typeTableIndex > n)
+ throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ NestedClassRow[] nestedClasses = tables.NestedClassTable;
+ n = nestedClasses.Length;
+ for (int i = 0; i < n; i++)
+ { //TODO: binary lookup
+ NestedClassRow ncr = nestedClasses[i];
+ if (ncr.EnclosingClass != typeTableIndex) continue;
+ TypeNode t = this.GetTypeFromDef(ncr.NestedClass);
+ if (t != null)
+ {
+ if (type.nestedTypes != null) return; //A recursive call to GetNestedTypes has already done the deed
+ t.DeclaringType = type;
+ if ((t.Flags & TypeFlags.RTSpecialName) == 0 || t.Name.UniqueIdKey != StandardIds._Deleted.UniqueIdKey)
+ result.Add(t);
+ }
+ else
+ {
+ throw new InvalidMetadataException("Invalid nested class row");
+ }
+ }
+ type.nestedTypes = result;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private void GetTypeMembers(TypeNode/*!*/ type, object/*!*/ handle)
+ {
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ try
+ {
+ MetadataReader tables = this.tables;
+ int typeTableIndex = (int)handle;
+ TypeDefRow[] typeDefs = tables.TypeDefTable;
+ FieldRow[] fieldDefs = tables.FieldTable;
+ FieldPtrRow[] fieldPtrs = tables.FieldPtrTable;
+ MethodRow[] methodDefs = tables.MethodTable;
+ MethodPtrRow[] methodPtrs = tables.MethodPtrTable;
+ EventMapRow[] eventMaps = tables.EventMapTable;
+ EventRow[] eventDefs = tables.EventTable;
+ EventPtrRow[] eventPtrs = tables.EventPtrTable;
+ MethodImplRow[] methodImpls = tables.MethodImplTable;
+ PropertyMapRow[] propertyMaps = tables.PropertyMapTable;
+ PropertyPtrRow[] propertyPtrs = tables.PropertyPtrTable;
+ PropertyRow[] propertyDefs = this.tables.PropertyTable;
+ NestedClassRow[] nestedClasses = tables.NestedClassTable;
+ int n = typeDefs.Length;
+ if (typeTableIndex < 1 || typeTableIndex > n)
+ throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ TypeDefRow td = typeDefs[typeTableIndex - 1];
+ if (type != td.Type) throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ //Get type members
+ if (type.IsGeneric)
+ {
+ if (type.templateParameters == null) type.templateParameters = new TypeNodeList(0);
+ this.currentTypeParameters = type.ConsolidatedTemplateParameters;
+ }
+ this.currentType = type;
+ TypeNode declaringType = type.DeclaringType;
+ while (this.currentTypeParameters == null && declaringType != null)
+ {
+ if (declaringType.IsGeneric)
+ {
+ if (declaringType.templateParameters == null) declaringType.templateParameters = new TypeNodeList(0);
+ this.currentTypeParameters = declaringType.ConsolidatedTemplateParameters;
+ }
+ declaringType = declaringType.DeclaringType;
+ }
+ type.members = new MemberList();
+ n = nestedClasses.Length;
+ for (int i = 0; i < n; i++)
+ {
+ NestedClassRow ncr = nestedClasses[i];
+ if (ncr.EnclosingClass != typeTableIndex) continue;
+ TypeNode t = this.GetTypeFromDef(ncr.NestedClass);
+ if (t != null)
+ {
+ t.DeclaringType = type;
+ if ((t.Flags & TypeFlags.RTSpecialName) == 0 || t.Name.UniqueIdKey != StandardIds._Deleted.UniqueIdKey)
+ type.Members.Add(t);
+ }
+ }
+ n = typeDefs.Length;
+ int m = fieldDefs.Length;
+ int start = td.FieldList;
+ int end = m + 1; if (typeTableIndex < n) end = typeDefs[typeTableIndex].FieldList;
+ if (type is EnumNode) this.GetUnderlyingTypeOfEnumNode((EnumNode)type, fieldDefs, fieldPtrs, start, end);
+ this.AddFieldsToType(type, fieldDefs, fieldPtrs, start, end);
+ m = methodDefs.Length;
+ start = td.MethodList;
+ end = m + 1; if (typeTableIndex < n) end = typeDefs[typeTableIndex].MethodList;
+ this.AddMethodsToType(type, methodPtrs, start, end);
+ n = propertyMaps.Length;
+ m = propertyDefs.Length;
+ for (int i = 0; i < n; i++)
+ { //TODO: binary search
+ PropertyMapRow pm = propertyMaps[i];
+ if (pm.Parent != typeTableIndex) continue;
+ start = pm.PropertyList;
+ end = m + 1; if (i < n - 1) end = propertyMaps[i + 1].PropertyList;
+ this.AddPropertiesToType(type, propertyDefs, propertyPtrs, start, end);
+ }
+ n = eventMaps.Length;
+ m = eventDefs.Length;
+ for (int i = 0; i < n; i++)
+ { //TODO: binary search
+ EventMapRow em = eventMaps[i];
+ if (em.Parent != typeTableIndex) continue;
+ start = em.EventList;
+ end = m + 1; if (i < n - 1) end = eventMaps[i + 1].EventList;
+ this.AddEventsToType(type, eventDefs, eventPtrs, start, end);
+ }
+ n = methodImpls.Length;
+ for (int i = 0; i < n; i++)
+ { //TODO: binary search
+ MethodImplRow mir = methodImpls[i];
+ if (mir.Class != typeTableIndex) continue;
+ Method implementer = this.GetMethodDefOrRef(mir.MethodBody);
+ if (implementer == null) continue;
+ MethodList implementedInterfaceMethods = implementer.ImplementedInterfaceMethods;
+ if (implementedInterfaceMethods == null)
+ implementedInterfaceMethods = implementer.ImplementedInterfaceMethods = new MethodList();
+ TypeNodeList savedMethodTypeParameters = this.currentMethodTypeParameters;
+ this.currentMethodTypeParameters = implementer.TemplateParameters;
+ implementedInterfaceMethods.Add(this.GetMethodDefOrRef(mir.MethodDeclaration));
+ this.currentMethodTypeParameters = savedMethodTypeParameters;
+ }
+ this.currentTypeParameters = savedCurrentTypeParameters;
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ type.Members = new MemberList(0);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private void GetTypeAttributes(TypeNode/*!*/ type, object/*!*/ handle)
+ {
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ try
+ {
+ MetadataReader tables = this.tables;
+ int typeTableIndex = (int)handle;
+ TypeDefRow[] typeDefs = tables.TypeDefTable;
+ int n = typeDefs.Length;
+ if (typeTableIndex < 1 || typeTableIndex > n)
+ throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ TypeDefRow td = typeDefs[typeTableIndex - 1];
+ if (type != td.Type) throw new System.ArgumentOutOfRangeException("handle", ExceptionStrings.InvalidTypeTableIndex);
+ //Get custom attributes
+ type.Attributes = this.GetCustomAttributesFor((typeTableIndex << 5) | 3);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ //Get security attributes
+ if ((type.Flags & TypeFlags.HasSecurity) != 0)
+ type.SecurityAttributes = this.GetSecurityAttributesFor((typeTableIndex << 2) | 0);
+#if !FxCop
+ }
+ catch (Exception e)
+ {
+ if (this.module != null)
+ {
+ if (this.module.MetadataImportErrors == null) this.module.MetadataImportErrors = new ArrayList();
+ this.module.MetadataImportErrors.Add(e);
+ }
+ type.Attributes = new AttributeList(0);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ }
+#else
+ }finally{}
+#endif
+ }
+ private TypeNodeList/*!*/ ParseTypeList(MemoryCursor/*!*/ sigReader)
+ {
+ int n = sigReader.ReadCompressedInt();
+ TypeNodeList result = new TypeNodeList(n);
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.ParseTypeSignature(sigReader);
+ if (t == null || t == Struct.Dummy)
+ {
+ //Can happen when dealing with a primitive type that implements an interface that references the primitive type.
+ //For example, System.String implements IComparable<System.String>.
+ if (this.currentType != null && !CoreSystemTypes.Initialized)
+ t = this.currentType;
+ else
+ {
+ Debug.Assert(false);
+ t = new TypeParameter();
+ t.Name = Identifier.For("Bad type parameter in position " + i);
+ t.DeclaringModule = this.module;
+ }
+ }
+ result.Add(t);
+ }
+ return result;
+ }
+ private bool TypeSignatureIsClass(MemoryCursor/*!*/ sigReader)
+ {
+ ElementType tok = (ElementType)sigReader.ReadCompressedInt();
+ switch (tok)
+ {
+ case ElementType.Pinned:
+ case ElementType.Pointer:
+ case ElementType.Reference:
+ return this.TypeSignatureIsClass(sigReader);
+ case ElementType.OptionalModifier:
+ case ElementType.RequiredModifier:
+ sigReader.ReadCompressedInt();
+ return this.TypeSignatureIsClass(sigReader);
+ case ElementType.Class:
+ return true;
+ case ElementType.GenericTypeInstance:
+ return this.TypeSignatureIsClass(sigReader);
+ case ElementType.TypeParameter:
+ {
+ int pnum = sigReader.ReadCompressedInt();
+ if (this.currentTypeParameters != null && this.currentTypeParameters.Count > pnum)
+ {
+ TypeNode tPar = this.currentTypeParameters[pnum];
+ return tPar != null && tPar is Class;
+ }
+ return false;
+ }
+ case ElementType.MethodParameter:
+ {
+ int pnum = sigReader.ReadCompressedInt();
+ if (this.currentMethodTypeParameters != null && this.currentMethodTypeParameters.Count > pnum)
+ {
+ TypeNode tPar = this.currentMethodTypeParameters[pnum];
+ return tPar != null && tPar is Class;
+ }
+ return false;
+ }
+ default:
+ return false;
+ }
+ }
+ private TypeNode ParseTypeSignature(MemoryCursor/*!*/ sigReader)
+ {
+ bool junk = false;
+ return this.ParseTypeSignature(sigReader, ref junk, ref junk);
+ }
+ private TypeNode ParseTypeSignature(MemoryCursor/*!*/ sigReader, ref bool pinned)
+ {
+ bool junk = false;
+ return this.ParseTypeSignature(sigReader, ref pinned, ref junk);
+ }
+ private TypeNode ParseTypeSignature(MemoryCursor/*!*/ sigReader, ref bool pinned, ref bool isTypeArgument)
+ {
+ TypeNode elementType;
+ ElementType tok = (ElementType)sigReader.ReadCompressedInt();
+ if (tok == ElementType.Pinned)
+ {
+ pinned = true;
+ tok = (ElementType)sigReader.ReadCompressedInt();
+ }
+ switch (tok)
+ {
+ case ElementType.Boolean: return CoreSystemTypes.Boolean;
+ case ElementType.Char: return CoreSystemTypes.Char;
+ case ElementType.Double: return CoreSystemTypes.Double;
+ case ElementType.Int16: return CoreSystemTypes.Int16;
+ case ElementType.Int32: return CoreSystemTypes.Int32;
+ case ElementType.Int64: return CoreSystemTypes.Int64;
+ case ElementType.Int8: return CoreSystemTypes.Int8;
+ case ElementType.IntPtr: return CoreSystemTypes.IntPtr;
+ case ElementType.BoxedEnum:
+ case ElementType.Object: return CoreSystemTypes.Object;
+ case ElementType.Single: return CoreSystemTypes.Single;
+ case ElementType.String: return CoreSystemTypes.String;
+ case ElementType.DynamicallyTypedReference: return CoreSystemTypes.DynamicallyTypedReference;
+ case ElementType.UInt16: return CoreSystemTypes.UInt16;
+ case ElementType.UInt32: return CoreSystemTypes.UInt32;
+ case ElementType.UInt64: return CoreSystemTypes.UInt64;
+ case ElementType.UInt8: return CoreSystemTypes.UInt8;
+ case ElementType.UIntPtr: return CoreSystemTypes.UIntPtr;
+ case ElementType.Void: return CoreSystemTypes.Void;
+ case ElementType.Pointer:
+ elementType = this.ParseTypeSignature(sigReader, ref pinned);
+ if (elementType == null) elementType = CoreSystemTypes.Object;
+ if (elementType == null) return null;
+ return elementType.GetPointerType();
+ case ElementType.Reference:
+ elementType = this.ParseTypeSignature(sigReader, ref pinned);
+ if (elementType == null) elementType = CoreSystemTypes.Object;
+ return elementType.GetReferenceType();
+ case ElementType.FunctionPointer:
+ return this.ParseFunctionPointer(sigReader);
+ case ElementType.OptionalModifier:
+ case ElementType.RequiredModifier:
+ TypeNode modifier = this.DecodeAndGetTypeDefOrRefOrSpec(sigReader.ReadCompressedInt());
+ if (modifier == null) modifier = CoreSystemTypes.Object;
+ TypeNode modified = this.ParseTypeSignature(sigReader, ref pinned);
+ if (modified == null) modified = CoreSystemTypes.Object;
+ if (modified == null || modified == null) return null;
+ if (tok == ElementType.RequiredModifier)
+ return RequiredModifier.For(modifier, modified);
+ else
+ return OptionalModifier.For(modifier, modified);
+ case ElementType.Class:
+ return this.DecodeAndGetTypeDefOrRefOrSpec(sigReader.ReadCompressedInt());
+ case ElementType.ValueType:
+ return this.DecodeAndGetTypeDefOrRefOrSpec(sigReader.ReadCompressedInt(), true);
+ case ElementType.TypeParameter:
+ TypeNode tPar = null;
+ int pnum = sigReader.ReadCompressedInt();
+ if (this.currentTypeParameters != null && this.currentTypeParameters.Count > pnum)
+ tPar = this.currentTypeParameters[pnum];
+ if (tPar == null)
+ {
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.BadTypeParameterInPositionForType, pnum, this.currentType == null ? "" : this.currentType.FullName));
+ tPar = new TypeParameter();
+ tPar.Name = Identifier.For("Bad type parameter in position " + pnum);
+ tPar.DeclaringModule = this.module;
+ }
+ isTypeArgument = true;
+ return tPar;
+ case ElementType.MethodParameter:
+ TypeNode mTPar = null;
+ pnum = sigReader.ReadCompressedInt();
+ if (this.currentMethodTypeParameters != null && this.currentMethodTypeParameters.Count > pnum)
+ mTPar = this.currentMethodTypeParameters[pnum];
+ if (mTPar == null)
+ {
+ HandleError(this.module, String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.BadMethodTypeParameterInPosition, pnum));
+ mTPar = new MethodTypeParameter();
+ mTPar.Name = Identifier.For("Bad method type parameter in position " + pnum);
+ }
+ isTypeArgument = true;
+ return mTPar;
+ case ElementType.GenericTypeInstance:
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ TypeNode template = this.ParseTypeSignature(sigReader, ref pinned);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ if (template == null || template.ConsolidatedTemplateParameters == null) return template; //Likely a dummy type
+ if (CoreSystemTypes.Initialized)
+ {
+ if (this.currentTypeParameters == null || this.currentTypeParameters.Count == 0)
+ this.currentTypeParameters = template.ConsolidatedTemplateParameters;
+ TypeNodeList genArgs = this.ParseTypeList(sigReader);
+ if (this.module == null) return null;
+ TypeNode genInst = template.GetGenericTemplateInstance(this.module, genArgs);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return genInst;
+ }
+ InterfaceExpression ifaceExpr = new InterfaceExpression(null);
+ ifaceExpr.Template = template;
+ ifaceExpr.Namespace = template.Namespace;
+ ifaceExpr.Name = template.Name;
+ ifaceExpr.TemplateArguments = this.ParseTypeList(sigReader);
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return ifaceExpr;
+ case ElementType.SzArray:
+ elementType = this.ParseTypeSignature(sigReader, ref pinned);
+ if (elementType == null) elementType = CoreSystemTypes.Object;
+ if (elementType == null) return null;
+ return elementType.GetArrayType(1);
+ case ElementType.Array:
+ elementType = this.ParseTypeSignature(sigReader, ref pinned);
+ if (elementType == null) elementType = CoreSystemTypes.Object;
+ if (elementType == null) return null;
+ int rank = sigReader.ReadCompressedInt();
+ int numSizes = sigReader.ReadCompressedInt();
+ int[] sizes = new int[numSizes];
+ for (int i = 0; i < numSizes; i++) sizes[i] = sigReader.ReadCompressedInt();
+ int numLoBounds = sigReader.ReadCompressedInt();
+ int[] loBounds = new int[numLoBounds];
+ for (int i = 0; i < numLoBounds; i++) loBounds[i] = sigReader.ReadCompressedInt();
+ return elementType.GetArrayType(rank, numSizes, numLoBounds, sizes, loBounds);
+ case ElementType.Sentinel: return null;
+ case ElementType.Type: return CoreSystemTypes.Type;
+ case ElementType.Enum: return this.GetTypeFromSerializedName(ReadSerString(sigReader));
+ }
+ throw new InvalidMetadataException(ExceptionStrings.MalformedSignature);
+ }
+ private FunctionPointer/*!*/ ParseFunctionPointer(MemoryCursor/*!*/ sigReader)
+ {
+ CallingConventionFlags convention = (CallingConventionFlags)sigReader.ReadByte();
+ int n = sigReader.ReadCompressedInt();
+ TypeNode returnType = this.ParseTypeSignature(sigReader);
+ if (returnType == null) returnType = CoreSystemTypes.Object;
+ TypeNodeList parameterTypes = new TypeNodeList(n);
+ int m = n;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.ParseTypeSignature(sigReader);
+ if (t == null)
+ m = i--;
+ else
+ parameterTypes.Add(t);
+ }
+ FunctionPointer fp = FunctionPointer.For(parameterTypes, returnType);
+ fp.CallingConvention = convention;
+ fp.VarArgStart = m;
+ return fp;
+ }
+ private StatementList ParseMethodBody(Method/*!*/ method, int methodIndex, int RVA)
+ {
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ if (method.DeclaringType.Template != null)
+ this.currentTypeParameters = method.DeclaringType.ConsolidatedTemplateArguments;
+ else
+ this.currentTypeParameters = method.DeclaringType.ConsolidatedTemplateParameters;
+ BodyParser parser = new BodyParser(this, method, methodIndex, RVA);
+ StatementList result = parser.ParseStatements();
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return result;
+ }
+ private InstructionList ParseMethodInstructions(Method/*!*/ method, int methodIndex, int RVA)
+ {
+ TypeNodeList savedCurrentTypeParameters = this.currentTypeParameters;
+ if (method.DeclaringType.Template != null)
+ this.currentTypeParameters = method.DeclaringType.ConsolidatedTemplateArguments;
+ else
+ this.currentTypeParameters = method.DeclaringType.ConsolidatedTemplateParameters;
+ InstructionParser parser = new InstructionParser(this, method, methodIndex, RVA);
+ InstructionList result = parser.ParseInstructions();
+ this.currentTypeParameters = savedCurrentTypeParameters;
+ return result;
+ }
+ }
+
+ internal abstract class ILParser
+ {
+ internal int counter;
+ protected Reader/*!*/ reader;
+ protected MemoryCursor/*!*/ bodyReader;
+ internal int size;
+ protected Method/*!*/ method;
+ protected int methodIndex;
+ protected int RVA;
+ protected LocalList/*!*/ locals = new LocalList();
+
+ internal ILParser(Reader/*!*/ reader, Method/*!*/ method, int methodIndex, int RVA)
+ {
+ this.reader = reader;
+ this.bodyReader = reader.tables.GetNewCursor();
+ this.method = method;
+#if !FxCop
+ this.method.LocalList = this.locals;
+#else
+ this.method.Locals = this.locals;
+#endif
+ this.methodIndex = methodIndex;
+ this.RVA = RVA;
+ //^ base();
+ }
+ protected Expression Parameters(int i)
+ {
+ if (this.method.IsStatic) return this.method.Parameters[i];
+ if (i == 0) return this.method.ThisParameter;
+ return this.method.Parameters[i - 1];
+ }
+ protected void ParseHeader()
+ {
+ byte header = this.reader.tables.GetMethodBodyHeaderByte(this.RVA);
+ if ((header & 0x3) == 2)
+ {
+ this.size = header >> 2;
+ this.bodyReader = this.reader.tables.GetNewCursor();
+ this.reader.tables.Skip(size);
+ }
+ else
+ {
+ method.InitLocals = (header & 0x10) != 0;
+ byte header2 = this.reader.tables.GetByte();
+ int fatHeaderSize = header2 >> 4;
+ if (fatHeaderSize == 2) return;
+ if (fatHeaderSize != 3) throw new InvalidMetadataException(ExceptionStrings.InvalidFatMethodHeader);
+ this.reader.tables.Skip(2); //Skip over maxstack. No need to remember it.
+ this.size = this.reader.tables.GetInt32();
+ int localIndex = this.reader.tables.GetInt32();
+ this.bodyReader = this.reader.tables.GetNewCursor();
+ this.reader.tables.Skip(size);
+ this.reader.tables.AlignTo32BitBoundary();
+ while ((header & 0x8) != 0)
+ {
+ header = this.reader.tables.GetByte();
+ if ((header & 3) != 1) throw new InvalidMetadataException(ExceptionStrings.BadMethodHeaderSection);
+ if ((header & 0x80) != 0) throw new InvalidMetadataException(ExceptionStrings.TooManyMethodHeaderSections);
+ this.ParseExceptionHandlerEntry((header & 0x40) == 0);
+ }
+ Hashtable localSourceNames = new Hashtable();
+#if UseSingularityPDB
+ if (this.reader.getDebugSymbols && this.reader.pdbFunctions != null) {
+ PdbFunction pdbFunc = this.reader.GetPdbFunction(0x6000000|(uint)methodIndex);
+ if (pdbFunc != null)
+ this.GetLocalNames(pdbFunc.scopes, localSourceNames);
+ }
+#elif !ROTOR
+ if (this.reader.getDebugSymbols && this.reader.debugReader != null)
+ {
+ ISymUnmanagedMethod methodInfo = null;
+ try
+ {
+ try
+ {
+ this.reader.debugReader.GetMethod(0x6000000 | (uint)methodIndex, ref methodInfo);
+ if (methodInfo != null)
+ {
+ ISymUnmanagedScope rootScope = methodInfo.GetRootScope();
+ try
+ {
+ this.reader.GetLocalSourceNames(rootScope, localSourceNames);
+ }
+ finally
+ {
+ if (rootScope != null)
+ Marshal.ReleaseComObject(rootScope);
+ }
+ }
+ }
+ catch (COMException)
+ {
+ }
+ catch (InvalidCastException)
+ {
+ }
+ catch (System.Runtime.InteropServices.InvalidComObjectException) { }
+ }
+ finally
+ {
+ if (methodInfo != null)
+ Marshal.ReleaseComObject(methodInfo);
+ }
+ }
+#endif
+ this.reader.GetLocals(localIndex, this.locals, localSourceNames);
+ }
+ }
+
+#if UseSingularityPDB
+ private void GetLocalNames(PdbScope[] scopes, Hashtable localSourceNames) {
+ for (int i = 0, n = scopes == null ? 0 : scopes.Length; i < n; i++) {
+ PdbScope scope = scopes[i];
+ foreach (PdbSlot slot in scope.slots)
+ localSourceNames[(int)slot.slot] = slot.name;
+ this.GetLocalNames(scope.scopes, localSourceNames);
+ }
+ }
+#endif
+
+ abstract protected void ParseExceptionHandlerEntry(bool smallSection);
+ protected byte GetByte()
+ {
+ this.counter += 1;
+ return this.bodyReader.ReadByte();
+ }
+ protected sbyte GetSByte()
+ {
+ this.counter += 1;
+ return this.bodyReader.ReadSByte();
+ }
+ protected short GetInt16()
+ {
+ this.counter += 2;
+ return this.bodyReader.ReadInt16();
+ }
+ protected int GetInt32()
+ {
+ this.counter += 4;
+ return this.bodyReader.ReadInt32();
+ }
+ protected long GetInt64()
+ {
+ this.counter += 8;
+ return this.bodyReader.ReadInt64();
+ }
+ protected float GetSingle()
+ {
+ this.counter += 4;
+ return this.bodyReader.ReadSingle();
+ }
+ protected double GetDouble()
+ {
+ this.counter += 8;
+ return this.bodyReader.ReadDouble();
+ }
+ protected Member/*!*/ GetMemberFromToken()
+ {
+ return this.reader.GetMemberFromToken(this.GetInt32());
+ }
+ protected Member/*!*/ GetMemberFromToken(out TypeNodeList varArgTypes)
+ {
+ return this.reader.GetMemberFromToken(this.GetInt32(), out varArgTypes);
+ }
+ protected string/*!*/ GetStringFromToken()
+ {
+ int tok = this.GetInt32();
+ return this.reader.tables.GetUserString(tok & 0xFFFFFF);
+ }
+ protected OpCode GetOpCode()
+ {
+ int result = this.GetByte();
+ if (result == (int)OpCode.Prefix1)
+ result = result << 8 | this.GetByte();
+ return (OpCode)result;
+ }
+ }
+ sealed internal class BodyParser : ILParser
+ {
+ private readonly ExpressionStack/*!*/ operandStack = new ExpressionStack();
+ private readonly TrivialHashtable/*!*/ blockMap = new TrivialHashtable();
+ private int alignment = -1;
+ private bool isReadOnly;
+ private bool isTailCall;
+ private bool isVolatile;
+ private TypeNode constraint;
+
+ internal BodyParser(Reader/*!*/ reader, Method/*!*/ method, int methodIndex, int RVA)
+ : base(reader, method, methodIndex, RVA)
+ {
+ //^ base;
+ }
+#if !FxCop
+ override protected void ParseExceptionHandlerEntry(bool smallSection)
+ {
+ int dataSize = this.reader.tables.GetByte();
+ int n = (int)(ushort)this.reader.tables.GetInt16();
+ if (smallSection)
+ n = dataSize / 12;
+ else
+ n = (dataSize + (n << 8)) / 24;
+ if (n < 0) n = 0;
+ this.method.ExceptionHandlers = new ExceptionHandlerList(n);
+ for (int i = 0; i < n; i++)
+ {
+ int flags, tryOffset, tryLength, handlerOffset, handlerLength, tokenOrOffset;
+ if (smallSection)
+ {
+ flags = this.reader.tables.GetInt16();
+ tryOffset = this.reader.tables.GetUInt16();
+ tryLength = this.reader.tables.GetByte();
+ handlerOffset = this.reader.tables.GetUInt16();
+ handlerLength = this.reader.tables.GetByte();
+ }
+ else
+ {
+ flags = this.reader.tables.GetInt32();
+ tryOffset = this.reader.tables.GetInt32();
+ tryLength = this.reader.tables.GetInt32();
+ handlerOffset = this.reader.tables.GetInt32();
+ handlerLength = this.reader.tables.GetInt32();
+ }
+ tokenOrOffset = this.reader.tables.GetInt32();
+ ExceptionHandler eh = new ExceptionHandler();
+ switch (flags)
+ {
+ case 0x00:
+ eh.HandlerType = NodeType.Catch;
+ int pos = this.reader.tables.GetCurrentPosition();
+ eh.FilterType = (TypeNode)this.reader.GetMemberFromToken(tokenOrOffset);
+ this.reader.tables.SetCurrentPosition(pos);
+ break;
+ case 0x01:
+ eh.HandlerType = NodeType.Filter;
+ eh.FilterExpression = Reader.GetOrCreateBlock(blockMap, tokenOrOffset);
+ break;
+ case 0x02: eh.HandlerType = NodeType.Finally; break;
+ case 0x04: eh.HandlerType = NodeType.FaultHandler; break;
+ default: throw new InvalidMetadataException(ExceptionStrings.BadExceptionHandlerType);
+ }
+ eh.TryStartBlock = Reader.GetOrCreateBlock(this.blockMap, tryOffset);
+ eh.BlockAfterTryEnd = Reader.GetOrCreateBlock(this.blockMap, tryOffset + tryLength);
+ eh.HandlerStartBlock = Reader.GetOrCreateBlock(this.blockMap, handlerOffset);
+ eh.BlockAfterHandlerEnd = Reader.GetOrCreateBlock(this.blockMap, handlerOffset + handlerLength);
+ this.method.ExceptionHandlers.Add(eh);
+ }
+ }
+#endif
+ private AssignmentStatement/*!*/ ParseArrayElementAssignment(OpCode opCode)
+ {
+ Expression rhvalue = PopOperand();
+ ExpressionList indexers = new ExpressionList(1);
+ indexers.Add(PopOperand());
+ Expression array = PopOperand();
+ Indexer indexer = new Indexer(array, indexers);
+ TypeNode t = CoreSystemTypes.Object;
+ switch (opCode)
+ {
+ case OpCode.Stelem_I: t = CoreSystemTypes.IntPtr; break;
+ case OpCode.Stelem_I1: t = CoreSystemTypes.Int8; break;
+ case OpCode.Stelem_I2: t = CoreSystemTypes.Int16; break;
+ case OpCode.Stelem_I4: t = CoreSystemTypes.Int32; break;
+ case OpCode.Stelem_I8: t = CoreSystemTypes.Int64; break;
+ case OpCode.Stelem_R4: t = CoreSystemTypes.Single; break;
+ case OpCode.Stelem_R8: t = CoreSystemTypes.Double; break;
+ case OpCode.Stelem: t = (TypeNode)this.GetMemberFromToken(); break;
+ default:
+ ArrayType arrT = array.Type as ArrayType;
+ if (arrT != null) t = arrT.ElementType;
+ break;
+ }
+ indexer.ElementType = indexer.Type = t;
+ return new AssignmentStatement(indexer, rhvalue);
+ }
+ private Indexer/*!*/ ParseArrayElementLoad(OpCode opCode, TypeNode elementType)
+ {
+ ExpressionList indexers = new ExpressionList(1); indexers.Add(PopOperand());
+ Expression array = PopOperand();
+ Indexer indexer = new Indexer(array, indexers);
+ TypeNode t = elementType;
+ switch (opCode)
+ {
+ case OpCode.Ldelem_I1: t = CoreSystemTypes.Int8; break;
+ case OpCode.Ldelem_U1: t = CoreSystemTypes.UInt8; break;
+ case OpCode.Ldelem_I2: t = CoreSystemTypes.Int16; break;
+ case OpCode.Ldelem_U2: t = CoreSystemTypes.UInt16; break;
+ case OpCode.Ldelem_I4: t = CoreSystemTypes.Int32; break;
+ case OpCode.Ldelem_U4: t = CoreSystemTypes.UInt32; break;
+ case OpCode.Ldelem_I8: t = CoreSystemTypes.Int64; break;
+ case OpCode.Ldelem_I: t = CoreSystemTypes.IntPtr; break;
+ case OpCode.Ldelem_R4: t = CoreSystemTypes.Single; break;
+ case OpCode.Ldelem_R8: t = CoreSystemTypes.Double; break;
+ case OpCode.Ldelem: t = (TypeNode)this.GetMemberFromToken(); break;
+ default:
+ if (t != null) break;
+ t = CoreSystemTypes.Object;
+ ArrayType arrT = array.Type as ArrayType;
+ if (arrT != null) t = arrT.ElementType;
+ break;
+ }
+ indexer.ElementType = indexer.Type = t;
+ return indexer;
+ }
+ private UnaryExpression/*!*/ ParseArrayElementLoadAddress()
+ {
+ TypeNode elemType = (TypeNode)this.GetMemberFromToken();
+ return new UnaryExpression(this.ParseArrayElementLoad(0, elemType), this.isReadOnly ? NodeType.ReadOnlyAddressOf : NodeType.AddressOf, elemType.GetReferenceType());
+ }
+ private static UnaryExpression/*!*/ SetType(UnaryExpression/*!*/ uex)
+ {
+ if (uex == null || uex.Operand == null) return uex;
+ TypeNode elemType = uex.Operand.Type;
+ if (elemType == null) return uex;
+ uex.Type = elemType.GetReferenceType();
+ return uex;
+ }
+ private BinaryExpression/*!*/ ParseBinaryComparison(NodeType oper)
+ {
+ Expression op2 = PopOperand();
+ Expression op1 = PopOperand();
+ BinaryExpression result = new BinaryExpression(op1, op2, oper);
+ result.Type = CoreSystemTypes.Int32;
+ return result;
+ }
+ private BinaryExpression/*!*/ ParseBinaryOperation(NodeType oper)
+ {
+ Expression op2 = PopOperand();
+ Expression op1 = PopOperand();
+ BinaryExpression result = new BinaryExpression(op1, op2, oper);
+ result.Type = op1.Type;
+ if (result.Type == null) result.Type = op2.Type;
+ return result;
+ }
+ private UnaryExpression/*!*/ ParseUnaryOperation(NodeType oper)
+ {
+ Expression op = PopOperand();
+ return new UnaryExpression(op, oper, op.Type);
+ }
+ private Branch/*!*/ ParseBranch(NodeType operatorType, int operandCount, bool shortOffset, bool unordered)
+ {
+ return this.ParseBranch(operatorType, operandCount, shortOffset, unordered, false);
+ }
+ private Branch/*!*/ ParseBranch(NodeType operatorType, int operandCount, bool shortOffset, bool unordered, bool leavesExceptionBlock)
+ {
+ Expression operand2 = operandCount > 1 ? PopOperand() : null;
+ Expression operand1 = operandCount > 0 ? PopOperand() : null;
+ Expression condition = operandCount > 1 ? (Expression)new BinaryExpression(operand1, operand2, operatorType) :
+ (operandCount > 0 ? (operatorType == NodeType.Nop ? operand1 : (Expression)new UnaryExpression(operand1, operatorType)) : null);
+ int targetAddress = shortOffset ? this.GetSByte() : this.GetInt32();
+ Block targetBlock = (Block)this.blockMap[targetAddress + this.counter + 1];
+ Debug.Assert(targetBlock != null);
+ if (targetAddress >= 0 && !this.reader.preserveShortBranches) shortOffset = false;
+ return new Branch(condition, targetBlock, shortOffset, unordered, leavesExceptionBlock);
+ }
+ private MethodCall/*!*/ ParseCall(NodeType typeOfCall, out bool isStatement)
+ {
+ TypeNodeList varArgTypes;
+ Method meth = (Method)this.GetMemberFromToken(out varArgTypes);
+ int numVarArgs = varArgTypes == null ? 0 : varArgTypes.Count;
+ isStatement = BodyParser.TypeIsVoid(meth.ReturnType);
+ int n = meth.Parameters == null ? 0 : meth.Parameters.Count;
+ if (typeOfCall == NodeType.Jmp) n = 0;
+ else n += numVarArgs;
+ Expression[] args = new Expression[n];
+ ExpressionList arguments = new ExpressionList(n);
+ for (int i = n - 1; i >= 0; i--) args[i] = PopOperand();
+ for (int i = 0; i < n; i++) arguments.Add(args[i]);
+ if (varArgTypes != null)
+ {
+ for (int i = n - 1, j = numVarArgs; j > 0; j--, i--)
+ {
+ Expression e = arguments[i];
+ TypeNode t = varArgTypes[j - 1];
+ if (e != null && t != null) e.Type = t;
+ }
+ }
+ Expression thisob = meth.IsStatic ? null : PopOperand();
+ MemberBinding methBinding = new MemberBinding(thisob, meth);
+ MethodCall result = new MethodCall(methBinding, arguments, typeOfCall);
+ result.Type = meth.ReturnType;
+ result.IsTailCall = this.isTailCall;
+ if (this.constraint != null)
+ {
+ result.Constraint = this.constraint;
+ this.constraint = null;
+ }
+ return result;
+ }
+ private static bool TypeIsVoid(TypeNode t)
+ {
+ if (t == null) return false;
+ for (; ; )
+ {
+ switch (t.NodeType)
+ {
+ case NodeType.OptionalModifier:
+ case NodeType.RequiredModifier:
+ t = ((TypeModifier)t).ModifiedType;
+ break;
+ default:
+ return t == CoreSystemTypes.Void;
+ }
+ }
+ }
+ private MethodCall/*!*/ ParseCalli(out bool isStatement)
+ {
+ FunctionPointer fp = this.reader.GetCalliSignature(this.GetInt32());
+ if (fp == null) throw new InvalidMetadataException(ExceptionStrings.BaddCalliSignature);
+ isStatement = BodyParser.TypeIsVoid(fp.ReturnType);
+ int n = fp.ParameterTypes.Count;
+ Expression[] args = new Expression[n + 1];
+ ExpressionList arguments = new ExpressionList(n + 1);
+ for (int i = n; i >= 0; i--) args[i] = PopOperand();
+ for (int i = 0; i <= n; i++) arguments.Add(args[i]);
+ Expression thisob = fp.IsStatic ? null : PopOperand();
+ MemberBinding methBinding = new MemberBinding(thisob, fp);
+ MethodCall result = new MethodCall(methBinding, arguments, NodeType.Calli);
+ result.Type = fp.ReturnType;
+ result.IsTailCall = this.isTailCall;
+ return result;
+ }
+ private static Expression/*!*/ ParseTypeCheck(Expression operand, TypeNode type, NodeType typeOfCheck)
+ {
+ TypeNode etype = type;
+ if (typeOfCheck == NodeType.Unbox) etype = type.GetReferenceType();
+ Expression expr = new BinaryExpression(operand, new Literal(type, CoreSystemTypes.Type), typeOfCheck, etype);
+ return expr;
+ }
+ private Construct/*!*/ ParseConstruct()
+ {
+ TypeNodeList varArgTypes;
+ Method meth = (Method)this.GetMemberFromToken(out varArgTypes);
+ int n = meth.Parameters.Count;
+ Expression[] args = new Expression[n];
+ ExpressionList arguments = new ExpressionList(n);
+ for (int i = n - 1; i >= 0; i--) args[i] = PopOperand();
+ for (int i = 0; i < n; i++) arguments.Add(args[i]);
+ Construct result = new Construct(new MemberBinding(null, meth), arguments);
+ result.Type = meth.DeclaringType;
+ return result;
+ }
+ private AssignmentStatement/*!*/ ParseCopyObject()
+ {
+ TypeNode type = (TypeNode)this.GetMemberFromToken();
+ Expression rhaddr = PopOperand();
+ Expression lhaddr = PopOperand();
+ return new AssignmentStatement(new AddressDereference(lhaddr, type, this.isVolatile, this.alignment), new AddressDereference(rhaddr, type));
+ }
+ private UnaryExpression /*!*/ ParseLoadRuntimeMetadataToken()
+ {
+ Expression expr = null;
+ TypeNode exprType = null;
+ Member member = this.GetMemberFromToken();
+ TypeNode t = member as TypeNode;
+ if (t == null)
+ {
+ exprType = (member.NodeType == NodeType.Field)
+ ? CoreSystemTypes.RuntimeFieldHandle : CoreSystemTypes.RuntimeMethodHandle;
+ expr = new MemberBinding(null, member);
+ }
+ else
+ {
+ exprType = CoreSystemTypes.RuntimeTypeHandle;
+ expr = new Literal(t, CoreSystemTypes.Type);
+ }
+ return new UnaryExpression(expr, NodeType.Ldtoken, exprType);
+ }
+ private AssignmentStatement/*!*/ ParseInitObject()
+ {
+ TypeNode type = (TypeNode)this.GetMemberFromToken();
+ Expression lhaddr = PopOperand();
+ return new AssignmentStatement(new AddressDereference(lhaddr, type, this.isVolatile, this.alignment), new Literal(null, CoreSystemTypes.Object));
+ }
+ private ConstructArray/*!*/ ParseNewArray()
+ {
+ TypeNode type = (TypeNode)this.GetMemberFromToken();
+ ExpressionList sizes = new ExpressionList(1);
+ sizes.Add(PopOperand());
+ ConstructArray result = new ConstructArray(type, sizes, null);
+ result.Type = type.GetArrayType(1);
+ return result;
+ }
+#if !FxCop
+ internal StatementList/*!*/ ParseStatements()
+ {
+ this.ParseHeader();
+ if (this.size == 0) return new StatementList(0);
+ this.CreateBlocksForBranchTargets();
+ StatementList result = new StatementList();
+ Block currentBlock = null;
+ while (this.counter < size)
+ {
+ if (currentBlock == null)
+ {
+ currentBlock = Reader.GetOrCreateBlock(this.blockMap, this.counter);
+ result.Add(currentBlock);
+ }
+ bool endOfBasicBlock = this.ParseStatement(currentBlock);
+ if (endOfBasicBlock) currentBlock = null;
+ }
+ result.Add(Reader.GetOrCreateBlock(this.blockMap, this.counter));
+ return result;
+ }
+#endif
+ private bool ParseStatement(Block/*!*/ block)
+ {
+ //parse instructions and put in expression tree until an assignment, void call, branch target, or branch is encountered
+ StatementList statementList = block.Statements;
+ Expression expr = null;
+ Statement statement = null;
+ bool transferStatement = false;
+ int startingAddress = 0;
+#if !FxCop
+ SourceContext sourceContext = new SourceContext();
+ sourceContext.StartPos = this.counter;
+#endif
+#if !ROTOR
+ if (this.method.contextForOffset != null)
+ {
+ object sctx = this.method.contextForOffset[this.counter + 1];
+ if (sctx != null) sourceContext = (SourceContext)sctx;
+ }
+#endif
+ while (true)
+ {
+ bool isStatement = false;
+ startingAddress = this.counter + 1; //Add one so that it is never zero (the latter means no entry to the TrivialHashtable)
+#if !FxCop
+ OpCode opCode = this.GetOpCode();
+#else
+ this.ilOffset = this.counter;
+ if (this.handlerMap.TryGetValue(this.ilOffset, out expr)){
+ expr.sourceContext = sourceContext;
+ expr.ILOffset = this.ilOffset;
+ this.operandStack.Push(expr);
+ }
+ this.opCode = this.GetOpCode();
+#endif
+ switch (opCode)
+ {
+ case OpCode.Nop: statement = new Statement(NodeType.Nop); goto done;
+ case OpCode.Break: statement = new Statement(NodeType.DebugBreak); goto done;
+ case OpCode.Ldarg_0: expr = this.Parameters(0); break;
+ case OpCode.Ldarg_1: expr = this.Parameters(1); break;
+ case OpCode.Ldarg_2: expr = this.Parameters(2); break;
+ case OpCode.Ldarg_3: expr = this.Parameters(3); break;
+ case OpCode.Ldloc_0: expr = this.locals[0]; break;
+ case OpCode.Ldloc_1: expr = this.locals[1]; break;
+ case OpCode.Ldloc_2: expr = this.locals[2]; break;
+ case OpCode.Ldloc_3: expr = this.locals[3]; break;
+ case OpCode.Stloc_0: statement = new AssignmentStatement(this.locals[0], PopOperand()); goto done;
+ case OpCode.Stloc_1: statement = new AssignmentStatement(this.locals[1], PopOperand()); goto done;
+ case OpCode.Stloc_2: statement = new AssignmentStatement(this.locals[2], PopOperand()); goto done;
+ case OpCode.Stloc_3: statement = new AssignmentStatement(this.locals[3], PopOperand()); goto done;
+ case OpCode.Ldarg_S: expr = this.Parameters(this.GetByte()); break;
+ case OpCode.Ldarga_S: expr = SetType(new UnaryExpression(this.Parameters(this.GetByte()), NodeType.AddressOf)); break;
+ case OpCode.Starg_S: statement = new AssignmentStatement(this.Parameters(this.GetByte()), PopOperand()); goto done;
+ case OpCode.Ldloc_S: expr = this.locals[this.GetByte()]; break;
+ case OpCode.Ldloca_S: expr = SetType(new UnaryExpression(this.locals[this.GetByte()], NodeType.AddressOf)); break;
+ case OpCode.Stloc_S: statement = new AssignmentStatement(this.locals[this.GetByte()], PopOperand()); goto done;
+ case OpCode.Ldnull: expr = new Literal(null, CoreSystemTypes.Object); break;
+ case OpCode.Ldc_I4_M1: expr = new Literal(-1, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_0: expr = new Literal(0, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_1: expr = new Literal(1, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_2: expr = new Literal(2, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_3: expr = new Literal(3, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_4: expr = new Literal(4, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_5: expr = new Literal(5, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_6: expr = new Literal(6, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_7: expr = new Literal(7, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_8: expr = new Literal(8, CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4_S: expr = new Literal((int)this.GetSByte(), CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I4: expr = new Literal(this.GetInt32(), CoreSystemTypes.Int32); break;
+ case OpCode.Ldc_I8: expr = new Literal(this.GetInt64(), CoreSystemTypes.Int64); break;
+ case OpCode.Ldc_R4: expr = new Literal(this.GetSingle(), CoreSystemTypes.Single); break;
+ case OpCode.Ldc_R8: expr = new Literal(this.GetDouble(), CoreSystemTypes.Double); break;
+ case OpCode.Dup: statement = new ExpressionStatement(new Expression(NodeType.Dup)); goto done;
+ case OpCode.Pop: statement = new ExpressionStatement(new UnaryExpression(PopOperand(), NodeType.Pop)); goto done;
+ case OpCode.Jmp: expr = this.ParseCall(NodeType.Jmp, out isStatement); if (isStatement) goto done; break;
+ case OpCode.Call: expr = this.ParseCall(NodeType.Call, out isStatement); if (isStatement) goto done; break;
+ case OpCode.Calli: expr = this.ParseCalli(out isStatement); if (isStatement) goto done; break;
+ case OpCode.Ret:
+ Expression retVal = BodyParser.TypeIsVoid(this.method.ReturnType) ? null : PopOperand();
+ statement = new Return(retVal);
+ transferStatement = true; goto done;
+ case OpCode.Br_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false); transferStatement = true; goto done;
+ case OpCode.Brfalse_S: statement = this.ParseBranch(NodeType.LogicalNot, 1, true, false); transferStatement = true; goto done;
+ case OpCode.Brtrue_S: statement = this.ParseBranch(NodeType.Nop, 1, true, false); transferStatement = true; goto done;
+ case OpCode.Beq_S: statement = this.ParseBranch(NodeType.Eq, 2, true, false); transferStatement = true; goto done;
+ case OpCode.Bge_S: statement = this.ParseBranch(NodeType.Ge, 2, true, false); transferStatement = true; goto done;
+ case OpCode.Bgt_S: statement = this.ParseBranch(NodeType.Gt, 2, true, false); transferStatement = true; goto done;
+ case OpCode.Ble_S: statement = this.ParseBranch(NodeType.Le, 2, true, false); transferStatement = true; goto done;
+ case OpCode.Blt_S: statement = this.ParseBranch(NodeType.Lt, 2, true, false); transferStatement = true; goto done;
+ case OpCode.Bne_Un_S: statement = this.ParseBranch(NodeType.Ne, 2, true, true); transferStatement = true; goto done;
+ case OpCode.Bge_Un_S: statement = this.ParseBranch(NodeType.Ge, 2, true, true); transferStatement = true; goto done;
+ case OpCode.Bgt_Un_S: statement = this.ParseBranch(NodeType.Gt, 2, true, true); transferStatement = true; goto done;
+ case OpCode.Ble_Un_S: statement = this.ParseBranch(NodeType.Le, 2, true, true); transferStatement = true; goto done;
+ case OpCode.Blt_Un_S: statement = this.ParseBranch(NodeType.Lt, 2, true, true); transferStatement = true; goto done;
+ case OpCode.Br: statement = this.ParseBranch(NodeType.Nop, 0, false, false); transferStatement = true; goto done;
+ case OpCode.Brfalse: statement = this.ParseBranch(NodeType.LogicalNot, 1, false, false); transferStatement = true; goto done;
+ case OpCode.Brtrue: statement = this.ParseBranch(NodeType.Nop, 1, false, false); transferStatement = true; goto done;
+ case OpCode.Beq: statement = this.ParseBranch(NodeType.Eq, 2, false, false); transferStatement = true; goto done;
+ case OpCode.Bge: statement = this.ParseBranch(NodeType.Ge, 2, false, false); transferStatement = true; goto done;
+ case OpCode.Bgt: statement = this.ParseBranch(NodeType.Gt, 2, false, false); transferStatement = true; goto done;
+ case OpCode.Ble: statement = this.ParseBranch(NodeType.Le, 2, false, false); transferStatement = true; goto done;
+ case OpCode.Blt: statement = this.ParseBranch(NodeType.Lt, 2, false, false); transferStatement = true; goto done;
+ case OpCode.Bne_Un: statement = this.ParseBranch(NodeType.Ne, 2, false, true); transferStatement = true; goto done;
+ case OpCode.Bge_Un: statement = this.ParseBranch(NodeType.Ge, 2, false, true); transferStatement = true; goto done;
+ case OpCode.Bgt_Un: statement = this.ParseBranch(NodeType.Gt, 2, false, true); transferStatement = true; goto done;
+ case OpCode.Ble_Un: statement = this.ParseBranch(NodeType.Le, 2, false, true); transferStatement = true; goto done;
+ case OpCode.Blt_Un: statement = this.ParseBranch(NodeType.Lt, 2, false, true); transferStatement = true; goto done;
+ case OpCode.Switch: statement = this.ParseSwitchInstruction(); transferStatement = true; goto done;
+ case OpCode.Ldind_I1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int8, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_U1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt8, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_I2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int16, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_U2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt16, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_I4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int32, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_U4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt32, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_I8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int64, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_I: expr = new AddressDereference(PopOperand(), CoreSystemTypes.IntPtr, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_R4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Single, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_R8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Double, this.isVolatile, this.alignment); break;
+ case OpCode.Ldind_Ref: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Object, this.isVolatile, this.alignment); break;
+ case OpCode.Stind_Ref: statement = this.ParseStoreIndirect(CoreSystemTypes.Object); goto done;
+ case OpCode.Stind_I1: statement = this.ParseStoreIndirect(CoreSystemTypes.Int8); goto done;
+ case OpCode.Stind_I2: statement = this.ParseStoreIndirect(CoreSystemTypes.Int16); goto done;
+ case OpCode.Stind_I4: statement = this.ParseStoreIndirect(CoreSystemTypes.Int32); goto done;
+ case OpCode.Stind_I8: statement = this.ParseStoreIndirect(CoreSystemTypes.Int64); goto done;
+ case OpCode.Stind_R4: statement = this.ParseStoreIndirect(CoreSystemTypes.Single); goto done;
+ case OpCode.Stind_R8: statement = this.ParseStoreIndirect(CoreSystemTypes.Double); goto done;
+ case OpCode.Add: expr = this.ParseBinaryOperation(NodeType.Add); break;
+ case OpCode.Sub: expr = this.ParseBinaryOperation(NodeType.Sub); break;
+ case OpCode.Mul: expr = this.ParseBinaryOperation(NodeType.Mul); break;
+ case OpCode.Div: expr = this.ParseBinaryOperation(NodeType.Div); break;
+ case OpCode.Div_Un: expr = this.ParseBinaryOperation(NodeType.Div_Un); break;
+ case OpCode.Rem: expr = this.ParseBinaryOperation(NodeType.Rem); break;
+ case OpCode.Rem_Un: expr = this.ParseBinaryOperation(NodeType.Rem_Un); break;
+ case OpCode.And: expr = this.ParseBinaryOperation(NodeType.And); break;
+ case OpCode.Or: expr = this.ParseBinaryOperation(NodeType.Or); break;
+ case OpCode.Xor: expr = this.ParseBinaryOperation(NodeType.Xor); break;
+ case OpCode.Shl: expr = this.ParseBinaryOperation(NodeType.Shl); break;
+ case OpCode.Shr: expr = this.ParseBinaryOperation(NodeType.Shr); break;
+ case OpCode.Shr_Un: expr = this.ParseBinaryOperation(NodeType.Shr_Un); break;
+ case OpCode.Neg: expr = this.ParseUnaryOperation(NodeType.Neg); break;
+ case OpCode.Not: expr = this.ParseUnaryOperation(NodeType.Not); break;
+ case OpCode.Conv_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I1, CoreSystemTypes.Int8); break;
+ case OpCode.Conv_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I2, CoreSystemTypes.Int16); break;
+ case OpCode.Conv_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I4, CoreSystemTypes.Int32); break;
+ case OpCode.Conv_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I8, CoreSystemTypes.Int64); break;
+ case OpCode.Conv_R4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R4, CoreSystemTypes.Single); break;
+ case OpCode.Conv_R8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R8, CoreSystemTypes.Double); break;
+ case OpCode.Conv_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U4, CoreSystemTypes.UInt32); break;
+ case OpCode.Conv_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U8, CoreSystemTypes.UInt64); break;
+ case OpCode.Callvirt: expr = this.ParseCall(NodeType.Callvirt, out isStatement); if (isStatement) goto done; break;
+ case OpCode.Cpobj: statement = this.ParseCopyObject(); goto done;
+ case OpCode.Ldobj: expr = new AddressDereference(PopOperand(), (TypeNode)this.GetMemberFromToken(), this.isVolatile, this.alignment); break;
+ case OpCode.Ldstr: expr = new Literal(this.GetStringFromToken(), CoreSystemTypes.String); break;
+ case OpCode.Newobj: expr = this.ParseConstruct(); break;
+ case OpCode.Castclass: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Castclass); break;
+ case OpCode.Isinst: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Isinst); break;
+ case OpCode.Conv_R_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R_Un, CoreSystemTypes.Double); break;
+ case OpCode.Unbox: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Unbox); break;
+ case OpCode.Throw: statement = new Throw(PopOperand()); transferStatement = true; goto done;
+ case OpCode.Ldfld:
+ expr = new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment);
+ break;
+ case OpCode.Ldflda:
+ expr = SetType(new UnaryExpression(new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf));
+ break;
+ case OpCode.Stfld: statement = this.ParseStoreField(); goto done;
+ case OpCode.Ldsfld: expr = new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment); break;
+ case OpCode.Ldsflda: expr = SetType(new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break;
+ case OpCode.Stsfld: statement = new AssignmentStatement(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), PopOperand()); goto done;
+ case OpCode.Stobj: statement = this.ParseStoreIndirect((TypeNode)this.GetMemberFromToken()); goto done;
+ case OpCode.Conv_Ovf_I1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1_Un, CoreSystemTypes.Int8); break;
+ case OpCode.Conv_Ovf_I2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2_Un, CoreSystemTypes.Int16); break;
+ case OpCode.Conv_Ovf_I4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4_Un, CoreSystemTypes.Int32); break;
+ case OpCode.Conv_Ovf_I8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8_Un, CoreSystemTypes.Int64); break;
+ case OpCode.Conv_Ovf_U1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1_Un, CoreSystemTypes.UInt8); break;
+ case OpCode.Conv_Ovf_U2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2_Un, CoreSystemTypes.UInt16); break;
+ case OpCode.Conv_Ovf_U4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4_Un, CoreSystemTypes.UInt32); break;
+ case OpCode.Conv_Ovf_U8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8_Un, CoreSystemTypes.UInt64); break;
+ case OpCode.Conv_Ovf_I_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I_Un, CoreSystemTypes.IntPtr); break;
+ case OpCode.Conv_Ovf_U_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U_Un, CoreSystemTypes.UIntPtr); break;
+ case OpCode.Box:
+ TypeNode t = (TypeNode)this.GetMemberFromToken();
+ TypeNode bt = t is EnumNode ? CoreSystemTypes.Enum : CoreSystemTypes.ValueType;
+ expr = new BinaryExpression(PopOperand(), new Literal(t, CoreSystemTypes.Type), NodeType.Box, bt); break;
+ case OpCode.Newarr: expr = this.ParseNewArray(); break;
+ case OpCode.Ldlen: expr = new UnaryExpression(PopOperand(), NodeType.Ldlen, CoreSystemTypes.UIntPtr); break;
+ case OpCode.Ldelema: expr = this.ParseArrayElementLoadAddress(); break;
+ case OpCode.Ldelem_I1:
+ case OpCode.Ldelem_U1:
+ case OpCode.Ldelem_I2:
+ case OpCode.Ldelem_U2:
+ case OpCode.Ldelem_I4:
+ case OpCode.Ldelem_U4:
+ case OpCode.Ldelem_I8:
+ case OpCode.Ldelem_I:
+ case OpCode.Ldelem_R4:
+ case OpCode.Ldelem_R8:
+ case OpCode.Ldelem_Ref: expr = this.ParseArrayElementLoad(opCode, null); break;
+ case OpCode.Stelem_I:
+ case OpCode.Stelem_I1:
+ case OpCode.Stelem_I2:
+ case OpCode.Stelem_I4:
+ case OpCode.Stelem_I8:
+ case OpCode.Stelem_R4:
+ case OpCode.Stelem_R8:
+ case OpCode.Stelem_Ref: statement = this.ParseArrayElementAssignment(opCode); goto done;
+ case OpCode.Ldelem: expr = this.ParseArrayElementLoad(opCode, null); break;
+ case OpCode.Stelem: statement = this.ParseArrayElementAssignment(opCode); goto done;
+ case OpCode.Unbox_Any: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.UnboxAny); break;
+ case OpCode.Conv_Ovf_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1, CoreSystemTypes.Int8); break;
+ case OpCode.Conv_Ovf_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1, CoreSystemTypes.UInt8); break;
+ case OpCode.Conv_Ovf_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2, CoreSystemTypes.Int16); break;
+ case OpCode.Conv_Ovf_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2, CoreSystemTypes.UInt16); break;
+ case OpCode.Conv_Ovf_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4, CoreSystemTypes.Int32); break;
+ case OpCode.Conv_Ovf_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4, CoreSystemTypes.UInt32); break;
+ case OpCode.Conv_Ovf_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8, CoreSystemTypes.Int64); break;
+ case OpCode.Conv_Ovf_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8, CoreSystemTypes.UInt64); break;
+ case OpCode.Refanyval: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Refanyval, CoreSystemTypes.IntPtr); break;
+ case OpCode.Ckfinite: expr = this.ParseUnaryOperation(NodeType.Ckfinite); break;
+ case OpCode.Mkrefany: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Mkrefany, CoreSystemTypes.DynamicallyTypedReference); break;
+ case OpCode.Ldtoken: expr = ParseLoadRuntimeMetadataToken(); break;
+ case OpCode.Conv_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U2, CoreSystemTypes.UInt16); break;
+ case OpCode.Conv_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U1, CoreSystemTypes.UInt8); break;
+ case OpCode.Conv_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I, CoreSystemTypes.IntPtr); break;
+ case OpCode.Conv_Ovf_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I, CoreSystemTypes.IntPtr); break;
+ case OpCode.Conv_Ovf_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U, CoreSystemTypes.UIntPtr); break;
+ case OpCode.Add_Ovf: expr = this.ParseBinaryOperation(NodeType.Add_Ovf); break;
+ case OpCode.Add_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Add_Ovf_Un); break;
+ case OpCode.Mul_Ovf: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf); break;
+ case OpCode.Mul_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf_Un); break;
+ case OpCode.Sub_Ovf: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf); break;
+ case OpCode.Sub_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf_Un); break;
+ case OpCode.Endfinally: statement = new EndFinally(); transferStatement = true; goto done;
+ case OpCode.Leave: statement = this.ParseBranch(NodeType.Nop, 0, false, false, true); transferStatement = true; goto done;
+ case OpCode.Leave_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false, true); transferStatement = true; goto done;
+ case OpCode.Stind_I: statement = this.ParseStoreIndirect(CoreSystemTypes.IntPtr); goto done;
+ case OpCode.Conv_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U, CoreSystemTypes.UIntPtr); break;
+ case OpCode.Arglist: expr = new Expression(NodeType.Arglist, CoreSystemTypes.ArgIterator); break;
+ case OpCode.Ceq: expr = this.ParseBinaryComparison(NodeType.Ceq); break;
+ case OpCode.Cgt: expr = this.ParseBinaryComparison(NodeType.Cgt); break;
+ case OpCode.Cgt_Un: expr = this.ParseBinaryComparison(NodeType.Cgt_Un); break;
+ case OpCode.Clt: expr = this.ParseBinaryComparison(NodeType.Clt); break;
+ case OpCode.Clt_Un: expr = this.ParseBinaryComparison(NodeType.Clt_Un); break;
+ case OpCode.Ldftn: expr = new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldftn, CoreSystemTypes.IntPtr); break;
+ case OpCode.Ldvirtftn: expr = new BinaryExpression(PopOperand(), new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldvirtftn, CoreSystemTypes.IntPtr); break;
+ case OpCode.Ldarg: expr = this.Parameters((ushort)this.GetInt16()); break;
+ case OpCode.Ldarga: expr = SetType(new UnaryExpression(this.Parameters((ushort)this.GetInt16()), NodeType.AddressOf)); break;
+ case OpCode.Starg: statement = new AssignmentStatement(this.Parameters((ushort)this.GetInt16()), PopOperand()); goto done;
+ case OpCode.Ldloc: expr = this.locals[(ushort)this.GetInt16()]; break;
+ case OpCode.Ldloca: expr = SetType(new UnaryExpression(this.locals[(ushort)this.GetInt16()], NodeType.AddressOf)); break;
+ case OpCode.Stloc: statement = new AssignmentStatement(this.locals[(ushort)this.GetInt16()], PopOperand()); goto done;
+ case OpCode.Localloc: expr = new UnaryExpression(PopOperand(), NodeType.Localloc, CoreSystemTypes.Void); break;
+ case OpCode.Endfilter: statement = new EndFilter(PopOperand()); transferStatement = true; goto done;
+ case OpCode.Unaligned_: this.alignment = this.GetByte(); continue;
+ case OpCode.Volatile_: this.isVolatile = true; continue;
+ case OpCode.Tail_: this.isTailCall = true; continue;
+ case OpCode.Initobj: statement = this.ParseInitObject(); goto done;
+ case OpCode.Constrained_: this.constraint = this.GetMemberFromToken() as TypeNode; continue;
+ case OpCode.Cpblk: expr = this.ParseTernaryOperation(NodeType.Cpblk); goto done;
+ case OpCode.Initblk: expr = this.ParseTernaryOperation(NodeType.Initblk); goto done;
+ case OpCode.Rethrow: statement = new Throw(null); statement.NodeType = NodeType.Rethrow; transferStatement = true; goto done;
+ case OpCode.Sizeof: expr = new UnaryExpression(new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Sizeof, CoreSystemTypes.Int32); break;
+ case OpCode.Refanytype: expr = new UnaryExpression(PopOperand(), NodeType.Refanytype, CoreSystemTypes.RuntimeTypeHandle); break;
+ case OpCode.Readonly_: this.isReadOnly = true; continue;
+ default: throw new InvalidMetadataException(ExceptionStrings.UnknownOpCode);
+ }
+ if (this.blockMap[this.counter + 1] != null)
+ {
+ transferStatement = true; //Falls through to the next basic block, so implicitly a "transfer" statement
+ goto done;
+ }
+ //^ assume expr != null;
+#if FxCop
+ expr.sourceContext = sourceContext;
+ expr.ILOffset = this.ilOffset;
+#endif
+ this.operandStack.Push(expr);
+ this.isReadOnly = false;
+ this.isVolatile = false;
+ this.isTailCall = false;
+ this.alignment = -1;
+ }
+ done:
+ for (int i = 0; i <= this.operandStack.top; i++)
+ {
+ Expression e = this.operandStack.elements[i];
+ //^ assume e != null;
+ Statement s = new ExpressionStatement(e);
+#if FxCop
+ s.SourceContext = this.sourceContext;
+ s.ILOffset = this.ilOffset;
+#endif
+ statementList.Add(s);
+ }
+ this.operandStack.top = -1;
+ if (statement == null)
+ {
+ statement = new ExpressionStatement(expr);
+#if FxCop
+ expr.SourceContext = this.sourceContext;
+ expr.ILOffset = this.ilOffset;
+#endif
+ }
+ statement.SourceContext = sourceContext;
+#if FxCop
+ statement.ILOffset = this.ilOffset;
+#endif
+ statementList.Add(statement);
+ if (transferStatement) return true;
+ return this.blockMap[this.counter + 1] != null;
+ }
+ private AssignmentStatement ParseStoreField()
+ {
+ Expression rhvalue = PopOperand();
+ Expression thisob = PopOperand();
+ AssignmentStatement s = new AssignmentStatement(new MemberBinding(thisob, this.GetMemberFromToken(), this.isVolatile, this.alignment), rhvalue);
+ return s;
+ }
+ private AssignmentStatement ParseStoreIndirect(TypeNode type)
+ {
+ Expression rhvalue = PopOperand();
+ Expression lhaddr = PopOperand();
+ return new AssignmentStatement(new AddressDereference(lhaddr, type, this.isVolatile, this.alignment), rhvalue);
+ }
+ private SwitchInstruction ParseSwitchInstruction()
+ {
+ int numTargets = this.GetInt32();
+ int offset = this.counter + numTargets * 4;
+ BlockList targetList = new BlockList(numTargets);
+ for (int i = 0; i < numTargets; i++)
+ {
+ int targetAddress = this.GetInt32() + offset;
+ targetList.Add(Reader.GetOrCreateBlock(this.blockMap, targetAddress));
+ }
+ return new SwitchInstruction(PopOperand(), targetList);
+ }
+ private TernaryExpression ParseTernaryOperation(NodeType oper)
+ {
+ Expression op3 = PopOperand();
+ Expression op2 = PopOperand();
+ Expression op1 = PopOperand();
+ return new TernaryExpression(op1, op2, op3, oper, null);
+ }
+ private void CreateBlocksForBranchTargets()
+ {
+ int savedPosition = bodyReader.Position;
+ while (this.counter < this.size)
+ this.ProcessOneILInstruction();
+ this.counter = 0;
+ bodyReader.Position = savedPosition;
+ }
+ private void ProcessOneILInstruction()
+ {
+ OpCode opc = this.GetOpCode();
+ switch (opc)
+ {
+ case OpCode.Ldarg_S:
+ case OpCode.Ldarga_S:
+ case OpCode.Starg_S:
+ case OpCode.Ldloc_S:
+ case OpCode.Ldloca_S:
+ case OpCode.Stloc_S:
+ case OpCode.Ldc_I4_S:
+ this.GetByte(); return;
+ case OpCode.Ldc_I4:
+ case OpCode.Jmp:
+ case OpCode.Call:
+ case OpCode.Calli:
+ case OpCode.Callvirt:
+ case OpCode.Cpobj:
+ case OpCode.Ldobj:
+ case OpCode.Ldstr:
+ case OpCode.Newobj:
+ case OpCode.Castclass:
+ case OpCode.Isinst:
+ case OpCode.Unbox:
+ case OpCode.Ldfld:
+ case OpCode.Ldflda:
+ case OpCode.Stfld:
+ case OpCode.Ldsfld:
+ case OpCode.Ldsflda:
+ case OpCode.Stsfld:
+ case OpCode.Stobj:
+ case OpCode.Box:
+ case OpCode.Newarr:
+ case OpCode.Ldelema:
+ case OpCode.Ldelem:
+ case OpCode.Stelem:
+ case OpCode.Unbox_Any:
+ case OpCode.Refanyval:
+ case OpCode.Mkrefany:
+ case OpCode.Ldtoken:
+ this.GetInt32(); return;
+ case OpCode.Ldc_I8:
+ this.GetInt64(); return;
+ case OpCode.Ldc_R4:
+ this.GetSingle(); return;
+ case OpCode.Ldc_R8:
+ this.GetDouble(); return;
+ case OpCode.Br_S:
+ case OpCode.Brfalse_S:
+ case OpCode.Brtrue_S:
+ case OpCode.Beq_S:
+ case OpCode.Bge_S:
+ case OpCode.Bgt_S:
+ case OpCode.Ble_S:
+ case OpCode.Blt_S:
+ case OpCode.Bne_Un_S:
+ case OpCode.Bge_Un_S:
+ case OpCode.Bgt_Un_S:
+ case OpCode.Ble_Un_S:
+ case OpCode.Blt_Un_S:
+ case OpCode.Leave_S:
+ this.SkipBranch(true); return;
+ case OpCode.Br:
+ case OpCode.Brfalse:
+ case OpCode.Brtrue:
+ case OpCode.Beq:
+ case OpCode.Bge:
+ case OpCode.Bgt:
+ case OpCode.Ble:
+ case OpCode.Blt:
+ case OpCode.Bne_Un:
+ case OpCode.Bge_Un:
+ case OpCode.Bgt_Un:
+ case OpCode.Ble_Un:
+ case OpCode.Blt_Un:
+ case OpCode.Leave:
+ this.SkipBranch(false); return;
+ case OpCode.Switch:
+ this.SkipSwitch(); return;
+ case OpCode.Ldftn:
+ case OpCode.Ldvirtftn:
+ case OpCode.Initobj:
+ case OpCode.Constrained_:
+ case OpCode.Sizeof:
+ this.GetInt32(); return;
+ case OpCode.Ldarg:
+ case OpCode.Ldarga:
+ case OpCode.Ldloc:
+ case OpCode.Ldloca:
+ case OpCode.Starg:
+ case OpCode.Stloc:
+ this.GetInt16(); return;
+ case OpCode.Unaligned_:
+ this.GetByte(); return;
+ default:
+ return;
+ }
+ }
+ private void SkipBranch(bool shortOffset)
+ {
+ int offset = shortOffset ? this.GetSByte() : this.GetInt32();
+ Reader.GetOrCreateBlock(blockMap, this.counter + offset);
+ }
+ private void SkipSwitch()
+ {
+ int numCases = this.GetInt32();
+ int offset = this.counter + numCases * 4;
+ for (int i = 0; i < numCases; i++)
+ {
+ int targetAddress = this.GetInt32() + offset;
+ Reader.GetOrCreateBlock(this.blockMap, targetAddress);
+ }
+ }
+ private Expression PopOperand()
+ {
+ return this.operandStack.Pop();
+ }
+#if FxCop
+ private OpCode opCode;
+ private Block currentBlock;
+ private SourceContext sourceContext;
+ private int ilOffset;
+ private Dictionary<Block, List<TryNode>> tryMap;
+ private Dictionary<int, Expression> handlerMap;
+ internal StatementList/*!*/ ParseStatements() {
+ this.tryMap = new Dictionary<Block, List<TryNode>>();
+ this.handlerMap = new Dictionary<int, Expression>();
+ this.ParseHeader();
+ this.CreateBlocksForBranchTargets();
+ currentBlock = null;
+ this.sourceContext = new SourceContext();
+ while (this.counter < size) {
+ if (currentBlock == null) {
+ currentBlock = Reader.GetOrCreateBlock(this.blockMap, this.counter);
+ }
+ bool endOfBasicBlock = this.ParseStatement(currentBlock);
+ if (endOfBasicBlock) {
+ currentBlock.SourceContext = currentBlock.Statements[0].SourceContext;
+ currentBlock = null;
+ }
+ }
+ Reader.GetOrCreateBlock(this.blockMap, this.counter);
+ int counter = 0;
+ Block block = new Block();
+ block.Statements = new StatementList();
+ ProcessBlock(block, ref counter, this.size, null);
+ return block.Statements;
+ }
+ override protected void ParseExceptionHandlerEntry(bool smallSection) {
+ int dataSize = this.reader.tables.GetByte();
+ int n = (int)(ushort)this.reader.tables.GetInt16();
+ if (smallSection)
+ n = dataSize / 12;
+ else
+ n = (dataSize + (n << 8)) / 24;
+ for (int i = 0; i < n; i++) {
+ int flags, tryOffset, tryLength, handlerOffset, handlerLength, tokenOrOffset;
+ if (smallSection) {
+ flags = this.reader.tables.GetInt16();
+ tryOffset = this.reader.tables.GetUInt16();
+ tryLength = this.reader.tables.GetByte();
+ handlerOffset = this.reader.tables.GetUInt16();
+ handlerLength = this.reader.tables.GetByte();
+ }
+ else {
+ flags = this.reader.tables.GetInt32();
+ tryOffset = this.reader.tables.GetInt32();
+ tryLength = this.reader.tables.GetInt32();
+ handlerOffset = this.reader.tables.GetInt32();
+ handlerLength = this.reader.tables.GetInt32();
+ }
+ tokenOrOffset = this.reader.tables.GetInt32();
+ Block tryStartBlock = Reader.GetOrCreateBlock(this.blockMap, tryOffset);
+ Block blockAfterTryEnd = Reader.GetOrCreateBlock(this.blockMap, tryOffset + tryLength);
+ Block handlerStartBlock = Reader.GetOrCreateBlock(this.blockMap, handlerOffset);
+ Block blockAfterHandlerEnd = Reader.GetOrCreateBlock(this.blockMap, handlerOffset + handlerLength);
+ List<TryNode> tryList = null;
+ if (!this.tryMap.TryGetValue(tryStartBlock, out tryList)) {
+ this.tryMap[tryStartBlock] = tryList = new List<TryNode>();
+ }
+ TryNode currentTry = null;
+ int tryEnd = tryOffset + tryLength;
+ foreach (TryNode t in tryList) {
+ if (t.tryEnd == tryEnd) {
+ currentTry = t;
+ break;
+ }
+ }
+ if (currentTry == null) {
+ currentTry = new TryNode();
+ currentTry.tryEnd = tryEnd;
+ tryList.Add(currentTry);
+ }
+ int handlerEnd = handlerOffset + handlerLength;
+ if (currentTry.handlersEnd < handlerEnd)
+ currentTry.handlersEnd = handlerEnd;
+
+ Debug.Assert((int)flags != 3);
+ Debug.Assert((int)flags < 5);
+
+ switch (flags) {
+ case 0x00:
+ // for a catch handler, tokenOrOffset represents
+ // the metadata token of the handler type. handlerOffset
+ // is the literal offset for the catch block
+ int pos = this.reader.tables.GetCurrentPosition();
+ TypeNode filterType = (TypeNode)this.reader.GetMemberFromToken(tokenOrOffset);
+ this.reader.tables.SetCurrentPosition(pos);
+ string variableName = "$exception" + this.handlerMap.Count.ToString(CultureInfo.InvariantCulture);
+ StackVariable exception = new StackVariable(filterType, variableName);
+ CatchNode c = new CatchNode(handlerStartBlock, exception, filterType);
+ c.handlerEnd = handlerEnd;
+ currentTry.Catchers.Add(c);
+ this.handlerMap[handlerOffset] = exception;
+ break;
+ case 0x01:
+ // for a filter, tokenOrOffset represents the IL offset
+ // of the filter block. handlerOffset represents
+ // the IL offset of the associated catch handler
+ Block filterExpression = Reader.GetOrCreateBlock(blockMap, tokenOrOffset);
+ variableName = "$exception" + this.handlerMap.Count.ToString(CultureInfo.InvariantCulture);
+ exception = new StackVariable(CoreSystemTypes.Object, variableName);
+ Filter filter = new Filter(filterExpression, exception);
+ filter.handlerEnd = handlerOffset;
+ c = new CatchNode(handlerStartBlock, exception, null, filter);
+ c.handlerEnd = handlerEnd;
+ currentTry.Catchers.Add(c);
+ // note that handlerOffset would not be correct here!
+ this.handlerMap[tokenOrOffset] = exception;
+ break;
+ case 0x02:
+ FinallyNode f = new FinallyNode(handlerStartBlock);
+ f.handlerEnd = handlerEnd;
+ currentTry.Finally = f;
+ break;
+ case 0x04:
+ FaultHandler fh = new FaultHandler(handlerStartBlock);
+ fh.handlerEnd = handlerEnd;
+ currentTry.FaultHandler = fh;
+ break;
+ }
+ }
+ }
+ private void ProcessBlock(Block currentBlock, ref int counter, int blockEnd, Node blockNode) {
+ while (true) {
+ int lastCounter = counter;
+ Block block = GetNextBlock(ref counter);
+ if (block == null || block.ILOffset >= blockEnd) {
+ counter = lastCounter;
+ if (blockNode != null)
+ blockNode.SourceContext = currentBlock.Statements[0].SourceContext;
+ return;
+ }
+ if (this.tryMap.ContainsKey(block)) {
+ ProcessTryBlock(currentBlock, block, ref counter);
+ }
+ else {
+ if (currentBlock.Statements.Count == 0)
+ currentBlock.SourceContext = block.SourceContext;
+ currentBlock.Statements.Add(block);
+ }
+ }
+ }
+ private void ProcessTryBlock(Block outerBlock, Block currentBlock, ref int counter) {
+ List<TryNode> tryList = this.tryMap[currentBlock];
+ TryNode outerTry = tryList[tryList.Count - 1];
+ outerBlock.Statements.Add(outerTry);
+ tryList.Remove(outerTry);
+ if (tryList.Count > 0) {
+ outerTry.Block = new Block();
+ outerTry.Block.Statements = new StatementList();
+ ProcessTryBlock(outerTry.Block, currentBlock, ref counter);
+ }
+ else {
+ outerTry.Block = currentBlock;
+ }
+ this.tryMap.Remove(currentBlock);
+ ProcessBlock(outerTry.Block, ref counter, outerTry.tryEnd, outerTry);
+ while (true) {
+ int lastCounter = counter;
+ Block block = GetNextBlock(ref counter);
+ if (counter >= outerTry.handlersEnd) {
+ counter = lastCounter;
+ return;
+ }
+ int handlerEnd;
+ Node handlerNode;
+ GetHandlerEnd(outerTry, block, out handlerEnd, out handlerNode);
+ ProcessBlock(block, ref counter, handlerEnd, handlerNode);
+ }
+ }
+ private Block GetNextBlock(ref int counter) {
+ while (true) {
+ Block result = this.blockMap[counter + 1] as Block;
+ ++counter;
+ if (result != null || counter >= this.size)
+ return result;
+ }
+ }
+ private void GetHandlerEnd(TryNode t, Block block, out int handlerEnd, out Node handlerNode) {
+ handlerEnd = Int32.MaxValue;
+ handlerNode = null;
+ int startPos = block.ILOffset;
+ if (t.Finally != null
+ && t.Finally.handlerEnd > startPos
+ && t.Finally.handlerEnd < handlerEnd) {
+ handlerEnd = t.Finally.handlerEnd;
+ handlerNode = t.Finally;
+ }
+ foreach (CatchNode c in t.Catchers) {
+ if (c.handlerEnd > startPos && c.handlerEnd < handlerEnd) {
+ handlerEnd = c.handlerEnd;
+ handlerNode = c;
+ }
+ if (c.Filter != null && c.Filter.handlerEnd > startPos && c.Filter.handlerEnd < handlerEnd) {
+ handlerEnd = c.Filter.handlerEnd;
+ handlerNode = c.Filter;
+ }
+ }
+ if (t.FaultHandler != null
+ && t.FaultHandler.handlerEnd > startPos
+ && t.FaultHandler.handlerEnd < handlerEnd) {
+ handlerEnd = t.FaultHandler.handlerEnd;
+ handlerNode = t.FaultHandler;
+ }
+ }
+#endif
+ }
+ internal class InstructionParser : ILParser
+ {
+ private readonly TrivialHashtable/*!*/ ehMap;
+ internal InstructionParser(Reader/*!*/ reader, Method/*!*/ method, int methodIndex, int RVA)
+ : base(reader, method, methodIndex, RVA)
+ {
+ this.ehMap = new TrivialHashtable();
+ }
+ override protected void ParseExceptionHandlerEntry(bool smallSection)
+ {
+ TrivialHashtable tryMap = new TrivialHashtable();
+ int dataSize = this.reader.tables.GetByte();
+ int n = (int)(ushort)this.reader.tables.GetInt16();
+ if (smallSection)
+ n = dataSize / 12;
+ else
+ n = (dataSize + (n << 8)) / 24;
+ for (int i = 0; i < n; i++)
+ {
+ Instruction matchingInstruction;
+ int flags, tryOffset, tryLength, handlerOffset, handlerLength, tokenOrOffset;
+ if (smallSection)
+ {
+ flags = this.reader.tables.GetInt16();
+ tryOffset = this.reader.tables.GetUInt16();
+ tryLength = this.reader.tables.GetByte();
+ handlerOffset = this.reader.tables.GetUInt16();
+ handlerLength = this.reader.tables.GetByte();
+ }
+ else
+ {
+ flags = this.reader.tables.GetInt32();
+ tryOffset = this.reader.tables.GetInt32();
+ tryLength = this.reader.tables.GetInt32();
+ handlerOffset = this.reader.tables.GetInt32();
+ handlerLength = this.reader.tables.GetInt32();
+ }
+ tokenOrOffset = this.reader.tables.GetInt32();
+ if (tryMap[tryOffset + tryLength] == null)
+ {
+ matchingInstruction = this.AddInstruction(OpCode._Try, tryOffset);
+ this.AddInstruction(OpCode._EndTry, tryOffset + tryLength, matchingInstruction);
+ tryMap[tryOffset + tryLength] = String.Empty;
+ }
+ switch (flags)
+ {
+ case 0x00:
+ int pos = this.reader.tables.GetCurrentPosition();
+ TypeNode catchType = (TypeNode)this.reader.GetMemberFromToken(tokenOrOffset);
+ this.reader.tables.SetCurrentPosition(pos);
+ matchingInstruction = this.AddInstruction(OpCode._Catch, handlerOffset, catchType);
+ this.AddInstruction(OpCode._EndHandler, handlerOffset + handlerLength, matchingInstruction);
+ break;
+ case 0x01:
+ matchingInstruction = this.AddInstruction(OpCode._Filter, tokenOrOffset);
+ this.AddInstruction(OpCode._EndFilter, handlerOffset, matchingInstruction);
+ matchingInstruction = this.AddInstruction(OpCode._Catch, handlerOffset);
+ this.AddInstruction(OpCode._EndHandler, handlerOffset + handlerLength, matchingInstruction);
+ break;
+ case 0x02:
+ matchingInstruction = this.AddInstruction(OpCode._Finally, handlerOffset);
+ this.AddInstruction(OpCode._EndHandler, handlerOffset + handlerLength, matchingInstruction);
+ break;
+ case 0x04:
+ matchingInstruction = this.AddInstruction(OpCode._Fault, handlerOffset);
+ this.AddInstruction(OpCode._EndHandler, handlerOffset + handlerLength, matchingInstruction);
+ break;
+ default: throw new InvalidMetadataException(ExceptionStrings.BadExceptionHandlerType);
+ }
+ }
+ }
+ private Instruction AddInstruction(OpCode opCode, int offset)
+ {
+ return this.AddInstruction(opCode, offset, null);
+ }
+ private Instruction AddInstruction(OpCode opCode, int offset, object value)
+ {
+ Instruction instruction = new Instruction(opCode, offset, value);
+ InstructionList instructions = (InstructionList)this.ehMap[offset + 1];
+ if (instructions == null) this.ehMap[offset + 1] = instructions = new InstructionList(2);
+ instructions.Add(instruction);
+#if !ROTOR
+ if (this.method.contextForOffset != null)
+ {
+ object sctx = this.method.contextForOffset[offset + 1];
+ if (sctx != null) instruction.SourceContext = (SourceContext)sctx;
+ }
+#endif
+ return instruction;
+ }
+ private Int32List ParseSwitchInstruction()
+ {
+ int numTargets = this.GetInt32();
+ Int32List result = new Int32List(numTargets);
+ int offset = this.counter + numTargets * 4;
+ for (int i = 0; i < numTargets; i++)
+ {
+ int targetAddress = this.GetInt32() + offset;
+ result.Add(targetAddress);
+ }
+ return result;
+ }
+ internal InstructionList ParseInstructions()
+ {
+ this.ParseHeader();
+ if (this.size == 0) return new InstructionList(0);
+ InstructionList result = new InstructionList();
+ result.Add(new Instruction(OpCode._Locals, 0, this.locals));
+ while (this.counter <= size)
+ {
+ InstructionList instructions = (InstructionList)this.ehMap[this.counter + 1];
+ if (instructions != null)
+ {
+ for (int i = 0; i < instructions.Count; i++)
+ result.Add(instructions[i]);
+ }
+ if (this.counter < size)
+ result.Add(this.ParseInstruction());
+ else
+ break;
+ }
+ return result;
+ }
+ private SourceContext sourceContext = new SourceContext();
+ internal Instruction ParseInstruction()
+ {
+ if (this.counter >= this.size)
+ return null;
+ int offset = this.counter;
+#if !ROTOR
+ if (this.method.contextForOffset != null)
+ {
+ object sctx = this.method.contextForOffset[offset + 1];
+ if (sctx != null) this.sourceContext = (SourceContext)sctx;
+ }
+#endif
+ object value = null;
+ OpCode opCode = this.GetOpCode();
+ switch (opCode)
+ {
+ case OpCode.Nop:
+ case OpCode.Break:
+ break;
+ case OpCode.Ldarg_0: value = this.Parameters(0); break;
+ case OpCode.Ldarg_1: value = this.Parameters(1); break;
+ case OpCode.Ldarg_2: value = this.Parameters(2); break;
+ case OpCode.Ldarg_3: value = this.Parameters(3); break;
+ case OpCode.Ldloc_0: value = this.locals[0]; break;
+ case OpCode.Ldloc_1: value = this.locals[1]; break;
+ case OpCode.Ldloc_2: value = this.locals[2]; break;
+ case OpCode.Ldloc_3: value = this.locals[3]; break;
+ case OpCode.Stloc_0: value = this.locals[0]; break;
+ case OpCode.Stloc_1: value = this.locals[1]; break;
+ case OpCode.Stloc_2: value = this.locals[2]; break;
+ case OpCode.Stloc_3: value = this.locals[3]; break;
+ case OpCode.Ldarg_S:
+ case OpCode.Ldarga_S:
+ case OpCode.Starg_S:
+ value = this.Parameters(this.GetByte()); break;
+ case OpCode.Ldloc_S:
+ case OpCode.Ldloca_S:
+ case OpCode.Stloc_S:
+ value = this.locals[this.GetByte()]; break;
+ case OpCode.Ldnull:
+ break;
+ case OpCode.Ldc_I4_M1: value = (Int32)(-1); break;
+ case OpCode.Ldc_I4_0: value = (Int32)0; break;
+ case OpCode.Ldc_I4_1: value = (Int32)1; break;
+ case OpCode.Ldc_I4_2: value = (Int32)2; break;
+ case OpCode.Ldc_I4_3: value = (Int32)3; break;
+ case OpCode.Ldc_I4_4: value = (Int32)4; break;
+ case OpCode.Ldc_I4_5: value = (Int32)5; break;
+ case OpCode.Ldc_I4_6: value = (Int32)6; break;
+ case OpCode.Ldc_I4_7: value = (Int32)7; break;
+ case OpCode.Ldc_I4_8: value = (Int32)8; break;
+ case OpCode.Ldc_I4_S: value = (Int32)this.GetSByte(); break;
+ case OpCode.Ldc_I4: value = this.GetInt32(); break;
+ case OpCode.Ldc_I8: value = this.GetInt64(); break;
+ case OpCode.Ldc_R4: value = this.GetSingle(); break;
+ case OpCode.Ldc_R8: value = this.GetDouble(); break;
+ case OpCode.Dup:
+ case OpCode.Pop:
+ break;
+ case OpCode.Jmp:
+ case OpCode.Call:
+ value = (Method)this.GetMemberFromToken(); break;
+ case OpCode.Calli:
+ value = (FunctionPointer)this.reader.GetCalliSignature(this.GetInt32()); break;
+ case OpCode.Ret: break;
+ case OpCode.Br_S:
+ case OpCode.Brfalse_S:
+ case OpCode.Brtrue_S:
+ case OpCode.Beq_S:
+ case OpCode.Bge_S:
+ case OpCode.Bgt_S:
+ case OpCode.Ble_S:
+ case OpCode.Blt_S:
+ case OpCode.Bne_Un_S:
+ case OpCode.Bge_Un_S:
+ case OpCode.Bgt_Un_S:
+ case OpCode.Ble_Un_S:
+ case OpCode.Blt_Un_S:
+ value = this.counter + 1 + this.GetSByte(); break;
+ case OpCode.Br:
+ case OpCode.Brfalse:
+ case OpCode.Brtrue:
+ case OpCode.Beq:
+ case OpCode.Bge:
+ case OpCode.Bgt:
+ case OpCode.Ble:
+ case OpCode.Blt:
+ case OpCode.Bne_Un:
+ case OpCode.Bge_Un:
+ case OpCode.Bgt_Un:
+ case OpCode.Ble_Un:
+ case OpCode.Blt_Un:
+ value = this.counter + 4 + this.GetInt32(); break;
+ case OpCode.Switch: value = this.ParseSwitchInstruction(); break;
+ case OpCode.Ldind_I1:
+ case OpCode.Ldind_U1:
+ case OpCode.Ldind_I2:
+ case OpCode.Ldind_U2:
+ case OpCode.Ldind_I4:
+ case OpCode.Ldind_U4:
+ case OpCode.Ldind_I8:
+ case OpCode.Ldind_I:
+ case OpCode.Ldind_R4:
+ case OpCode.Ldind_R8:
+ case OpCode.Ldind_Ref:
+ case OpCode.Stind_Ref:
+ case OpCode.Stind_I1:
+ case OpCode.Stind_I2:
+ case OpCode.Stind_I4:
+ case OpCode.Stind_I8:
+ case OpCode.Stind_R4:
+ case OpCode.Stind_R8:
+ case OpCode.Add:
+ case OpCode.Sub:
+ case OpCode.Mul:
+ case OpCode.Div:
+ case OpCode.Div_Un:
+ case OpCode.Rem:
+ case OpCode.Rem_Un:
+ case OpCode.And:
+ case OpCode.Or:
+ case OpCode.Xor:
+ case OpCode.Shl:
+ case OpCode.Shr:
+ case OpCode.Shr_Un:
+ case OpCode.Neg:
+ case OpCode.Not:
+ case OpCode.Conv_I1:
+ case OpCode.Conv_I2:
+ case OpCode.Conv_I4:
+ case OpCode.Conv_I8:
+ case OpCode.Conv_R4:
+ case OpCode.Conv_R8:
+ case OpCode.Conv_U4:
+ case OpCode.Conv_U8:
+ break;
+ case OpCode.Callvirt: value = (Method)this.GetMemberFromToken(); break;
+ case OpCode.Cpobj:
+ case OpCode.Ldobj:
+ value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Ldstr: value = this.GetStringFromToken(); break;
+ case OpCode.Newobj: value = (Method)this.GetMemberFromToken(); break;
+ case OpCode.Castclass:
+ case OpCode.Isinst:
+ value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Conv_R_Un: break;
+ case OpCode.Unbox: value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Throw: break;
+ case OpCode.Ldfld:
+ case OpCode.Ldflda:
+ case OpCode.Stfld:
+ case OpCode.Ldsfld:
+ case OpCode.Ldsflda:
+ case OpCode.Stsfld:
+ case OpCode.Stobj:
+ value = this.GetMemberFromToken(); break;
+ case OpCode.Conv_Ovf_I1_Un:
+ case OpCode.Conv_Ovf_I2_Un:
+ case OpCode.Conv_Ovf_I4_Un:
+ case OpCode.Conv_Ovf_I8_Un:
+ case OpCode.Conv_Ovf_U1_Un:
+ case OpCode.Conv_Ovf_U2_Un:
+ case OpCode.Conv_Ovf_U4_Un:
+ case OpCode.Conv_Ovf_U8_Un:
+ case OpCode.Conv_Ovf_I_Un:
+ case OpCode.Conv_Ovf_U_Un:
+ break;
+ case OpCode.Box:
+ case OpCode.Newarr: value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Ldlen: break;
+ case OpCode.Ldelema: value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Ldelem_I1:
+ case OpCode.Ldelem_U1:
+ case OpCode.Ldelem_I2:
+ case OpCode.Ldelem_U2:
+ case OpCode.Ldelem_I4:
+ case OpCode.Ldelem_U4:
+ case OpCode.Ldelem_I8:
+ case OpCode.Ldelem_I:
+ case OpCode.Ldelem_R4:
+ case OpCode.Ldelem_R8:
+ case OpCode.Ldelem_Ref:
+ case OpCode.Stelem_I:
+ case OpCode.Stelem_I1:
+ case OpCode.Stelem_I2:
+ case OpCode.Stelem_I4:
+ case OpCode.Stelem_I8:
+ case OpCode.Stelem_R4:
+ case OpCode.Stelem_R8:
+ case OpCode.Stelem_Ref:
+ break;
+ case OpCode.Ldelem:
+ value = (TypeNode)this.GetMemberFromToken();
+ break;
+ case OpCode.Stelem: value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Unbox_Any: value = this.GetMemberFromToken(); break;
+ case OpCode.Conv_Ovf_I1:
+ case OpCode.Conv_Ovf_U1:
+ case OpCode.Conv_Ovf_I2:
+ case OpCode.Conv_Ovf_U2:
+ case OpCode.Conv_Ovf_I4:
+ case OpCode.Conv_Ovf_U4:
+ case OpCode.Conv_Ovf_I8:
+ case OpCode.Conv_Ovf_U8:
+ break;
+ case OpCode.Refanyval: value = this.GetMemberFromToken(); break;
+ case OpCode.Ckfinite: break;
+ case OpCode.Mkrefany: value = this.GetMemberFromToken(); break;
+ case OpCode.Ldtoken: value = this.GetMemberFromToken(); break;
+ case OpCode.Conv_U2:
+ case OpCode.Conv_U1:
+ case OpCode.Conv_I:
+ case OpCode.Conv_Ovf_I:
+ case OpCode.Conv_Ovf_U:
+ case OpCode.Add_Ovf:
+ case OpCode.Add_Ovf_Un:
+ case OpCode.Mul_Ovf:
+ case OpCode.Mul_Ovf_Un:
+ case OpCode.Sub_Ovf:
+ case OpCode.Sub_Ovf_Un:
+ case OpCode.Endfinally:
+ break;
+ case OpCode.Leave: value = this.counter + 4 + this.GetInt32(); break;
+ case OpCode.Leave_S: value = this.counter + 1 + this.GetSByte(); break;
+ case OpCode.Stind_I:
+ case OpCode.Conv_U:
+ case OpCode.Prefix7:
+ case OpCode.Prefix6:
+ case OpCode.Prefix5:
+ case OpCode.Prefix4:
+ case OpCode.Prefix3:
+ case OpCode.Prefix2:
+ case OpCode.Prefix1:
+ case OpCode.Arglist:
+ case OpCode.Ceq:
+ case OpCode.Cgt:
+ case OpCode.Cgt_Un:
+ case OpCode.Clt:
+ case OpCode.Clt_Un:
+ break;
+ case OpCode.Ldftn:
+ case OpCode.Ldvirtftn:
+ value = this.GetMemberFromToken(); break;
+ case OpCode.Ldarg:
+ case OpCode.Ldarga:
+ case OpCode.Starg:
+ value = this.Parameters(this.GetInt16()); break;
+ case OpCode.Ldloc:
+ case OpCode.Ldloca:
+ case OpCode.Stloc:
+ value = this.locals[this.GetInt16()]; break;
+ case OpCode.Localloc:
+ case OpCode.Endfilter:
+ break;
+ case OpCode.Unaligned_: value = this.GetByte(); break;
+ case OpCode.Volatile_:
+ case OpCode.Tail_:
+ break;
+ case OpCode.Initobj: value = (TypeNode)this.GetMemberFromToken(); break;
+ case OpCode.Constrained_: value = this.GetMemberFromToken() as TypeNode; break;
+ case OpCode.Cpblk:
+ case OpCode.Initblk:
+ break;
+ case OpCode.Rethrow:
+ break;
+ case OpCode.Sizeof: value = this.GetMemberFromToken(); break;
+ case OpCode.Refanytype:
+ case OpCode.Readonly_:
+ break;
+ default: throw new InvalidMetadataException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.UnknownOpCodeEncountered, opCode.ToString("x")));
+ }
+ Instruction instruction = new Instruction(opCode, offset, value);
+ instruction.SourceContext = this.sourceContext;
+ return instruction;
+ }
+ }
+ internal class ExpressionStack
+ {
+ internal Expression[]/*!*/ elements = new Expression[64];
+ internal int top = -1;
+
+ internal ExpressionStack()
+ {
+ //^ base();
+ }
+
+ private void Grow()
+ {
+ int n = this.elements.Length;
+ Expression[] newElements = new Expression[n + 64];
+ for (int i = 0; i < n; i++) newElements[i] = this.elements[i];
+ this.elements = newElements;
+ }
+ internal Expression/*!*/ Pop()
+ {
+ if (this.top < 0) return new Expression(NodeType.Pop);
+ Expression e = this.elements[this.top--];
+ //^ assume e != null;
+ return e;
+ }
+ internal void Push(Expression/*!*/ e)
+ {
+ if (++this.top >= this.elements.Length) this.Grow();
+ this.elements[this.top] = e;
+ }
+ }
+ /// <summary>
+ /// A thin wrapper for a synchronized System.Collections.Hashtable that inserts and strips WeakReference wrappers for the values stored in the table.
+ /// </summary>
+ internal class SynchronizedWeakDictionary : IDictionary
+ {
+ private Hashtable/*!*/ Hashtable = System.Collections.Hashtable.Synchronized(new Hashtable());
+
+ internal SynchronizedWeakDictionary()
+ {
+ //^ base();
+ }
+
+ public void Add(object/*!*/ key, object value)
+ {
+ this.Hashtable.Add(key, new WeakReference(value));
+ }
+ public void Clear()
+ {
+ this.Hashtable.Clear();
+ }
+ public bool Contains(object/*!*/ key)
+ {
+ return this.Hashtable.Contains(key);
+ }
+ public IDictionaryEnumerator/*!*/ GetEnumerator()
+ {
+ return this.Hashtable.GetEnumerator();
+ }
+ public bool IsFixedSize
+ {
+ get { return false; }
+ }
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+ public ICollection/*!*/ Keys
+ {
+ get { return this.Hashtable.Keys; }
+ }
+ public void Remove(object/*!*/ key)
+ {
+ this.Hashtable.Remove(key);
+ }
+ public ICollection/*!*/ Values
+ {
+ get { return new WeakValuesCollection(this.Hashtable.Values); }
+ }
+ public object this[object/*!*/ key]
+ {
+ get
+ {
+ WeakReference wref = (WeakReference)this.Hashtable[key];
+ if (wref == null) return null;
+ return wref.Target;
+ }
+ set
+ {
+ this.Hashtable[key] = new WeakReference(value);
+ }
+ }
+ public void CopyTo(Array/*!*/ array, int index)
+ {
+ IEnumerator enumerator = this.GetEnumerator();
+ for (int i = 0; enumerator.MoveNext(); i++)
+ array.SetValue(enumerator.Current, index + i);
+ }
+ public int Count
+ {
+ get { return this.Hashtable.Count; }
+ }
+ public bool IsSynchronized
+ {
+ get { return false; }
+ }
+ public object/*!*/ SyncRoot
+ {
+ get { return this.Hashtable.SyncRoot; }
+ }
+ IEnumerator/*!*/ IEnumerable.GetEnumerator()
+ {
+ return new WeakValuesEnumerator(this.Hashtable.GetEnumerator());
+ }
+ }
+ internal class WeakValuesCollection : ICollection
+ {
+ private ICollection/*!*/ collection;
+
+ internal WeakValuesCollection(ICollection/*!*/ collection)
+ {
+ this.collection = collection;
+ //^ base();
+ }
+
+ public void CopyTo(Array/*!*/ array, int index)
+ {
+ IEnumerator enumerator = this.GetEnumerator();
+ for (int i = 0; enumerator.MoveNext(); i++)
+ array.SetValue(enumerator.Current, index + i);
+ }
+ public int Count
+ {
+ get { return this.collection.Count; }
+ }
+ public bool IsSynchronized
+ {
+ get { return this.collection.IsSynchronized; }
+ }
+ public object/*!*/ SyncRoot
+ {
+ get { return this.collection.SyncRoot; }
+ }
+ public IEnumerator/*!*/ GetEnumerator()
+ {
+ return new WeakValuesEnumerator(this.collection.GetEnumerator());
+ }
+ }
+ internal class WeakValuesEnumerator : IEnumerator
+ {
+ private IEnumerator/*!*/ enumerator;
+
+ internal WeakValuesEnumerator(IEnumerator/*!*/ enumerator)
+ {
+ this.enumerator = enumerator;
+ //^ base();
+ }
+
+ public object Current
+ {
+ get
+ {
+ object curr = this.enumerator.Current;
+ if (curr is DictionaryEntry)
+ {
+ DictionaryEntry dicEntry = (DictionaryEntry)curr;
+ curr = dicEntry.Value;
+ }
+ WeakReference wref = curr as WeakReference;
+ if (wref != null) return wref.Target;
+ return null;
+ }
+ }
+ public bool MoveNext()
+ {
+ return this.enumerator.MoveNext();
+ }
+ public void Reset()
+ {
+ this.enumerator.Reset();
+ }
+ }
+#if !ROTOR && NoWriter
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
+ internal interface IMetaDataImport{}
+ internal class EmptyImporter : IMetaDataImport{}
+#endif
+#if FxCop
+ class StackVariable : Local {
+ internal StackVariable(TypeNode type, string name)
+ : base(type) {
+ this.NodeType = NodeType.StackVariable;
+ this.Name = Identifier.For(name);
+ }
+ internal StackVariable(TypeNode type, int index)
+ : base(type) {
+ this.NodeType = NodeType.StackVariable;
+ this.Name = Identifier.For("stack$" + index.ToString(CultureInfo.InvariantCulture));
+ }
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/Specializer.cs b/tools/Sandcastle/Source/CCI/Specializer.cs
new file mode 100644
index 0000000..d651883
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Specializer.cs
@@ -0,0 +1,1054 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Diagnostics;
+#if FxCop
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using MemberList = Microsoft.Cci.MemberCollection;
+using MethodList = Microsoft.Cci.MethodCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Module = Microsoft.Cci.ModuleNode;
+using Class = Microsoft.Cci.ClassNode;
+using Interface = Microsoft.Cci.InterfaceNode;
+#endif
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ /* Specializer walks an IR, replacing references to type parameters with references to actual types.
+ * The main complication is that structural types involving type parameters need to be reconstructed.
+ * Other complications arise from the fact that IL is not orthogonal and requires different instructions
+ * to be used depending on whether a type is a reference type or a value type. In templates, type parameters
+ * are treated as reference types when method bodies are generated. In order to instantiate a template with
+ * a value type argument, it is necessary to walk the method bodies and transform some expressions. This is
+ * not possible to do in a single pass because method bodies can contain references to signatures defined
+ * in parts of the IR that have not yet been visited and specialized. Consequently, Specializer ignores
+ * method bodies.
+ *
+ * Once all signatures have been fixed up by Specializer, it is necessary to use MethodBodySpecializer
+ * to walk the method bodies and fix up the IL to deal with value types that replaced type parameters.
+ * Another complication to deal with is that MemberBindings and NameBindings can refer to members
+ * defined in structural types based on type parameters. These must be substituted with references to the
+ * corresponding members of structural types based on the type arguments. Note that some structural types
+ * are themselves implemented as templates.
+ */
+
+ /// <summary>
+ /// This class specializes a normalized IR by replacing type parameters with type arguments.
+ /// </summary>
+#if !FxCop
+ public
+#endif
+ class Specializer : StandardVisitor
+ {
+ public TypeNodeList pars;
+ public TypeNodeList args;
+ public Method CurrentMethod;
+ public TypeNode CurrentType;
+ public Module TargetModule;
+
+ public Specializer(Module targetModule, TypeNodeList pars, TypeNodeList args)
+ {
+ Debug.Assert(pars != null && pars.Count > 0);
+ Debug.Assert(args != null && args.Count > 0);
+ this.pars = pars;
+ this.args = args;
+ this.TargetModule = targetModule;
+ }
+#if !MinimalReader
+ public Specializer(Visitor callingVisitor)
+ : base(callingVisitor)
+ {
+ }
+ public override void TransferStateTo(Visitor targetVisitor)
+ {
+ base.TransferStateTo(targetVisitor);
+ Specializer target = targetVisitor as Specializer;
+ if (target == null) return;
+ target.args = this.args;
+ target.pars = this.pars;
+ target.CurrentMethod = this.CurrentMethod;
+ target.CurrentType = this.CurrentType;
+ }
+#endif
+ public override DelegateNode VisitDelegateNode(DelegateNode delegateNode)
+ {
+ return this.VisitTypeNode(delegateNode) as DelegateNode;
+ }
+ public override Interface VisitInterfaceReference(Interface Interface)
+ {
+ return this.VisitTypeReference(Interface) as Interface;
+ }
+ public virtual Member VisitMemberReference(Member member)
+ {
+ if (member == null) return null;
+#if false && !MinimalReader
+ ParameterField pField = member as ParameterField;
+ if (pField != null){
+ if (pField.Parameter != null) pField.Type = pField.Parameter.Type;
+ return pField;
+ }
+#endif
+ TypeNode specializedType = this.VisitTypeReference(member.DeclaringType);
+ if (specializedType == member.DeclaringType || specializedType == null) return member;
+ return Specializer.GetCorrespondingMember(member, specializedType);
+ }
+ public static Member GetCorrespondingMember(Member/*!*/ member, TypeNode/*!*/ specializedType)
+ {
+ //member belongs to a structural type based on a type parameter.
+ //return the corresponding member from the structural type based on the type argument.
+ if (member.DeclaringType == null) { Debug.Fail(""); return null; }
+ MemberList unspecializedMembers = member.DeclaringType.Members;
+ MemberList specializedMembers = specializedType.Members;
+ if (unspecializedMembers == null || specializedMembers == null) { Debug.Assert(false); return null; }
+ int unspecializedOffset = 0;
+ int specializedOffset = 0;
+ //The offsets can become > 0 when the unspecialized type and/or specialized type is imported from another assembly
+ //(and the unspecialized type is in fact a partially specialized type.)
+ for (int i = 0, n = specializedMembers == null ? 0 : specializedMembers.Count; i < n; i++)
+ {
+ Member unspecializedMember = unspecializedMembers[i - unspecializedOffset];
+ Member specializedMember = specializedMembers[i - specializedOffset];
+ if (unspecializedMember != null && specializedMember == null && unspecializedOffset == i &&
+ !(unspecializedMember is TypeParameter || unspecializedMember is ClassParameter))
+ {
+ unspecializedOffset++; continue; //Keep current unspecialized member, skip over null specialized member
+ }
+ if (unspecializedMember == null && specializedMember != null && specializedOffset == i &&
+ !(specializedMember is TypeParameter || specializedMember is ClassParameter))
+ {
+ specializedOffset++; continue; //Keep current specialized member, skip over null
+ }
+ if (unspecializedMember == member)
+ {
+ Debug.Assert(specializedMember != null);
+ return specializedMember;
+ }
+ }
+ Debug.Assert(false);
+ return null;
+ }
+ public readonly Block DummyBody = new Block();
+ public override Method VisitMethod(Method method)
+ {
+ if (method == null) return null;
+ Method savedCurrentMethod = this.CurrentMethod;
+ TypeNode savedCurrentType = this.CurrentType;
+ this.CurrentMethod = method;
+ this.CurrentType = method.DeclaringType;
+ method.ThisParameter = (This)this.VisitThis(method.ThisParameter);
+ method.Attributes = this.VisitAttributeList(method.Attributes);
+ method.ReturnAttributes = this.VisitAttributeList(method.ReturnAttributes);
+ method.SecurityAttributes = this.VisitSecurityAttributeList(method.SecurityAttributes);
+ method.ReturnType = this.VisitTypeReference(method.ReturnType);
+#if !MinimalReader
+ method.ImplementedTypes = this.VisitTypeReferenceList(method.ImplementedTypes);
+#endif
+ method.Parameters = this.VisitParameterList(method.Parameters);
+ if (TargetPlatform.UseGenerics && this.args != method.TemplateArguments)
+ {
+ method.TemplateArguments = this.VisitTypeReferenceList(method.TemplateArguments);
+ method.TemplateParameters = this.VisitTypeParameterList(method.TemplateParameters);
+ }
+#if ExtendedRuntime
+ method.Contract = this.VisitMethodContract(method.Contract);
+#endif
+ method.ImplementedInterfaceMethods = this.VisitMethodList(method.ImplementedInterfaceMethods);
+ this.CurrentMethod = savedCurrentMethod;
+ this.CurrentType = savedCurrentType;
+ return method;
+ }
+#if ExtendedRuntime
+ public override MethodContract VisitMethodContract(MethodContract contract){
+ if (contract == null) return null;
+ if (contract.Specializer == null) {
+ contract.Specializer = new MethodContract.ContractSpecializerDelegate(this.VisitContractPart);
+ contract.ensures = null;
+ contract.modifies = null;
+ contract.requires = null;
+ } else {
+ contract.ensures = this.VisitEnsuresList(contract.ensures);
+ contract.modifies = this.VisitExpressionList(contract.modifies);
+ contract.requires = this.VisitRequiresList(contract.requires);
+ }
+ return contract;
+ }
+ private object VisitContractPart(Method method, object part) {
+ if (method == null) { Debug.Fail("method == null"); return part; }
+ this.CurrentMethod = method;
+ this.CurrentType = method.DeclaringType;
+ EnsuresList es = part as EnsuresList;
+ if (es != null) return this.VisitEnsuresList(es);
+ RequiresList rs = part as RequiresList;
+ if (rs != null) return this.VisitRequiresList(rs);
+ return part;
+ }
+#endif
+ public virtual MethodList VisitMethodList(MethodList methods)
+ {
+ if (methods == null) return null;
+ int n = methods.Count;
+ for (int i = 0; i < n; i++)
+ methods[i] = (Method)this.VisitMemberReference(methods[i]);
+ return methods;
+ }
+ public override TypeNode VisitTypeNode(TypeNode typeNode)
+ {
+ if (typeNode == null) return null;
+ TypeNode savedCurrentType = this.CurrentType;
+ if (savedCurrentType != null && savedCurrentType.TemplateArguments != null && savedCurrentType.TemplateArguments.Count > 0 &&
+ typeNode.Template != null && (typeNode.Template.TemplateParameters == null || typeNode.Template.TemplateParameters.Count == 0))
+ {
+ typeNode.TemplateArguments = new TypeNodeList(0);
+ }
+ this.CurrentType = typeNode;
+ typeNode.Attributes = this.VisitAttributeList(typeNode.Attributes);
+ typeNode.SecurityAttributes = this.VisitSecurityAttributeList(typeNode.SecurityAttributes);
+ Class c = typeNode as Class;
+ if (c != null) c.BaseClass = (Class)this.VisitTypeReference(c.BaseClass);
+ typeNode.Interfaces = this.VisitInterfaceReferenceList(typeNode.Interfaces);
+ if (typeNode.ProvideTypeMembers != null && typeNode.ProvideNestedTypes != null && typeNode.ProviderHandle != null)
+ {
+ typeNode.members = null;
+ typeNode.ProviderHandle = new SpecializerHandle(typeNode.ProvideNestedTypes, typeNode.ProvideTypeMembers, typeNode.ProviderHandle);
+ typeNode.ProvideNestedTypes = new TypeNode.NestedTypeProvider(this.ProvideNestedTypes);
+ typeNode.ProvideTypeMembers = new TypeNode.TypeMemberProvider(this.ProvideTypeMembers);
+#if !MinimalReader
+ DelegateNode delegateNode = typeNode as DelegateNode;
+ if (delegateNode != null)
+ {
+ if (!delegateNode.IsNormalized)
+ { //In the Normalized case Parameters are retrieved from the Invoke method, which means evaluating Members
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ }
+ }
+#endif
+ }
+ else
+ {
+ typeNode.Members = this.VisitMemberList(typeNode.Members);
+ DelegateNode delegateNode = typeNode as DelegateNode;
+ if (delegateNode != null)
+ {
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ }
+ }
+ this.CurrentType = savedCurrentType;
+ return typeNode;
+ }
+ private void ProvideNestedTypes(TypeNode/*!*/ typeNode, object/*!*/ handle)
+ {
+ SpecializerHandle sHandler = (SpecializerHandle)handle;
+ TypeNode savedCurrentType = this.CurrentType;
+ this.CurrentType = typeNode;
+ sHandler.NestedTypeProvider(typeNode, sHandler.Handle);
+ TypeNodeList nestedTypes = typeNode.nestedTypes;
+ for (int i = 0, n = nestedTypes == null ? 0 : nestedTypes.Count; i < n; i++)
+ {
+ //^ assert nestedTypes != null;
+ TypeNode nt = nestedTypes[i];
+ if (nt == null) continue;
+ this.VisitTypeNode(nt);
+ }
+ this.CurrentType = savedCurrentType;
+ }
+ private void ProvideTypeMembers(TypeNode/*!*/ typeNode, object/*!*/ handle)
+ {
+ SpecializerHandle sHandler = (SpecializerHandle)handle;
+ TypeNode savedCurrentType = this.CurrentType;
+ this.CurrentType = typeNode;
+ sHandler.TypeMemberProvider(typeNode, sHandler.Handle);
+ typeNode.Members = this.VisitMemberList(typeNode.Members);
+ DelegateNode delegateNode = typeNode as DelegateNode;
+ if (delegateNode != null && delegateNode.IsNormalized)
+ {
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ }
+ this.CurrentType = savedCurrentType;
+ }
+ internal class SpecializerHandle
+ {
+ internal TypeNode.NestedTypeProvider/*!*/ NestedTypeProvider;
+ internal TypeNode.TypeMemberProvider/*!*/ TypeMemberProvider;
+ internal object/*!*/ Handle;
+ internal SpecializerHandle(TypeNode.NestedTypeProvider/*!*/ nestedTypeProvider, TypeNode.TypeMemberProvider/*!*/ typeMemberProvider, object/*!*/ handle)
+ {
+ this.NestedTypeProvider = nestedTypeProvider;
+ this.TypeMemberProvider = typeMemberProvider;
+ this.Handle = handle;
+ //^ base();
+ }
+ }
+ public virtual Expression VisitTypeExpression(Expression expr)
+ {
+ TypeNodeList pars = this.pars;
+ TypeNodeList args = this.args;
+ Identifier id = expr as Identifier;
+ if (id != null)
+ {
+ int key = id.UniqueIdKey;
+ for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++)
+ {
+ //^ assert pars != null && args != null;
+ TypeNode par = pars[i];
+ if (par == null || par.Name == null) continue;
+ if (par.Name.UniqueIdKey == key) return new Literal(args[i], CoreSystemTypes.Type);
+ }
+ return id;
+ }
+#if !MinimalReader
+ Debug.Assert(expr is QualifiedIdentifier || expr is Literal);
+#endif
+ return expr;
+ }
+ public override TypeNode VisitTypeParameter(TypeNode typeParameter)
+ {
+ if (typeParameter == null) return null;
+ if (TargetPlatform.UseGenerics)
+ {
+ InterfaceList interfaces = typeParameter.Interfaces;
+ if (interfaces == null || interfaces.Count == 0) return typeParameter;
+ TypeNode baseType = this.VisitTypeReference(interfaces[0]);
+ if (baseType is Interface)
+ typeParameter.Interfaces = this.VisitInterfaceReferenceList(typeParameter.Interfaces);
+ else
+ typeParameter = this.ConvertToClassParameter(baseType, typeParameter);
+ return typeParameter;
+ }
+ else
+ {
+ typeParameter.Interfaces = this.VisitInterfaceReferenceList(typeParameter.Interfaces);
+ return null;
+ }
+ }
+ private TypeNode ConvertToClassParameter(TypeNode baseType, TypeNode/*!*/ typeParameter)
+ {
+ ClassParameter result;
+ if (typeParameter is MethodTypeParameter)
+ {
+ result = new MethodClassParameter();
+ }
+ else if (typeParameter is TypeParameter)
+ {
+ result = new ClassParameter();
+ result.DeclaringType = typeParameter.DeclaringType;
+ }
+ else
+ return typeParameter; //give up
+ result.SourceContext = typeParameter.SourceContext;
+ result.TypeParameterFlags = ((ITypeParameter)typeParameter).TypeParameterFlags;
+#if ExtendedRuntime
+ if (typeParameter.IsUnmanaged) { result.SetIsUnmanaged(); }
+#endif
+ result.Name = typeParameter.Name;
+ result.Namespace = StandardIds.ClassParameter;
+ result.BaseClass = baseType is Class ? (Class)baseType : CoreSystemTypes.Object;
+ result.DeclaringMember = ((ITypeParameter)typeParameter).DeclaringMember;
+ result.DeclaringModule = typeParameter.DeclaringModule;
+ result.Flags = typeParameter.Flags & ~TypeFlags.Interface;
+ //InterfaceList contraints = result.Interfaces = new InterfaceList();
+ InterfaceList interfaces = typeParameter.Interfaces;
+ for (int i = 1, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ //^ assert interfaces != null;
+ interfaces.Add(this.VisitInterfaceReference(interfaces[i]));
+ }
+ return result;
+ }
+ public override TypeNode VisitTypeReference(TypeNode type)
+ { //TODO: break up this method
+ if (type == null) return null;
+ TypeNodeList pars = this.pars;
+ TypeNodeList args = this.args;
+ switch (type.NodeType)
+ {
+ case NodeType.ArrayType:
+ ArrayType arrType = (ArrayType)type;
+ TypeNode elemType = this.VisitTypeReference(arrType.ElementType);
+ if (elemType == arrType.ElementType || elemType == null) return arrType;
+ if (arrType.IsSzArray()) return elemType.GetArrayType(1);
+ return elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds);
+#if !MinimalReader
+ case NodeType.DelegateNode:
+ {
+ FunctionType ftype = type as FunctionType;
+ if (ftype == null) goto default;
+ TypeNode referringType = ftype.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(ftype.DeclaringType);
+ return FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), referringType);
+ }
+#endif
+ case NodeType.Pointer:
+ Pointer pType = (Pointer)type;
+ elemType = this.VisitTypeReference(pType.ElementType);
+ if (elemType == pType.ElementType || elemType == null) return pType;
+ return elemType.GetPointerType();
+ case NodeType.Reference:
+ Reference rType = (Reference)type;
+ elemType = this.VisitTypeReference(rType.ElementType);
+ if (elemType == rType.ElementType || elemType == null) return rType;
+ return elemType.GetReferenceType();
+#if ExtendedRuntime
+ case NodeType.TupleType:{
+ TupleType tType = (TupleType)type;
+ bool reconstruct = false;
+ MemberList members = tType.Members;
+ int n = members == null ? 0 : members.Count;
+ FieldList fields = new FieldList(n);
+ for (int i = 0; i < n; i++){
+ //^ assert members != null;
+ Field f = members[i] as Field;
+ if (f == null) continue;
+ f = (Field)f.Clone();
+ fields.Add(f);
+ TypeNode oft = f.Type;
+ TypeNode ft = f.Type = this.VisitTypeReference(f.Type);
+ if (ft != oft) reconstruct = true;
+ }
+ if (!reconstruct) return tType;
+ TypeNode referringType = tType.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tType.DeclaringType);
+ return TupleType.For(fields, referringType);}
+ case NodeType.TypeIntersection:{
+ TypeIntersection tIntersect = (TypeIntersection)type;
+ TypeNode referringType = tIntersect.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tIntersect.DeclaringType);
+ return TypeIntersection.For(this.VisitTypeReferenceList(tIntersect.Types), referringType);}
+ case NodeType.TypeUnion:{
+ TypeUnion tUnion = (TypeUnion)type;
+ TypeNode referringType = tUnion.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(tUnion.DeclaringType);
+ TypeNodeList types = this.VisitTypeReferenceList(tUnion.Types);
+ if (referringType == null || types == null) { Debug.Fail(""); return null; }
+ return TypeUnion.For(types, referringType);}
+#endif
+#if !MinimalReader
+ case NodeType.ArrayTypeExpression:
+ ArrayTypeExpression aExpr = (ArrayTypeExpression)type;
+ aExpr.ElementType = this.VisitTypeReference(aExpr.ElementType);
+ return aExpr;
+ case NodeType.BoxedTypeExpression:
+ BoxedTypeExpression bExpr = (BoxedTypeExpression)type;
+ bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType);
+ return bExpr;
+ case NodeType.ClassExpression:
+ {
+ ClassExpression cExpr = (ClassExpression)type;
+ cExpr.Expression = this.VisitTypeExpression(cExpr.Expression);
+ Literal lit = cExpr.Expression as Literal; //Could happen if the expression is a template parameter
+ if (lit != null) return lit.Value as TypeNode;
+ cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments);
+ return cExpr;
+ }
+#endif
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ int key = type.UniqueKey;
+ for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++)
+ {
+ //^ assert pars != null && args != null;
+ TypeNode tp = pars[i];
+ if (tp == null) continue;
+ if (tp.UniqueKey == key) return args[i];
+ if (tp.Name.UniqueIdKey == type.Name.UniqueIdKey && (tp is ClassParameter && type is TypeParameter))
+ {
+ //This shouldn't really happen, but in practice it does. Hack past it.
+ return args[i];
+ }
+ }
+ return type;
+#if ExtendedRuntime
+ case NodeType.ConstrainedType:{
+ ConstrainedType conType = (ConstrainedType)type;
+ TypeNode referringType = conType.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(conType.DeclaringType);
+ TypeNode underlyingType = this.VisitTypeReference(conType.UnderlyingType);
+ Expression constraint = this.VisitExpression(conType.Constraint);
+ if (referringType == null || underlyingType == null || constraint == null) { Debug.Fail(""); return null; }
+ return new ConstrainedType(underlyingType, constraint, referringType);}
+#endif
+#if !MinimalReader
+ case NodeType.FlexArrayTypeExpression:
+ FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type;
+ flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType);
+ return flExpr;
+ case NodeType.FunctionTypeExpression:
+ FunctionTypeExpression ftExpr = (FunctionTypeExpression)type;
+ ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters);
+ ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType);
+ return ftExpr;
+ case NodeType.InvariantTypeExpression:
+ InvariantTypeExpression invExpr = (InvariantTypeExpression)type;
+ invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType);
+ return invExpr;
+#endif
+ case NodeType.InterfaceExpression:
+ InterfaceExpression iExpr = (InterfaceExpression)type;
+ if (iExpr.Expression == null) goto default;
+ iExpr.Expression = this.VisitTypeExpression(iExpr.Expression);
+ iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments);
+ return iExpr;
+#if !MinimalReader
+ case NodeType.NonEmptyStreamTypeExpression:
+ NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type;
+ neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType);
+ return neExpr;
+ case NodeType.NonNullTypeExpression:
+ NonNullTypeExpression nnExpr = (NonNullTypeExpression)type;
+ nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType);
+ return nnExpr;
+ case NodeType.NonNullableTypeExpression:
+ NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type;
+ nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType);
+ return nbExpr;
+ case NodeType.NullableTypeExpression:
+ NullableTypeExpression nuExpr = (NullableTypeExpression)type;
+ nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType);
+ return nuExpr;
+#endif
+ case NodeType.OptionalModifier:
+ {
+ TypeModifier modType = (TypeModifier)type;
+ TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
+ TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
+ if (modifiedType == null || modifierType == null) { return type; }
+#if ExtendedRuntime
+ if (modifierType != null && modifierType == SystemTypes.NullableType){
+ if (modifiedType.IsValueType) return modifiedType;
+ if (TypeNode.HasModifier(modifiedType, SystemTypes.NonNullType))
+ modifiedType = TypeNode.StripModifier(modifiedType, SystemTypes.NonNullType);
+ if (modifiedType.IsTemplateParameter) {
+ return OptionalModifier.For(modifierType, modifiedType);
+ }
+ return modifiedType;
+ }
+ if (modifierType == SystemTypes.NonNullType) {
+ if (modifiedType.IsValueType) return modifiedType;
+ modifiedType = TypeNode.StripModifier(modifiedType, SystemTypes.NonNullType);
+ }
+ //^ assert modifiedType != null;
+#endif
+ return OptionalModifier.For(modifierType, modifiedType);
+ }
+ case NodeType.RequiredModifier:
+ {
+ TypeModifier modType = (TypeModifier)type;
+ TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType);
+ TypeNode modifierType = this.VisitTypeReference(modType.Modifier);
+ if (modifiedType == null || modifierType == null) { Debug.Fail(""); return type; }
+ return RequiredModifier.For(modifierType, modifiedType);
+ }
+#if !MinimalReader
+ case NodeType.OptionalModifierTypeExpression:
+ OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type;
+ optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType);
+ optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier);
+ return optmodType;
+ case NodeType.RequiredModifierTypeExpression:
+ RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type;
+ reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType);
+ reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier);
+ return reqmodType;
+ case NodeType.PointerTypeExpression:
+ PointerTypeExpression pExpr = (PointerTypeExpression)type;
+ pExpr.ElementType = this.VisitTypeReference(pExpr.ElementType);
+ return pExpr;
+ case NodeType.ReferenceTypeExpression:
+ ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type;
+ rExpr.ElementType = this.VisitTypeReference(rExpr.ElementType);
+ return rExpr;
+ case NodeType.StreamTypeExpression:
+ StreamTypeExpression sExpr = (StreamTypeExpression)type;
+ sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType);
+ return sExpr;
+ case NodeType.TupleTypeExpression:
+ TupleTypeExpression tuExpr = (TupleTypeExpression)type;
+ tuExpr.Domains = this.VisitFieldList(tuExpr.Domains);
+ return tuExpr;
+ case NodeType.TypeExpression:
+ {
+ TypeExpression tExpr = (TypeExpression)type;
+ tExpr.Expression = this.VisitTypeExpression(tExpr.Expression);
+ if (tExpr.Expression is Literal) return type;
+ tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments);
+ return tExpr;
+ }
+ case NodeType.TypeIntersectionExpression:
+ TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type;
+ tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types);
+ return tiExpr;
+ case NodeType.TypeUnionExpression:
+ TypeUnionExpression tyuExpr = (TypeUnionExpression)type;
+ tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types);
+ return tyuExpr;
+#endif
+ default:
+ TypeNode declaringType = this.VisitTypeReference(type.DeclaringType);
+ if (declaringType != null)
+ {
+ Identifier tname = type.Name;
+ if (type.Template != null && type.IsGeneric) tname = type.Template.Name;
+ TypeNode nt = declaringType.GetNestedType(tname);
+ if (nt != null)
+ {
+ TypeNodeList arguments = type.TemplateArguments;
+ type = nt;
+ if (TargetPlatform.UseGenerics)
+ {
+ if (arguments != null && arguments.Count > 0 && nt.ConsolidatedTemplateParameters != null && nt.ConsolidatedTemplateParameters.Count > 0)
+ type = nt.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, arguments);
+ }
+ }
+ }
+ if (type.Template != null && (type.ConsolidatedTemplateParameters == null || type.ConsolidatedTemplateParameters.Count == 0))
+ {
+ if (!type.IsNotFullySpecialized && (!type.IsNormalized ||
+ (this.CurrentType != null && type.DeclaringModule == this.CurrentType.DeclaringModule))) return type;
+ //Type is a template instance, but some of its arguments were themselves parameters.
+ //See if any of these parameters are to be specialized by this specializer.
+ bool mustSpecializeFurther = false;
+ TypeNodeList targs = type.TemplateArguments;
+ int numArgs = targs == null ? 0 : targs.Count;
+ if (targs != null)
+ {
+ targs = targs.Clone();
+ for (int i = 0; i < numArgs; i++)
+ {
+ TypeNode targ = targs[i];
+ ITypeParameter tparg = targ as ITypeParameter;
+ if (tparg != null)
+ {
+ for (int j = 0, np = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; j < np && j < m; j++)
+ {
+ //^ assert pars != null && args != null;
+ if (TargetPlatform.UseGenerics)
+ {
+ ITypeParameter par = pars[j] as ITypeParameter;
+ if (par == null) continue;
+ if (tparg == par || (tparg.ParameterListIndex == par.ParameterListIndex && tparg.DeclaringMember == par.DeclaringMember))
+ {
+ targ = this.args[j]; break;
+ }
+ }
+ else
+ {
+ if (targ == pars[j]) { targ = this.args[j]; break; }
+ }
+ }
+ }
+ else
+ {
+ if (targ != type)
+ targ = this.VisitTypeReference(targ);
+ if (targ == type) continue;
+ }
+ mustSpecializeFurther |= targs[i] != targ;
+ targs[i] = targ;
+ }
+ }
+ if (targs == null || !mustSpecializeFurther) return type;
+ return type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs);
+ }
+ TypeNodeList tPars = type.TemplateParameters;
+ if (tPars == null || tPars.Count == 0) return type; //Not a parameterized type. No need to get an instance.
+ TypeNodeList tArgs = new TypeNodeList();
+ for (int i = 0, n = tPars.Count; i < n; i++)
+ {
+ TypeNode tPar = tPars[i];
+ tArgs.Add(tPar); //Leave parameter in place if there is no match
+ if (tPar == null || tPar.Name == null) continue;
+ int idKey = tPar.Name.UniqueIdKey;
+ for (int j = 0, m = pars == null ? 0 : pars.Count, k = args == null ? 0 : args.Count; j < m && j < k; j++)
+ {
+ //^ assert pars != null && args != null;
+ TypeNode par = pars[j];
+ if (par == null || par.Name == null) continue;
+ if (par.Name.UniqueIdKey == idKey)
+ {
+ tArgs[i] = args[j];
+ break;
+ }
+ }
+ }
+ return type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs);
+ }
+ }
+ }
+#if !NoWriter
+ public class MethodBodySpecializer : Specializer
+ {
+ public TrivialHashtable/*!*/ alreadyVisitedNodes = new TrivialHashtable();
+ public Method methodBeingSpecialized;
+ public Method dummyMethod;
+
+ public MethodBodySpecializer(Module module, TypeNodeList pars, TypeNodeList args)
+ : base(module, pars, args)
+ {
+ //^ base;
+ }
+#if !MinimalReader
+ public MethodBodySpecializer(Visitor callingVisitor)
+ : base(callingVisitor)
+ {
+ //^ base;
+ }
+#endif
+ public override Node Visit(Node node)
+ {
+ Literal lit = node as Literal;
+ if (lit != null && lit.Value == null) return lit;
+ Expression e = node as Expression;
+ if (e != null && !(e is Local || e is Parameter))
+ e.Type = this.VisitTypeReference(e.Type);
+ return base.Visit(node);
+ }
+
+ public override Expression VisitAddressDereference(AddressDereference addr)
+ {
+ if (addr == null) return null;
+ bool unboxDeref = addr.Address != null && addr.Address.NodeType == NodeType.Unbox;
+ addr.Address = this.VisitExpression(addr.Address);
+ if (addr.Address == null) return null;
+ if (unboxDeref && addr.Address.NodeType != NodeType.Unbox) return addr.Address;
+ Reference reference = addr.Address.Type as Reference;
+ if (reference != null) addr.Type = reference.ElementType;
+ return addr;
+ }
+ public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
+ {
+ assignment = (AssignmentStatement)base.VisitAssignmentStatement(assignment);
+ if (assignment == null) return null;
+ Expression target = assignment.Target;
+ Expression source = assignment.Source;
+ TypeNode tType = target == null ? null : target.Type;
+ TypeNode sType = source == null ? null : source.Type;
+ if (tType != null && sType != null)
+ {
+ //^ assert target != null;
+ if (tType.IsValueType)
+ {
+ if (sType is Reference)
+ assignment.Source = new AddressDereference(source, tType);
+ else if (!sType.IsValueType && !(sType == CoreSystemTypes.Object && source is Literal && target.NodeType == NodeType.AddressDereference))
+ assignment.Source = new AddressDereference(new BinaryExpression(source, new MemberBinding(null, sType), NodeType.Unbox), sType);
+ }
+ else
+ {
+ if (sType.IsValueType)
+ {
+ if (!(tType is Reference))
+ assignment.Source = new BinaryExpression(source, new MemberBinding(null, sType), NodeType.Box, tType);
+ }
+ }
+ }
+ return assignment;
+ }
+ public override Expression VisitBinaryExpression(BinaryExpression binaryExpression)
+ {
+ if (binaryExpression == null) return null;
+ bool opnd1IsInst = binaryExpression.Operand1 != null && binaryExpression.Operand1.NodeType == NodeType.Isinst;
+ binaryExpression = (BinaryExpression)base.VisitBinaryExpression(binaryExpression);
+ if (binaryExpression == null) return null;
+ Expression opnd1 = binaryExpression.Operand1;
+ Expression opnd2 = binaryExpression.Operand2;
+ Literal lit = opnd2 as Literal;
+ TypeNode t = lit == null ? null : lit.Value as TypeNode;
+ if (binaryExpression.NodeType == NodeType.Castclass /*|| binaryExpression.NodeType == NodeType.ExplicitCoercion*/)
+ {
+ //See if castclass must become box or unbox
+ if (t != null)
+ {
+ if (t.IsValueType)
+ {
+ AddressDereference adref = new AddressDereference(new BinaryExpression(opnd1, lit, NodeType.Unbox), t);
+ adref.Type = t;
+ return adref;
+ }
+ if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
+ {
+ return new BinaryExpression(opnd1, new MemberBinding(null, opnd1.Type), NodeType.Box, t);
+ }
+ }
+ }
+ else if (binaryExpression.NodeType == NodeType.Unbox)
+ {
+ if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
+ return opnd1;
+#if ExtendedRuntime
+ }else if (binaryExpression.NodeType == NodeType.Box){
+ if (t != null && t.IsReferenceType && !t.IsPointerType) { // using pointer types is a Sing# extension
+ return opnd1;
+ }
+#endif
+ }
+ else if (binaryExpression.NodeType == NodeType.Eq)
+ {
+ //For value types, turn comparisons against null into false
+ if (lit != null && lit.Value == null && opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
+ return Literal.False;
+ lit = opnd1 as Literal;
+ if (lit != null && lit.Value == null && opnd2 != null && opnd2.Type != null && opnd2.Type.IsValueType)
+ return Literal.False;
+ }
+ else if (binaryExpression.NodeType == NodeType.Ne)
+ {
+ //For value types, turn comparisons against null into true
+ if (lit != null && lit.Value == null && opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
+ {
+ if (opnd1IsInst && opnd1.Type == CoreSystemTypes.Boolean) return opnd1;
+ return Literal.True;
+ }
+ lit = opnd1 as Literal;
+ if (lit != null && lit.Value == null && opnd2 != null && opnd2.Type != null && opnd2.Type.IsValueType)
+ return Literal.True;
+ }
+ else if (binaryExpression.NodeType == NodeType.Isinst)
+ {
+ //Do not emit isinst instruction if opnd1 is a value type.
+ if (opnd1 != null && opnd1.Type != null && opnd1.Type.IsValueType)
+ {
+ if (opnd1.Type == t)
+ return Literal.True;
+ else
+ return Literal.False;
+ }
+ }
+ return binaryExpression;
+ }
+ public override Statement VisitBranch(Branch branch)
+ {
+ branch = (Branch)base.VisitBranch(branch);
+ if (branch == null) return null;
+ if (branch.Condition != null && !(branch.Condition is BinaryExpression))
+ {
+ //Deal with implicit comparisons against null
+ TypeNode ct = branch.Condition.Type;
+ if (ct != null && !ct.IsPrimitiveInteger && ct != CoreSystemTypes.Boolean && ct.IsValueType)
+ {
+ if (branch.Condition.NodeType == NodeType.LogicalNot)
+ return null;
+ branch.Condition = null;
+ }
+ }
+ return branch;
+ }
+ public override Expression VisitExpression(Expression expression)
+ {
+ if (expression == null) return null;
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ case NodeType.Arglist:
+ expression.Type = this.VisitTypeReference(expression.Type);
+ return expression;
+ case NodeType.Pop:
+ expression.Type = this.VisitTypeReference(expression.Type);
+ UnaryExpression uex = expression as UnaryExpression;
+ if (uex != null)
+ {
+ uex.Operand = this.VisitExpression(uex.Operand);
+ return uex;
+ }
+ return expression;
+ default:
+ return (Expression)this.Visit(expression);
+ }
+ }
+ public override Expression VisitIndexer(Indexer indexer)
+ {
+ indexer = (Indexer)base.VisitIndexer(indexer);
+ if (indexer == null || indexer.Object == null) return null;
+ ArrayType arrType = indexer.Object.Type as ArrayType;
+ TypeNode elemType = null;
+ if (arrType != null) elemType = indexer.Type = indexer.ElementType = arrType.ElementType;
+ //if (elemType != null && elemType.IsValueType && !elemType.IsPrimitive)
+ //return new AddressDereference(new UnaryExpression(indexer, NodeType.AddressOf), elemType);
+ return indexer;
+ }
+ public override Expression VisitLiteral(Literal literal)
+ {
+ if (literal == null) return null;
+ TypeNode t = literal.Value as TypeNode;
+ if (t != null && literal.Type == CoreSystemTypes.Type)
+ return new Literal(this.VisitTypeReference(t), literal.Type, literal.SourceContext);
+ return (Literal)literal.Clone();
+ }
+ public override Expression VisitLocal(Local local)
+ {
+ if (local == null) return null;
+ if (this.alreadyVisitedNodes[local.UniqueKey] != null) return local;
+ this.alreadyVisitedNodes[local.UniqueKey] = local;
+ return base.VisitLocal(local);
+ }
+#if !MinimalReader
+ public override Statement VisitLocalDeclarationsStatement(LocalDeclarationsStatement localDeclarations)
+ {
+ if (localDeclarations == null) return null;
+ localDeclarations.Type = this.VisitTypeReference(localDeclarations.Type);
+ return localDeclarations;
+ }
+#endif
+ public override Expression VisitParameter(Parameter parameter)
+ {
+#if !MinimalReader
+ ParameterBinding pb = parameter as ParameterBinding;
+ if (pb != null && pb.BoundParameter != null)
+ pb.Type = pb.BoundParameter.Type;
+#endif
+ return parameter;
+ }
+#if !MinimalReader
+ public override Expression VisitNameBinding(NameBinding nameBinding)
+ {
+ if (nameBinding == null) return null;
+ nameBinding.BoundMember = this.VisitExpression(nameBinding.BoundMember);
+ int n = nameBinding.BoundMembers == null ? 0 : nameBinding.BoundMembers.Count;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert nameBinding.BoundMembers != null;
+ nameBinding.BoundMembers[i] = this.VisitMemberReference(nameBinding.BoundMembers[i]);
+ }
+ return nameBinding;
+ }
+#endif
+ public override Expression VisitMemberBinding(MemberBinding memberBinding)
+ {
+ if (memberBinding == null) return null;
+ Expression tObj = memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject);
+ Member mem = this.VisitMemberReference(memberBinding.BoundMember);
+ if (mem == this.dummyMethod)
+ mem = this.methodBeingSpecialized;
+ Debug.Assert(mem != null);
+ memberBinding.BoundMember = mem;
+ if (memberBinding == null) return null;
+ Method method = memberBinding.BoundMember as Method;
+ if (method != null)
+ {
+ //Need to take the address of the target object (this parameter), or need to box it, if this target object type is value type
+ if (tObj != null && tObj.Type != null && tObj.Type.IsValueType)
+ {
+ if (tObj.NodeType != NodeType.This)
+ {
+ if (method.DeclaringType != null && method.DeclaringType.IsValueType) //it expects the address of the value type
+ memberBinding.TargetObject = new UnaryExpression(memberBinding.TargetObject, NodeType.AddressOf, memberBinding.TargetObject.Type.GetReferenceType());
+ else
+ { //it expects a boxed copy of the value type
+ MemberBinding obType = new MemberBinding(null, memberBinding.TargetObject.Type);
+ memberBinding.TargetObject = new BinaryExpression(memberBinding.TargetObject, obType, NodeType.Box, method.DeclaringType);
+ }
+ }
+ else
+ {
+ //REVIEW: perhaps This nodes of value types should be explicitly typed as reference types
+ //TODO: assert false in that case
+ }
+ }
+ }
+ return memberBinding;
+ }
+ public override Method VisitMethod(Method method)
+ {
+ if (method == null) return null;
+ Method savedCurrentMethod = this.CurrentMethod;
+ TypeNode savedCurrentType = this.CurrentType;
+ this.CurrentMethod = method;
+ this.CurrentType = method.DeclaringType;
+ method.Body = this.VisitBlock(method.Body);
+ this.CurrentMethod = savedCurrentMethod;
+ this.CurrentType = savedCurrentType;
+ return method;
+ }
+ public override Expression VisitConstruct(Construct cons)
+ {
+ cons = (Construct)base.VisitConstruct(cons);
+ if (cons == null) return null;
+ MemberBinding mb = cons.Constructor as MemberBinding;
+ if (mb == null) return cons;
+ Method meth = mb.BoundMember as Method;
+ if (meth == null) return cons;
+ ParameterList parameters = meth.Parameters;
+ if (parameters == null) return cons;
+ ExpressionList operands = cons.Operands;
+ int n = operands == null ? 0 : operands.Count;
+ if (n > parameters.Count) n = parameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert operands != null;
+ Expression e = operands[i];
+ if (e == null) continue;
+ Parameter p = parameters[i];
+ if (p == null) continue;
+ if (e.Type == null || p.Type == null) continue;
+ if (e.Type.IsValueType && !p.Type.IsValueType)
+ operands[i] = new BinaryExpression(e, new MemberBinding(null, e.Type), NodeType.Box, p.Type);
+ }
+ return cons;
+ }
+ public override Expression VisitMethodCall(MethodCall call)
+ {
+ call = (MethodCall)base.VisitMethodCall(call);
+ if (call == null) return null;
+ MemberBinding mb = call.Callee as MemberBinding;
+ if (mb == null) return call;
+ Method meth = mb.BoundMember as Method;
+ if (meth == null) return call;
+ ParameterList parameters = meth.Parameters;
+ if (parameters == null) return call;
+ ExpressionList operands = call.Operands;
+ int n = operands == null ? 0 : operands.Count;
+ if (n > parameters.Count) n = parameters.Count;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert operands != null;
+ Expression e = operands[i];
+ if (e == null) continue;
+ Parameter p = parameters[i];
+ if (p == null) continue;
+ if (e.Type == null || p.Type == null) continue;
+ if (e.Type.IsValueType && !p.Type.IsValueType)
+ operands[i] = new BinaryExpression(e, new MemberBinding(null, e.Type), NodeType.Box, p.Type);
+ }
+ if (meth.ReturnType != null && call.Type != null && meth.ReturnType.IsValueType && !call.Type.IsValueType)
+ return new BinaryExpression(call, new MemberBinding(null, meth.ReturnType), NodeType.Box, call.Type);
+ return call;
+ }
+ public override Statement VisitReturn(Return Return)
+ {
+ Return = (Return)base.VisitReturn(Return);
+ if (Return == null) return null;
+ Expression rval = Return.Expression;
+ if (rval == null || rval.Type == null || this.CurrentMethod == null || this.CurrentMethod.ReturnType == null)
+ return Return;
+ if (rval.Type.IsValueType && !this.CurrentMethod.ReturnType.IsValueType)
+ Return.Expression = new BinaryExpression(rval, new MemberBinding(null, rval.Type), NodeType.Box, this.CurrentMethod.ReturnType);
+ return Return;
+ }
+ public override TypeNode VisitTypeNode(TypeNode typeNode)
+ {
+ if (typeNode == null) return null;
+ TypeNode savedCurrentType = this.CurrentType;
+ this.CurrentType = typeNode;
+ MemberList members = typeNode.Members;
+ for (int i = 0, n = members == null ? 0 : members.Count; i < n; i++)
+ {
+ //^ assert members != null;
+ Member mem = members[i];
+ TypeNode t = mem as TypeNode;
+ if (t != null) { this.VisitTypeNode(t); continue; }
+ Method m = mem as Method;
+ if (m != null) { this.VisitMethod(m); continue; }
+ }
+ this.CurrentType = savedCurrentType;
+ return typeNode;
+ }
+ public override Expression VisitUnaryExpression(UnaryExpression unaryExpression)
+ {
+ if (unaryExpression == null) return null;
+ return base.VisitUnaryExpression((UnaryExpression)unaryExpression.Clone());
+ }
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/StandardIds.cs b/tools/Sandcastle/Source/CCI/StandardIds.cs
new file mode 100644
index 0000000..b4145b3
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/StandardIds.cs
@@ -0,0 +1,154 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !FxCop
+ public
+#endif
+ class StandardIds
+ {
+ private StandardIds() { }
+ public static readonly Identifier/*!*/ Address = Identifier.For("Address");
+ public static readonly Identifier/*!*/ AllowMultiple = Identifier.For("AllowMultiple");
+ public static readonly Identifier/*!*/ ClassParameter = Identifier.For("class parameter");
+ public static readonly Identifier/*!*/ Ctor = Identifier.For(".ctor");
+ public static readonly Identifier/*!*/ CCtor = Identifier.For(".cctor");
+ public static readonly Identifier/*!*/ Enum = Identifier.For("Enum");
+ public static readonly Identifier/*!*/ Get = Identifier.For("Get");
+ public static readonly Identifier/*!*/ Inherited = Identifier.For("Inherited");
+ public static readonly Identifier/*!*/ Invoke = Identifier.For("Invoke");
+ public static readonly Identifier/*!*/ Set = Identifier.For("Set");
+ public static readonly Identifier/*!*/ System = Identifier.For("System");
+ public static readonly Identifier/*!*/ This = Identifier.For("this");
+ public static readonly Identifier/*!*/ TypeParameter = Identifier.For("type parameter");
+ public static readonly Identifier/*!*/ Value__ = Identifier.For("value__");
+ public static readonly Identifier/*!*/ _Deleted = Identifier.For("_Deleted");
+#if !NoXml || !MinimalReader
+ public static readonly Identifier/*!*/ opExplicit = Identifier.For("op_Explicit");
+ public static readonly Identifier/*!*/ opImplicit = Identifier.For("op_Implicit");
+#endif
+#if !MinimalReader
+ public static readonly Identifier/*!*/ Add = Identifier.For("Add");
+ public static readonly Identifier/*!*/ Anonymity = Identifier.For("Anonymity");
+ public static readonly Identifier/*!*/ ArgumentOutOfRangeException = Identifier.For("ArgumentOutOfRangeException");
+ public static readonly Identifier/*!*/ Assembly = Identifier.For("Assembly");
+ public static readonly Identifier/*!*/ Assert = Identifier.For("Assert");
+ public static readonly Identifier/*!*/ BeginInvoke = Identifier.For("BeginInvoke");
+ public static readonly Identifier/*!*/ callback = Identifier.For("callback");
+ public static readonly Identifier/*!*/ CallingConvention = Identifier.For("CallingConvention");
+ public static readonly Identifier/*!*/ CapitalObject = Identifier.For("Object");
+ public static readonly Identifier/*!*/ CharSet = Identifier.For("CharSet");
+ public static readonly Identifier/*!*/ Class = Identifier.For("Class");
+ public static readonly Identifier/*!*/ Clear = Identifier.For("Clear");
+ public static readonly Identifier/*!*/ Closure = Identifier.For("Closure");
+ public static readonly Identifier/*!*/ Collection = Identifier.For("Collection");
+ public static readonly Identifier/*!*/ Combine = Identifier.For("Combine");
+ public static readonly Identifier/*!*/ Concat = Identifier.For("Concat");
+ public static readonly Identifier/*!*/ Count = Identifier.For("Count");
+ public static readonly Identifier/*!*/ CreateInstance = Identifier.For("CreateInstance");
+ public static readonly Identifier/*!*/ Current = Identifier.For("Current");
+ public static readonly Identifier/*!*/ Dispose = Identifier.For("Dispose");
+ public static readonly Identifier/*!*/ ElementType = Identifier.For("ElementType");
+ public static readonly Identifier/*!*/ Enter = Identifier.For("Enter");
+ public static readonly Identifier/*!*/ EntryPoint = Identifier.For("EntryPoint");
+ public static readonly Identifier/*!*/ ExactSpelling = Identifier.For("ExactSpelling");
+ public static readonly Identifier/*!*/ Exit = Identifier.For("Exit");
+ public static readonly Identifier/*!*/ EndInvoke = Identifier.For("EndInvoke");
+ public static readonly new Identifier/*!*/ Equals = Identifier.For("Equals");
+ public static readonly Identifier/*!*/ Finalize = Identifier.For("Finalize");
+ public static readonly Identifier/*!*/ FromObject = Identifier.For("FromObject");
+ public static readonly Identifier/*!*/ getCurrent = Identifier.For("get_Current");
+ public static readonly Identifier/*!*/ getCount = Identifier.For("get_Count");
+ public static readonly Identifier/*!*/ GetEnumerator = Identifier.For("GetEnumerator");
+ public static readonly new Identifier/*!*/ GetHashCode = Identifier.For("GetHashCode");
+ public static readonly Identifier/*!*/ getHasValue = Identifier.For("get_HasValue");
+ public static readonly Identifier/*!*/ getItem = Identifier.For("get_Item");
+ public static readonly Identifier/*!*/ GetTag = Identifier.For("GetTag");
+ public static readonly Identifier/*!*/ GetTagAsType = Identifier.For("GetTagAsType");
+ public static readonly Identifier/*!*/ getValue = Identifier.For("get_Value");
+ public static readonly Identifier/*!*/ GetValue = Identifier.For("GetValue");
+ public static readonly Identifier/*!*/ GetValueOrDefault = Identifier.For("GetValueOrDefault");
+ public static readonly new Identifier/*!*/ GetType = Identifier.For("GetType");
+ public static readonly Identifier/*!*/ Global = Identifier.For("global");
+ public static readonly Identifier/*!*/ IFactory = Identifier.For("IFactory");
+ public static readonly Identifier/*!*/ IEnumerableGetEnumerator = Identifier.For("IEnumerable.GetEnumerator");
+ public static readonly Identifier/*!*/ IEnumeratorGetCurrent = Identifier.For("IEnumerator.get_Current");
+ public static readonly Identifier/*!*/ IEnumeratorReset = Identifier.For("IEnumerator.Reset");
+ public static readonly Identifier/*!*/ IndexOf = Identifier.For("IndexOf");
+ public static readonly Identifier/*!*/ Insert = Identifier.For("Insert");
+ public static readonly Identifier/*!*/ IsInterned = Identifier.For("IsInterned");
+ public static readonly Identifier/*!*/ IsNull = Identifier.For("IsNull");
+ public static readonly Identifier/*!*/ It = Identifier.For("it");
+ public static readonly Identifier/*!*/ Item = Identifier.For("Item");
+ public static readonly Identifier/*!*/ Length = Identifier.For("Length");
+ public static readonly Identifier/*!*/ Main = Identifier.For("Main");
+ public static readonly Identifier/*!*/ Method = Identifier.For("method");
+ public static readonly new Identifier/*!*/ MemberwiseClone = Identifier.For("MemberwiseClone");
+ public static readonly Identifier/*!*/ MoveNext = Identifier.For("MoveNext");
+ public static readonly Identifier/*!*/ Namespace = Identifier.For("Namespace");
+ public static readonly Identifier/*!*/ New = Identifier.For("New");
+ public static readonly Identifier/*!*/ NewObj = Identifier.For(".newObj"); // used for locals representing new C() for value types
+ public static readonly Identifier/*!*/ Object = Identifier.For("object");
+ public static readonly Identifier/*!*/ opAddition = Identifier.For("op_Addition");
+ public static readonly Identifier/*!*/ opBitwiseAnd = Identifier.For("op_BitwiseAnd");
+ public static readonly Identifier/*!*/ opBitwiseOr = Identifier.For("op_BitwiseOr");
+ public static readonly Identifier/*!*/ opComma = Identifier.For("op_Comma");
+ public static readonly Identifier/*!*/ opDecrement = Identifier.For("op_Decrement");
+ public static readonly Identifier/*!*/ opDivision = Identifier.For("op_Division");
+ public static readonly Identifier/*!*/ opEquality = Identifier.For("op_Equality");
+ public static readonly Identifier/*!*/ opExclusiveOr = Identifier.For("op_ExclusiveOr");
+ public static readonly Identifier/*!*/ opFalse = Identifier.For("op_False");
+ public static readonly Identifier/*!*/ opGreaterThan = Identifier.For("op_GreaterThan");
+ public static readonly Identifier/*!*/ opGreaterThanOrEqual = Identifier.For("op_GreaterThanOrEqual");
+ public static readonly Identifier/*!*/ opIncrement = Identifier.For("op_Increment");
+ public static readonly Identifier/*!*/ opInequality = Identifier.For("op_Inequality");
+ public static readonly Identifier/*!*/ opLeftShift = Identifier.For("op_LeftShift");
+ public static readonly Identifier/*!*/ opLessThan = Identifier.For("op_LessThan");
+ public static readonly Identifier/*!*/ opLessThanOrEqual = Identifier.For("op_LessThanOrEqual");
+ public static readonly Identifier/*!*/ opLogicalNot = Identifier.For("op_LogicalNot");
+ public static readonly Identifier/*!*/ opModulus = Identifier.For("op_Modulus");
+ public static readonly Identifier/*!*/ opMultiply = Identifier.For("op_Multiply");
+ public static readonly Identifier/*!*/ opOnesComplement = Identifier.For("op_OnesComplement");
+ public static readonly Identifier/*!*/ opRightShift = Identifier.For("op_RightShift");
+ public static readonly Identifier/*!*/ opSubtraction = Identifier.For("op_Subtraction");
+ public static readonly Identifier/*!*/ opTrue = Identifier.For("op_True");
+ public static readonly Identifier/*!*/ opUnaryNegation = Identifier.For("op_UnaryNegation");
+ public static readonly Identifier/*!*/ opUnaryPlus = Identifier.For("op_UnaryPlus");
+ public static readonly Identifier/*!*/ Pack = Identifier.For("Pack");
+ public static readonly Identifier/*!*/ Phase = Identifier.For("Phase");
+ public static readonly Identifier/*!*/ Position = Identifier.For("Position");
+ public static readonly Identifier/*!*/ PreserveSig = Identifier.For("PreserveSig");
+ public static readonly new Identifier/*!*/ ReferenceEquals = Identifier.For("ReferenceEquals");
+ public static readonly Identifier/*!*/ Remove = Identifier.For("Remove");
+ public static readonly Identifier/*!*/ Replace = Identifier.For("Replace");
+ public static readonly Identifier/*!*/ Reset = Identifier.For("Reset");
+ public static readonly Identifier/*!*/ result = Identifier.For("result");
+ public static readonly Identifier/*!*/ SetLastError = Identifier.For("SetLastError");
+ public static readonly Identifier/*!*/ SetValue = Identifier.For("SetValue");
+ public static readonly Identifier/*!*/ Size = Identifier.For("Size");
+ public static readonly Identifier/*!*/ StructuralTypes = Identifier.For("StructuralTypes");
+ public static readonly Identifier/*!*/ Tag = Identifier.For("tag");
+ public static readonly Identifier/*!*/ TagType = Identifier.For("tagType");
+ public static readonly Identifier/*!*/ ThisValue = Identifier.For("this value: ");
+ public static readonly Identifier/*!*/ ToObject = Identifier.For("ToObject");
+ public static readonly new Identifier/*!*/ ToString = Identifier.For("ToString");
+#if CCINamespace
+ public static readonly Identifier/*!*/ CciTypeExtensions = Identifier.For("Microsoft.Cci.TypeExtensions");
+#else
+ public static readonly Identifier/*!*/ CciTypeExtensions = Identifier.For("System.Compiler.TypeExtensions");
+#endif
+ public static readonly Identifier/*!*/ Value = Identifier.For("value");
+ public static readonly Identifier/*!*/ Var = Identifier.For("var");
+ public static readonly Identifier/*!*/ __Arglist = Identifier.For("__arglist");
+#endif
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/StandardVisitor.cs b/tools/Sandcastle/Source/CCI/StandardVisitor.cs
new file mode 100644
index 0000000..fcc6ba6
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/StandardVisitor.cs
@@ -0,0 +1,2225 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Diagnostics;
+#if FxCop
+using AttributeList = Microsoft.Cci.AttributeNodeCollection;
+using BlockList = Microsoft.Cci.BlockCollection;
+using ExpressionList = Microsoft.Cci.ExpressionCollection;
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using MemberList = Microsoft.Cci.MemberCollection;
+using NodeList = Microsoft.Cci.NodeCollection;
+using ParameterList = Microsoft.Cci.ParameterCollection;
+using SecurityAttributeList = Microsoft.Cci.SecurityAttributeCollection;
+using StatementList = Microsoft.Cci.StatementCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Property = Microsoft.Cci.PropertyNode;
+using Module = Microsoft.Cci.ModuleNode;
+using Return = Microsoft.Cci.ReturnNode;
+using Class = Microsoft.Cci.ClassNode;
+using Interface = Microsoft.Cci.InterfaceNode;
+using Event = Microsoft.Cci.EventNode;
+using Throw = Microsoft.Cci.ThrowNode;
+#endif
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+
+ /// <summary>
+ /// Base for all classes that process the IR using the visitor pattern.
+ /// </summary>
+#if !FxCop
+ public
+#endif
+ abstract class Visitor
+ {
+ /// <summary>
+ /// Switches on node.NodeType to call a visitor method that has been specialized for node.
+ /// </summary>
+ /// <param name="node">The node to be visited.</param>
+ /// <returns> Returns null if node is null. Otherwise returns an updated node (possibly a different object).</returns>
+ public abstract Node Visit(Node node);
+#if !MinimalReader
+ /// <summary>
+ /// Transfers the state from one visitor to another. This enables separate visitor instances to cooperative process a single IR.
+ /// </summary>
+ public virtual void TransferStateTo(Visitor targetVisitor)
+ {
+ }
+#endif
+ public virtual ExpressionList VisitExpressionList(ExpressionList list)
+ {
+ if (list == null) return null;
+ for (int i = 0, n = list.Count; i < n; i++)
+ list[i] = (Expression)this.Visit(list[i]);
+ return list;
+ }
+ }
+
+ /// <summary>
+ /// Walks an IR, mutuating it into a new form
+ /// </summary>
+#if !FxCop
+ public
+#endif
+ class StandardVisitor : Visitor
+ {
+#if !MinimalReader
+ public Visitor callingVisitor;
+#endif
+ protected bool memberListNamesChanged;
+
+ public StandardVisitor()
+ {
+ }
+#if !MinimalReader
+ public StandardVisitor(Visitor callingVisitor)
+ {
+ this.callingVisitor = callingVisitor;
+ }
+#endif
+ public virtual Node VisitUnknownNodeType(Node node)
+ {
+#if !MinimalReader
+ Visitor visitor = this.GetVisitorFor(node);
+ if (visitor == null) return node;
+ if (this.callingVisitor != null)
+ //Allow specialized state (unknown to this visitor) to propagate all the way down to the new visitor
+ this.callingVisitor.TransferStateTo(visitor);
+ this.TransferStateTo(visitor);
+ node = visitor.Visit(node);
+ visitor.TransferStateTo(this);
+ if (this.callingVisitor != null)
+ //Propagate specialized state (unknown to this visitor) all the way up the chain
+ visitor.TransferStateTo(this.callingVisitor);
+#else
+ Debug.Assert(false);
+#endif
+ return node;
+ }
+#if !MinimalReader
+ public virtual Visitor GetVisitorFor(Node node)
+ {
+ if (node == null) return null;
+ return (Visitor)node.GetVisitorFor(this, this.GetType().Name);
+ }
+#endif
+ public override Node Visit(Node node)
+ {
+ if (node == null) return null;
+ switch (node.NodeType)
+ {
+#if !MinimalReader
+ case NodeType.Acquire:
+ return this.VisitAcquire((Acquire)node);
+#endif
+ case NodeType.AddressDereference:
+ return this.VisitAddressDereference((AddressDereference)node);
+#if !MinimalReader
+ case NodeType.AliasDefinition:
+ return this.VisitAliasDefinition((AliasDefinition)node);
+ case NodeType.AnonymousNestedFunction:
+ return this.VisitAnonymousNestedFunction((AnonymousNestedFunction)node);
+ case NodeType.ApplyToAll:
+ return this.VisitApplyToAll((ApplyToAll)node);
+#endif
+ case NodeType.Arglist:
+ return this.VisitExpression((Expression)node);
+#if !MinimalReader
+ case NodeType.ArglistArgumentExpression:
+ return this.VisitArglistArgumentExpression((ArglistArgumentExpression)node);
+ case NodeType.ArglistExpression:
+ return this.VisitArglistExpression((ArglistExpression)node);
+#endif
+ case NodeType.ArrayType:
+ Debug.Assert(false); return null;
+ case NodeType.Assembly:
+ return this.VisitAssembly((AssemblyNode)node);
+ case NodeType.AssemblyReference:
+ return this.VisitAssemblyReference((AssemblyReference)node);
+#if !MinimalReader
+ case NodeType.Assertion:
+ return this.VisitAssertion((Assertion)node);
+ case NodeType.Assumption:
+ return this.VisitAssumption((Assumption)node);
+ case NodeType.AssignmentExpression:
+ return this.VisitAssignmentExpression((AssignmentExpression)node);
+#endif
+ case NodeType.AssignmentStatement:
+ return this.VisitAssignmentStatement((AssignmentStatement)node);
+ case NodeType.Attribute:
+ return this.VisitAttributeNode((AttributeNode)node);
+#if !MinimalReader
+ case NodeType.Base:
+ return this.VisitBase((Base)node);
+#endif
+ case NodeType.Block:
+ return this.VisitBlock((Block)node);
+#if !MinimalReader
+ case NodeType.BlockExpression:
+ return this.VisitBlockExpression((BlockExpression)node);
+#endif
+ case NodeType.Branch:
+ return this.VisitBranch((Branch)node);
+#if !MinimalReader
+ case NodeType.Compilation:
+ return this.VisitCompilation((Compilation)node);
+ case NodeType.CompilationUnit:
+ return this.VisitCompilationUnit((CompilationUnit)node);
+ case NodeType.CompilationUnitSnippet:
+ return this.VisitCompilationUnitSnippet((CompilationUnitSnippet)node);
+#endif
+#if ExtendedRuntime
+ case NodeType.ConstrainedType:
+ return this.VisitConstrainedType((ConstrainedType)node);
+#endif
+#if !MinimalReader
+ case NodeType.Continue:
+ return this.VisitContinue((Continue)node);
+ case NodeType.CurrentClosure:
+ return this.VisitCurrentClosure((CurrentClosure)node);
+#endif
+ case NodeType.DebugBreak:
+ return node;
+ case NodeType.Call:
+ case NodeType.Calli:
+ case NodeType.Callvirt:
+ case NodeType.Jmp:
+#if !MinimalReader
+ case NodeType.MethodCall:
+#endif
+ return this.VisitMethodCall((MethodCall)node);
+#if !MinimalReader
+ case NodeType.Catch:
+ return this.VisitCatch((Catch)node);
+#endif
+ case NodeType.Class:
+ return this.VisitClass((Class)node);
+#if !MinimalReader
+ case NodeType.CoerceTuple:
+ return this.VisitCoerceTuple((CoerceTuple)node);
+ case NodeType.CollectionEnumerator:
+ return this.VisitCollectionEnumerator((CollectionEnumerator)node);
+ case NodeType.Composition:
+ return this.VisitComposition((Composition)node);
+#endif
+ case NodeType.Construct:
+ return this.VisitConstruct((Construct)node);
+ case NodeType.ConstructArray:
+ return this.VisitConstructArray((ConstructArray)node);
+#if !MinimalReader
+ case NodeType.ConstructDelegate:
+ return this.VisitConstructDelegate((ConstructDelegate)node);
+ case NodeType.ConstructFlexArray:
+ return this.VisitConstructFlexArray((ConstructFlexArray)node);
+ case NodeType.ConstructIterator:
+ return this.VisitConstructIterator((ConstructIterator)node);
+ case NodeType.ConstructTuple:
+ return this.VisitConstructTuple((ConstructTuple)node);
+#endif
+ case NodeType.DelegateNode:
+ return this.VisitDelegateNode((DelegateNode)node);
+#if !MinimalReader
+ case NodeType.DoWhile:
+ return this.VisitDoWhile((DoWhile)node);
+#endif
+ case NodeType.Dup:
+ return this.VisitExpression((Expression)node);
+ case NodeType.EndFilter:
+ return this.VisitEndFilter((EndFilter)node);
+ case NodeType.EndFinally:
+ return this.VisitEndFinally((EndFinally)node);
+ case NodeType.EnumNode:
+ return this.VisitEnumNode((EnumNode)node);
+ case NodeType.Event:
+ return this.VisitEvent((Event)node);
+#if ExtendedRuntime
+ case NodeType.EnsuresExceptional :
+ return this.VisitEnsuresExceptional((EnsuresExceptional)node);
+#endif
+#if !MinimalReader
+ case NodeType.Exit:
+ return this.VisitExit((Exit)node);
+ case NodeType.Read:
+ case NodeType.Write:
+ return this.VisitExpose((Expose)node);
+ case NodeType.ExpressionSnippet:
+ return this.VisitExpressionSnippet((ExpressionSnippet)node);
+#endif
+ case NodeType.ExpressionStatement:
+ return this.VisitExpressionStatement((ExpressionStatement)node);
+#if !MinimalReader
+ case NodeType.FaultHandler:
+ return this.VisitFaultHandler((FaultHandler)node);
+#endif
+ case NodeType.Field:
+ return this.VisitField((Field)node);
+#if !MinimalReader
+ case NodeType.FieldInitializerBlock:
+ return this.VisitFieldInitializerBlock((FieldInitializerBlock)node);
+ case NodeType.Finally:
+ return this.VisitFinally((Finally)node);
+ case NodeType.Filter:
+ return this.VisitFilter((Filter)node);
+ case NodeType.Fixed:
+ return this.VisitFixed((Fixed)node);
+ case NodeType.For:
+ return this.VisitFor((For)node);
+ case NodeType.ForEach:
+ return this.VisitForEach((ForEach)node);
+ case NodeType.FunctionDeclaration:
+ return this.VisitFunctionDeclaration((FunctionDeclaration)node);
+ case NodeType.Goto:
+ return this.VisitGoto((Goto)node);
+ case NodeType.GotoCase:
+ return this.VisitGotoCase((GotoCase)node);
+#endif
+ case NodeType.Identifier:
+ return this.VisitIdentifier((Identifier)node);
+#if !MinimalReader
+ case NodeType.If:
+ return this.VisitIf((If)node);
+ case NodeType.ImplicitThis:
+ return this.VisitImplicitThis((ImplicitThis)node);
+#endif
+ case NodeType.Indexer:
+ return this.VisitIndexer((Indexer)node);
+ case NodeType.InstanceInitializer:
+ return this.VisitInstanceInitializer((InstanceInitializer)node);
+#if ExtendedRuntime
+ case NodeType.Invariant :
+ return this.VisitInvariant((Invariant)node);
+#endif
+ case NodeType.StaticInitializer:
+ return this.VisitStaticInitializer((StaticInitializer)node);
+ case NodeType.Method:
+ return this.VisitMethod((Method)node);
+#if !MinimalReader
+ case NodeType.TemplateInstance:
+ return this.VisitTemplateInstance((TemplateInstance)node);
+ case NodeType.StackAlloc:
+ return this.VisitStackAlloc((StackAlloc)node);
+#endif
+ case NodeType.Interface:
+ return this.VisitInterface((Interface)node);
+#if !MinimalReader
+ case NodeType.LabeledStatement:
+ return this.VisitLabeledStatement((LabeledStatement)node);
+#endif
+ case NodeType.Literal:
+ return this.VisitLiteral((Literal)node);
+ case NodeType.Local:
+ return this.VisitLocal((Local)node);
+#if !MinimalReader
+ case NodeType.LocalDeclaration:
+ return this.VisitLocalDeclaration((LocalDeclaration)node);
+ case NodeType.LocalDeclarationsStatement:
+ return this.VisitLocalDeclarationsStatement((LocalDeclarationsStatement)node);
+ case NodeType.Lock:
+ return this.VisitLock((Lock)node);
+ case NodeType.LRExpression:
+ return this.VisitLRExpression((LRExpression)node);
+#endif
+ case NodeType.MemberBinding:
+ return this.VisitMemberBinding((MemberBinding)node);
+#if ExtendedRuntime
+ case NodeType.MethodContract :
+ return this.VisitMethodContract((MethodContract)node);
+#endif
+ case NodeType.Module:
+ return this.VisitModule((Module)node);
+ case NodeType.ModuleReference:
+ return this.VisitModuleReference((ModuleReference)node);
+#if !MinimalReader
+ case NodeType.NameBinding:
+ return this.VisitNameBinding((NameBinding)node);
+#endif
+ case NodeType.NamedArgument:
+ return this.VisitNamedArgument((NamedArgument)node);
+#if !MinimalReader
+ case NodeType.Namespace:
+ return this.VisitNamespace((Namespace)node);
+#endif
+ case NodeType.Nop:
+#if !MinimalReader
+ case NodeType.SwitchCaseBottom:
+#endif
+ return node;
+#if ExtendedRuntime
+ case NodeType.EnsuresNormal :
+ return this.VisitEnsuresNormal((EnsuresNormal)node);
+ case NodeType.OldExpression :
+ return this.VisitOldExpression((OldExpression)node);
+ case NodeType.RequiresOtherwise :
+ return this.VisitRequiresOtherwise((RequiresOtherwise)node);
+ case NodeType.RequiresPlain :
+ return this.VisitRequiresPlain((RequiresPlain)node);
+#endif
+ case NodeType.OptionalModifier:
+ case NodeType.RequiredModifier:
+ //TODO: type modifers should only be visited via VisitTypeReference
+ return this.VisitTypeModifier((TypeModifier)node);
+ case NodeType.Parameter:
+ return this.VisitParameter((Parameter)node);
+ case NodeType.Pop:
+ return this.VisitExpression((Expression)node);
+#if !MinimalReader
+ case NodeType.PrefixExpression:
+ return this.VisitPrefixExpression((PrefixExpression)node);
+ case NodeType.PostfixExpression:
+ return this.VisitPostfixExpression((PostfixExpression)node);
+#endif
+ case NodeType.Property:
+ return this.VisitProperty((Property)node);
+#if !MinimalReader
+ case NodeType.Quantifier:
+ return this.VisitQuantifier((Quantifier)node);
+ case NodeType.Comprehension:
+ return this.VisitComprehension((Comprehension)node);
+ case NodeType.ComprehensionBinding:
+ return this.VisitComprehensionBinding((ComprehensionBinding)node);
+ case NodeType.QualifiedIdentifer:
+ return this.VisitQualifiedIdentifier((QualifiedIdentifier)node);
+#endif
+ case NodeType.Rethrow:
+ case NodeType.Throw:
+ return this.VisitThrow((Throw)node);
+#if !MinimalReader
+ case NodeType.RefValueExpression:
+ return this.VisitRefValueExpression((RefValueExpression)node);
+ case NodeType.RefTypeExpression:
+ return this.VisitRefTypeExpression((RefTypeExpression)node);
+#endif
+ case NodeType.Return:
+ return this.VisitReturn((Return)node);
+#if !MinimalReader
+ case NodeType.Repeat:
+ return this.VisitRepeat((Repeat)node);
+ case NodeType.ResourceUse:
+ return this.VisitResourceUse((ResourceUse)node);
+#endif
+ case NodeType.SecurityAttribute:
+ return this.VisitSecurityAttribute((SecurityAttribute)node);
+#if !MinimalReader
+ case NodeType.SetterValue:
+ return this.VisitSetterValue((SetterValue)node);
+ case NodeType.StatementSnippet:
+ return this.VisitStatementSnippet((StatementSnippet)node);
+#endif
+ case NodeType.Struct:
+ return this.VisitStruct((Struct)node);
+#if !MinimalReader
+ case NodeType.Switch:
+ return this.VisitSwitch((Switch)node);
+ case NodeType.SwitchCase:
+ return this.VisitSwitchCase((SwitchCase)node);
+#endif
+ case NodeType.SwitchInstruction:
+ return this.VisitSwitchInstruction((SwitchInstruction)node);
+#if !MinimalReader
+ case NodeType.Typeswitch:
+ return this.VisitTypeswitch((Typeswitch)node);
+ case NodeType.TypeswitchCase:
+ return this.VisitTypeswitchCase((TypeswitchCase)node);
+#endif
+ case NodeType.This:
+ return this.VisitThis((This)node);
+#if !MinimalReader
+ case NodeType.Try:
+ return this.VisitTry((Try)node);
+#endif
+#if ExtendedRuntime
+ case NodeType.TypeContract:
+ return this.VisitTypeContract((TypeContract)node);
+
+ case NodeType.TupleType:
+ return this.VisitTupleType((TupleType)node);
+ case NodeType.TypeAlias:
+ return this.VisitTypeAlias((TypeAlias)node);
+ case NodeType.TypeIntersection:
+ return this.VisitTypeIntersection((TypeIntersection)node);
+#endif
+#if !MinimalReader
+ case NodeType.TypeMemberSnippet:
+ return this.VisitTypeMemberSnippet((TypeMemberSnippet)node);
+#endif
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ return this.VisitTypeParameter((TypeNode)node);
+#if ExtendedRuntime
+ case NodeType.TypeUnion:
+ return this.VisitTypeUnion((TypeUnion)node);
+#endif
+#if !MinimalReader
+ case NodeType.TypeReference:
+ return this.VisitTypeReference((TypeReference)node);
+ case NodeType.UsedNamespace:
+ return this.VisitUsedNamespace((UsedNamespace)node);
+ case NodeType.VariableDeclaration:
+ return this.VisitVariableDeclaration((VariableDeclaration)node);
+ case NodeType.While:
+ return this.VisitWhile((While)node);
+ case NodeType.Yield:
+ return this.VisitYield((Yield)node);
+
+ case NodeType.Conditional:
+#endif
+ case NodeType.Cpblk:
+ case NodeType.Initblk:
+ return this.VisitTernaryExpression((TernaryExpression)node);
+
+ case NodeType.Add:
+ case NodeType.Add_Ovf:
+ case NodeType.Add_Ovf_Un:
+#if !MinimalReader
+ case NodeType.AddEventHandler:
+#endif
+ case NodeType.And:
+#if !MinimalReader
+ case NodeType.As:
+#endif
+ case NodeType.Box:
+ case NodeType.Castclass:
+ case NodeType.Ceq:
+ case NodeType.Cgt:
+ case NodeType.Cgt_Un:
+ case NodeType.Clt:
+ case NodeType.Clt_Un:
+#if !MinimalReader
+ case NodeType.Comma:
+#endif
+ case NodeType.Div:
+ case NodeType.Div_Un:
+ case NodeType.Eq:
+#if !MinimalReader
+ case NodeType.ExplicitCoercion:
+#endif
+ case NodeType.Ge:
+ case NodeType.Gt:
+#if !MinimalReader
+ case NodeType.Is:
+ case NodeType.Iff:
+ case NodeType.Implies:
+#endif
+ case NodeType.Isinst:
+ case NodeType.Ldvirtftn:
+ case NodeType.Le:
+#if !MinimalReader
+ case NodeType.LogicalAnd:
+ case NodeType.LogicalOr:
+#endif
+ case NodeType.Lt:
+ case NodeType.Mkrefany:
+#if !MinimalReader
+ case NodeType.Maplet:
+#endif
+ case NodeType.Mul:
+ case NodeType.Mul_Ovf:
+ case NodeType.Mul_Ovf_Un:
+ case NodeType.Ne:
+ case NodeType.Or:
+#if !MinimalReader
+ case NodeType.NullCoalesingExpression:
+ case NodeType.Range:
+#endif
+ case NodeType.Refanyval:
+ case NodeType.Rem:
+ case NodeType.Rem_Un:
+#if !MinimalReader
+ case NodeType.RemoveEventHandler:
+#endif
+ case NodeType.Shl:
+ case NodeType.Shr:
+ case NodeType.Shr_Un:
+ case NodeType.Sub:
+ case NodeType.Sub_Ovf:
+ case NodeType.Sub_Ovf_Un:
+ case NodeType.Unbox:
+ case NodeType.UnboxAny:
+ case NodeType.Xor:
+ return this.VisitBinaryExpression((BinaryExpression)node);
+
+ case NodeType.AddressOf:
+#if !MinimalReader
+ case NodeType.OutAddress:
+ case NodeType.RefAddress:
+#endif
+ case NodeType.Ckfinite:
+ case NodeType.Conv_I:
+ case NodeType.Conv_I1:
+ case NodeType.Conv_I2:
+ case NodeType.Conv_I4:
+ case NodeType.Conv_I8:
+ case NodeType.Conv_Ovf_I:
+ case NodeType.Conv_Ovf_I1:
+ case NodeType.Conv_Ovf_I1_Un:
+ case NodeType.Conv_Ovf_I2:
+ case NodeType.Conv_Ovf_I2_Un:
+ case NodeType.Conv_Ovf_I4:
+ case NodeType.Conv_Ovf_I4_Un:
+ case NodeType.Conv_Ovf_I8:
+ case NodeType.Conv_Ovf_I8_Un:
+ case NodeType.Conv_Ovf_I_Un:
+ case NodeType.Conv_Ovf_U:
+ case NodeType.Conv_Ovf_U1:
+ case NodeType.Conv_Ovf_U1_Un:
+ case NodeType.Conv_Ovf_U2:
+ case NodeType.Conv_Ovf_U2_Un:
+ case NodeType.Conv_Ovf_U4:
+ case NodeType.Conv_Ovf_U4_Un:
+ case NodeType.Conv_Ovf_U8:
+ case NodeType.Conv_Ovf_U8_Un:
+ case NodeType.Conv_Ovf_U_Un:
+ case NodeType.Conv_R4:
+ case NodeType.Conv_R8:
+ case NodeType.Conv_R_Un:
+ case NodeType.Conv_U:
+ case NodeType.Conv_U1:
+ case NodeType.Conv_U2:
+ case NodeType.Conv_U4:
+ case NodeType.Conv_U8:
+#if !MinimalReader
+ case NodeType.Decrement:
+ case NodeType.DefaultValue:
+ case NodeType.Increment:
+#endif
+ case NodeType.Ldftn:
+ case NodeType.Ldlen:
+ case NodeType.Ldtoken:
+ case NodeType.Localloc:
+ case NodeType.LogicalNot:
+ case NodeType.Neg:
+ case NodeType.Not:
+#if !MinimalReader
+ case NodeType.Parentheses:
+#endif
+ case NodeType.Refanytype:
+ case NodeType.ReadOnlyAddressOf:
+ case NodeType.Sizeof:
+ case NodeType.SkipCheck:
+#if !MinimalReader
+ case NodeType.Typeof:
+ case NodeType.UnaryPlus:
+#endif
+ return this.VisitUnaryExpression((UnaryExpression)node);
+#if ExtendedRuntime
+ // query node types
+ case NodeType.QueryAggregate:
+ return this.VisitQueryAggregate((QueryAggregate)node);
+ case NodeType.QueryAlias:
+ return this.VisitQueryAlias((QueryAlias)node);
+ case NodeType.QueryAll:
+ case NodeType.QueryAny:
+ return this.VisitQueryQuantifier((QueryQuantifier)node);
+ case NodeType.QueryAxis:
+ return this.VisitQueryAxis((QueryAxis)node);
+ case NodeType.QueryCommit:
+ return this.VisitQueryCommit((QueryCommit)node);
+ case NodeType.QueryContext:
+ return this.VisitQueryContext((QueryContext)node);
+ case NodeType.QueryDelete:
+ return this.VisitQueryDelete((QueryDelete)node);
+ case NodeType.QueryDifference:
+ return this.VisitQueryDifference((QueryDifference)node);
+ case NodeType.QueryDistinct:
+ return this.VisitQueryDistinct((QueryDistinct)node);
+ case NodeType.QueryExists:
+ return this.VisitQueryExists((QueryExists)node);
+ case NodeType.QueryFilter:
+ return this.VisitQueryFilter((QueryFilter)node);
+ case NodeType.QueryGeneratedType:
+ return this.VisitQueryGeneratedType((QueryGeneratedType)node);
+ case NodeType.QueryGroupBy:
+ return this.VisitQueryGroupBy((QueryGroupBy)node);
+ case NodeType.QueryInsert:
+ return this.VisitQueryInsert((QueryInsert)node);
+ case NodeType.QueryIntersection:
+ return this.VisitQueryIntersection((QueryIntersection)node);
+ case NodeType.QueryIterator:
+ return this.VisitQueryIterator((QueryIterator)node);
+ case NodeType.QueryJoin:
+ return this.VisitQueryJoin((QueryJoin)node);
+ case NodeType.QueryLimit:
+ return this.VisitQueryLimit((QueryLimit)node);
+ case NodeType.QueryOrderBy:
+ return this.VisitQueryOrderBy((QueryOrderBy)node);
+ case NodeType.QueryOrderItem:
+ return this.VisitQueryOrderItem((QueryOrderItem)node);
+ case NodeType.QueryPosition:
+ return this.VisitQueryPosition((QueryPosition)node);
+ case NodeType.QueryProject:
+ return this.VisitQueryProject((QueryProject)node);
+ case NodeType.QueryQuantifiedExpression:
+ return this.VisitQueryQuantifiedExpression((QueryQuantifiedExpression)node);
+ case NodeType.QueryRollback:
+ return this.VisitQueryRollback((QueryRollback)node);
+ case NodeType.QuerySelect:
+ return this.VisitQuerySelect((QuerySelect)node);
+ case NodeType.QuerySingleton:
+ return this.VisitQuerySingleton((QuerySingleton)node);
+ case NodeType.QueryTransact:
+ return this.VisitQueryTransact((QueryTransact)node);
+ case NodeType.QueryTypeFilter:
+ return this.VisitQueryTypeFilter((QueryTypeFilter)node);
+ case NodeType.QueryUnion:
+ return this.VisitQueryUnion((QueryUnion)node);
+ case NodeType.QueryUpdate:
+ return this.VisitQueryUpdate((QueryUpdate)node);
+ case NodeType.QueryYielder:
+ return this.VisitQueryYielder((QueryYielder)node);
+#endif
+ default:
+ return this.VisitUnknownNodeType(node);
+ }
+ }
+ public virtual Expression VisitAddressDereference(AddressDereference addr)
+ {
+ if (addr == null) return null;
+ addr.Address = this.VisitExpression(addr.Address);
+ return addr;
+ }
+#if !MinimalReader
+ public virtual AliasDefinition VisitAliasDefinition(AliasDefinition aliasDefinition)
+ {
+ if (aliasDefinition == null) return null;
+ aliasDefinition.AliasedType = this.VisitTypeReference(aliasDefinition.AliasedType);
+ return aliasDefinition;
+ }
+ public virtual AliasDefinitionList VisitAliasDefinitionList(AliasDefinitionList aliasDefinitions)
+ {
+ if (aliasDefinitions == null) return null;
+ for (int i = 0, n = aliasDefinitions.Count; i < n; i++)
+ aliasDefinitions[i] = this.VisitAliasDefinition(aliasDefinitions[i]);
+ return aliasDefinitions;
+ }
+ public virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func)
+ {
+ if (func == null) return null;
+ func.Parameters = this.VisitParameterList(func.Parameters);
+ func.Body = this.VisitBlock(func.Body);
+ return func;
+ }
+ public virtual Expression VisitApplyToAll(ApplyToAll applyToAll)
+ {
+ if (applyToAll == null) return null;
+ applyToAll.Operand1 = this.VisitExpression(applyToAll.Operand1);
+ applyToAll.Operand2 = this.VisitExpression(applyToAll.Operand2);
+ return applyToAll;
+ }
+ public ArrayType VisitArrayType(ArrayType array)
+ {
+ Debug.Assert(false, "An array type exists only at runtime. It should be referred to, but never visited.");
+ return null;
+ }
+#endif
+ public virtual AssemblyNode VisitAssembly(AssemblyNode assembly)
+ {
+ if (assembly == null) return null;
+ this.VisitModule(assembly);
+ assembly.ModuleAttributes = this.VisitAttributeList(assembly.ModuleAttributes);
+ assembly.SecurityAttributes = this.VisitSecurityAttributeList(assembly.SecurityAttributes);
+ return assembly;
+ }
+ public virtual AssemblyReference VisitAssemblyReference(AssemblyReference assemblyReference)
+ {
+ return assemblyReference;
+ }
+#if !MinimalReader
+ public virtual Statement VisitAssertion(Assertion assertion)
+ {
+ if (assertion == null) return null;
+ assertion.Condition = this.VisitExpression(assertion.Condition);
+ return assertion;
+ }
+ public virtual Statement VisitAssumption(Assumption assumption)
+ {
+ if (assumption == null) return null;
+ assumption.Condition = this.VisitExpression(assumption.Condition);
+ return assumption;
+ }
+ public virtual Expression VisitAssignmentExpression(AssignmentExpression assignment)
+ {
+ if (assignment == null) return null;
+ assignment.AssignmentStatement = (Statement)this.Visit(assignment.AssignmentStatement);
+ return assignment;
+ }
+#endif
+ public virtual Statement VisitAssignmentStatement(AssignmentStatement assignment)
+ {
+ if (assignment == null) return null;
+ assignment.Target = this.VisitTargetExpression(assignment.Target);
+ assignment.Source = this.VisitExpression(assignment.Source);
+ return assignment;
+ }
+ public virtual Expression VisitAttributeConstructor(AttributeNode attribute)
+ {
+ if (attribute == null) return null;
+ return this.VisitExpression(attribute.Constructor);
+ }
+ public virtual AttributeNode VisitAttributeNode(AttributeNode attribute)
+ {
+ if (attribute == null) return null;
+ attribute.Constructor = this.VisitAttributeConstructor(attribute);
+ attribute.Expressions = this.VisitExpressionList(attribute.Expressions);
+ return attribute;
+ }
+ public virtual AttributeList VisitAttributeList(AttributeList attributes)
+ {
+ if (attributes == null) return null;
+ for (int i = 0, n = attributes.Count; i < n; i++)
+ attributes[i] = this.VisitAttributeNode(attributes[i]);
+ return attributes;
+ }
+#if !MinimalReader
+ public virtual Expression VisitBase(Base Base)
+ {
+ return Base;
+ }
+#endif
+ public virtual Expression VisitBinaryExpression(BinaryExpression binaryExpression)
+ {
+ if (binaryExpression == null) return null;
+ binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1);
+ binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2);
+ return binaryExpression;
+ }
+ public virtual Block VisitBlock(Block block)
+ {
+ if (block == null) return null;
+ block.Statements = this.VisitStatementList(block.Statements);
+ return block;
+ }
+#if !MinimalReader
+ public virtual Expression VisitBlockExpression(BlockExpression blockExpression)
+ {
+ if (blockExpression == null) return null;
+ blockExpression.Block = this.VisitBlock(blockExpression.Block);
+ return blockExpression;
+ }
+#endif
+ public virtual BlockList VisitBlockList(BlockList blockList)
+ {
+ if (blockList == null) return null;
+ for (int i = 0, n = blockList.Count; i < n; i++)
+ blockList[i] = this.VisitBlock(blockList[i]);
+ return blockList;
+ }
+ public virtual Statement VisitBranch(Branch branch)
+ {
+ if (branch == null) return null;
+ branch.Condition = this.VisitExpression(branch.Condition);
+ return branch;
+ }
+#if !MinimalReader
+ public virtual Statement VisitCatch(Catch Catch)
+ {
+ if (Catch == null) return null;
+ Catch.Variable = this.VisitTargetExpression(Catch.Variable);
+ Catch.Type = this.VisitTypeReference(Catch.Type);
+ Catch.Block = this.VisitBlock(Catch.Block);
+ return Catch;
+ }
+ public virtual CatchList VisitCatchList(CatchList catchers)
+ {
+ if (catchers == null) return null;
+ for (int i = 0, n = catchers.Count; i < n; i++)
+ catchers[i] = (Catch)this.VisitCatch(catchers[i]);
+ return catchers;
+ }
+#endif
+ public virtual Class VisitClass(Class Class)
+ {
+ return (Class)this.VisitTypeNode(Class);
+ }
+#if !MinimalReader
+ public virtual Expression VisitCoerceTuple(CoerceTuple coerceTuple)
+ {
+ if (coerceTuple == null) return null;
+ coerceTuple.OriginalTuple = this.VisitExpression(coerceTuple.OriginalTuple);
+ return this.VisitConstructTuple(coerceTuple);
+ }
+ public virtual CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce)
+ {
+ if (ce == null) return null;
+ ce.Collection = this.VisitExpression(ce.Collection);
+ return ce;
+ }
+ public virtual Compilation VisitCompilation(Compilation compilation)
+ {
+ if (compilation == null) return null;
+ Module module = compilation.TargetModule;
+ if (module != null)
+ module.Attributes = this.VisitAttributeList(module.Attributes);
+ AssemblyNode assem = module as AssemblyNode;
+ if (assem != null)
+ assem.ModuleAttributes = this.VisitAttributeList(assem.ModuleAttributes);
+ compilation.CompilationUnits = this.VisitCompilationUnitList(compilation.CompilationUnits);
+ return compilation;
+ }
+ public virtual CompilationUnit VisitCompilationUnit(CompilationUnit cUnit)
+ {
+ if (cUnit == null) return null;
+ cUnit.Nodes = this.VisitNodeList(cUnit.Nodes);
+ return cUnit;
+ }
+ public virtual NodeList VisitNodeList(NodeList nodes)
+ {
+ if (nodes == null) return null;
+ for (int i = 0, n = nodes.Count; i < n; i++)
+ nodes[i] = this.Visit(nodes[i]);
+ return nodes;
+ }
+ public virtual CompilationUnitList VisitCompilationUnitList(CompilationUnitList compilationUnits)
+ {
+ if (compilationUnits == null) return null;
+ for (int i = 0, n = compilationUnits.Count; i < n; i++)
+ compilationUnits[i] = (CompilationUnit)this.Visit(compilationUnits[i]);
+ return compilationUnits;
+ }
+ public virtual CompilationUnit VisitCompilationUnitSnippet(CompilationUnitSnippet snippet)
+ {
+ return this.VisitCompilationUnit(snippet);
+ }
+ public virtual Node VisitComposition(Composition comp)
+ {
+ if (comp == null) return null;
+ if (comp.GetType() == typeof(Composition))
+ {
+ comp.Expression = (Expression)this.Visit(comp.Expression);
+ return comp;
+ }
+ return this.VisitUnknownNodeType(comp);
+ }
+#endif
+ public virtual Expression VisitConstruct(Construct cons)
+ {
+ if (cons == null) return null;
+ cons.Constructor = this.VisitExpression(cons.Constructor);
+ cons.Operands = this.VisitExpressionList(cons.Operands);
+#if !MinimalReader
+ cons.Owner = this.VisitExpression(cons.Owner);
+#endif
+ return cons;
+ }
+ public virtual Expression VisitConstructArray(ConstructArray consArr)
+ {
+ if (consArr == null) return null;
+ consArr.ElementType = this.VisitTypeReference(consArr.ElementType);
+ consArr.Operands = this.VisitExpressionList(consArr.Operands);
+#if !MinimalReader
+ consArr.Initializers = this.VisitExpressionList(consArr.Initializers);
+ consArr.Owner = this.VisitExpression(consArr.Owner);
+#endif
+ return consArr;
+ }
+#if !MinimalReader
+ public virtual Expression VisitConstructDelegate(ConstructDelegate consDelegate)
+ {
+ if (consDelegate == null) return null;
+ consDelegate.DelegateType = this.VisitTypeReference(consDelegate.DelegateType);
+ consDelegate.TargetObject = this.VisitExpression(consDelegate.TargetObject);
+ return consDelegate;
+ }
+ public virtual Expression VisitConstructFlexArray(ConstructFlexArray consArr)
+ {
+ if (consArr == null) return null;
+ consArr.ElementType = this.VisitTypeReference(consArr.ElementType);
+ consArr.Operands = this.VisitExpressionList(consArr.Operands);
+ consArr.Initializers = this.VisitExpressionList(consArr.Initializers);
+ return consArr;
+ }
+ public virtual Expression VisitConstructIterator(ConstructIterator consIterator)
+ {
+ return consIterator;
+ }
+ public virtual Expression VisitConstructTuple(ConstructTuple consTuple)
+ {
+ if (consTuple == null) return null;
+ consTuple.Fields = this.VisitFieldList(consTuple.Fields);
+ return consTuple;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual TypeNode VisitConstrainedType(ConstrainedType cType){
+ if (cType == null) return null;
+ cType.UnderlyingType = this.VisitTypeReference(cType.UnderlyingType);
+ cType.Constraint = this.VisitExpression(cType.Constraint);
+ return cType;
+ }
+#endif
+#if !MinimalReader
+ public virtual Statement VisitContinue(Continue Continue)
+ {
+ return Continue;
+ }
+ public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure)
+ {
+ return currentClosure;
+ }
+#endif
+ public virtual DelegateNode VisitDelegateNode(DelegateNode delegateNode)
+ {
+ if (delegateNode == null) return null;
+ delegateNode = (DelegateNode)this.VisitTypeNode(delegateNode);
+ if (delegateNode == null) return null;
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType);
+ return delegateNode;
+ }
+#if !MinimalReader
+ public virtual Statement VisitDoWhile(DoWhile doWhile)
+ {
+ if (doWhile == null) return null;
+ doWhile.Invariants = this.VisitLoopInvariantList(doWhile.Invariants);
+ doWhile.Body = this.VisitBlock(doWhile.Body);
+ doWhile.Condition = this.VisitExpression(doWhile.Condition);
+ return doWhile;
+ }
+#endif
+ public virtual Statement VisitEndFilter(EndFilter endFilter)
+ {
+ if (endFilter == null) return null;
+ endFilter.Value = this.VisitExpression(endFilter.Value);
+ return endFilter;
+ }
+ public virtual Statement VisitEndFinally(EndFinally endFinally)
+ {
+ return endFinally;
+ }
+#if ExtendedRuntime
+ public virtual EnsuresList VisitEnsuresList(EnsuresList Ensures) {
+ if (Ensures == null) return null;
+ for (int i = 0, n = Ensures.Count; i < n; i++)
+ Ensures[i] = (Ensures) this.Visit(Ensures[i]);
+ return Ensures;
+ }
+#endif
+ public virtual EnumNode VisitEnumNode(EnumNode enumNode)
+ {
+ return (EnumNode)this.VisitTypeNode(enumNode);
+ }
+ public virtual Event VisitEvent(Event evnt)
+ {
+ if (evnt == null) return null;
+ evnt.Attributes = this.VisitAttributeList(evnt.Attributes);
+ evnt.HandlerType = this.VisitTypeReference(evnt.HandlerType);
+ return evnt;
+ }
+#if ExtendedRuntime
+ public virtual EnsuresExceptional VisitEnsuresExceptional(EnsuresExceptional exceptional) {
+ if (exceptional == null) return null;
+ exceptional.PostCondition = this.VisitExpression(exceptional.PostCondition);
+ exceptional.Type = this.VisitTypeReference(exceptional.Type);
+ exceptional.Variable = this.VisitExpression(exceptional.Variable);
+ return exceptional;
+ }
+#endif
+#if !MinimalReader
+ public virtual Statement VisitExit(Exit exit)
+ {
+ return exit;
+ }
+ public virtual Statement VisitExpose(Expose @expose)
+ {
+ if (@expose == null) return null;
+ @expose.Instance = this.VisitExpression(@expose.Instance);
+ @expose.Body = this.VisitBlock(expose.Body);
+ return expose;
+ }
+#endif
+
+ public virtual Expression VisitExpression(Expression expression)
+ {
+ if (expression == null) return null;
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ case NodeType.Arglist:
+ return expression;
+ case NodeType.Pop:
+ UnaryExpression uex = expression as UnaryExpression;
+ if (uex != null)
+ {
+ uex.Operand = this.VisitExpression(uex.Operand);
+ return uex;
+ }
+ return expression;
+ default:
+ return (Expression)this.Visit(expression);
+ }
+ }
+ public override ExpressionList VisitExpressionList(ExpressionList expressions)
+ {
+ if (expressions == null) return null;
+ for (int i = 0, n = expressions.Count; i < n; i++)
+ expressions[i] = this.VisitExpression(expressions[i]);
+ return expressions;
+ }
+#if !MinimalReader
+ public virtual Expression VisitExpressionSnippet(ExpressionSnippet snippet)
+ {
+ return snippet;
+ }
+#endif
+ public virtual Statement VisitExpressionStatement(ExpressionStatement statement)
+ {
+ if (statement == null) return null;
+ statement.Expression = this.VisitExpression(statement.Expression);
+ return statement;
+ }
+#if !MinimalReader
+ public virtual Statement VisitFaultHandler(FaultHandler faultHandler)
+ {
+ if (faultHandler == null) return null;
+ faultHandler.Block = this.VisitBlock(faultHandler.Block);
+ return faultHandler;
+ }
+ public virtual FaultHandlerList VisitFaultHandlerList(FaultHandlerList faultHandlers)
+ {
+ if (faultHandlers == null) return null;
+ for (int i = 0, n = faultHandlers.Count; i < n; i++)
+ faultHandlers[i] = (FaultHandler)this.VisitFaultHandler(faultHandlers[i]);
+ return faultHandlers;
+ }
+#endif
+ public virtual Field VisitField(Field field)
+ {
+ if (field == null) return null;
+ field.Attributes = this.VisitAttributeList(field.Attributes);
+ field.Type = this.VisitTypeReference(field.Type);
+#if !MinimalReader
+ field.Initializer = this.VisitExpression(field.Initializer);
+ field.ImplementedInterfaces = this.VisitInterfaceReferenceList(field.ImplementedInterfaces);
+#endif
+ return field;
+ }
+#if !MinimalReader
+ public virtual Block VisitFieldInitializerBlock(FieldInitializerBlock block)
+ {
+ if (block == null) return null;
+ block.Type = this.VisitTypeReference(block.Type);
+ return this.VisitBlock(block);
+ }
+ public virtual FieldList VisitFieldList(FieldList fields)
+ {
+ if (fields == null) return null;
+ for (int i = 0, n = fields.Count; i < n; i++)
+ fields[i] = this.VisitField(fields[i]);
+ return fields;
+ }
+ public virtual Statement VisitFilter(Filter filter)
+ {
+ if (filter == null) return null;
+ filter.Expression = this.VisitExpression(filter.Expression);
+ filter.Block = this.VisitBlock(filter.Block);
+ return filter;
+ }
+ public virtual FilterList VisitFilterList(FilterList filters)
+ {
+ if (filters == null) return null;
+ for (int i = 0, n = filters.Count; i < n; i++)
+ filters[i] = (Filter)this.VisitFilter(filters[i]);
+ return filters;
+ }
+ public virtual Statement VisitFinally(Finally Finally)
+ {
+ if (Finally == null) return null;
+ Finally.Block = this.VisitBlock(Finally.Block);
+ return Finally;
+ }
+ public virtual Statement VisitFixed(Fixed Fixed)
+ {
+ if (Fixed == null) return null;
+ Fixed.Declarators = (Statement)this.Visit(Fixed.Declarators);
+ Fixed.Body = this.VisitBlock(Fixed.Body);
+ return Fixed;
+ }
+ public virtual Statement VisitFor(For For)
+ {
+ if (For == null) return null;
+ For.Initializer = this.VisitStatementList(For.Initializer);
+ For.Invariants = this.VisitLoopInvariantList(For.Invariants);
+ For.Condition = this.VisitExpression(For.Condition);
+ For.Incrementer = this.VisitStatementList(For.Incrementer);
+ For.Body = this.VisitBlock(For.Body);
+ return For;
+ }
+ public virtual Statement VisitForEach(ForEach forEach)
+ {
+ if (forEach == null) return null;
+ forEach.TargetVariableType = this.VisitTypeReference(forEach.TargetVariableType);
+ forEach.TargetVariable = this.VisitTargetExpression(forEach.TargetVariable);
+ forEach.SourceEnumerable = this.VisitExpression(forEach.SourceEnumerable);
+ forEach.InductionVariable = this.VisitTargetExpression(forEach.InductionVariable);
+ forEach.Invariants = this.VisitLoopInvariantList(forEach.Invariants);
+ forEach.Body = this.VisitBlock(forEach.Body);
+ return forEach;
+ }
+ public virtual Statement VisitFunctionDeclaration(FunctionDeclaration functionDeclaration)
+ {
+ if (functionDeclaration == null) return null;
+ functionDeclaration.Parameters = this.VisitParameterList(functionDeclaration.Parameters);
+ functionDeclaration.ReturnType = this.VisitTypeReference(functionDeclaration.ReturnType);
+ functionDeclaration.Body = this.VisitBlock(functionDeclaration.Body);
+ return functionDeclaration;
+ }
+ public virtual Expression VisitTemplateInstance(TemplateInstance templateInstance)
+ {
+ if (templateInstance == null) return null;
+ templateInstance.Expression = this.VisitExpression(templateInstance.Expression);
+ templateInstance.TypeArguments = this.VisitTypeReferenceList(templateInstance.TypeArguments);
+ return templateInstance;
+ }
+ public virtual Expression VisitStackAlloc(StackAlloc alloc)
+ {
+ if (alloc == null) return null;
+ alloc.ElementType = this.VisitTypeReference(alloc.ElementType);
+ alloc.NumberOfElements = this.VisitExpression(alloc.NumberOfElements);
+ return alloc;
+ }
+ public virtual Statement VisitGoto(Goto Goto)
+ {
+ return Goto;
+ }
+ public virtual Statement VisitGotoCase(GotoCase gotoCase)
+ {
+ if (gotoCase == null) return null;
+ gotoCase.CaseLabel = this.VisitExpression(gotoCase.CaseLabel);
+ return gotoCase;
+ }
+#endif
+ public virtual Expression VisitIdentifier(Identifier identifier)
+ {
+ return identifier;
+ }
+#if !MinimalReader
+ public virtual Statement VisitIf(If If)
+ {
+ if (If == null) return null;
+ If.Condition = this.VisitExpression(If.Condition);
+ If.TrueBlock = this.VisitBlock(If.TrueBlock);
+ If.FalseBlock = this.VisitBlock(If.FalseBlock);
+ return If;
+ }
+ public virtual Expression VisitImplicitThis(ImplicitThis implicitThis)
+ {
+ return implicitThis;
+ }
+#endif
+ public virtual Expression VisitIndexer(Indexer indexer)
+ {
+ if (indexer == null) return null;
+ indexer.Object = this.VisitExpression(indexer.Object);
+ indexer.Operands = this.VisitExpressionList(indexer.Operands);
+ return indexer;
+ }
+ public virtual Interface VisitInterface(Interface Interface)
+ {
+ return (Interface)this.VisitTypeNode(Interface);
+ }
+ public virtual Interface VisitInterfaceReference(Interface Interface)
+ {
+ return (Interface)this.VisitTypeReference(Interface);
+ }
+ public virtual InterfaceList VisitInterfaceReferenceList(InterfaceList interfaceReferences)
+ {
+ if (interfaceReferences == null) return null;
+ for (int i = 0, n = interfaceReferences.Count; i < n; i++)
+ interfaceReferences[i] = this.VisitInterfaceReference(interfaceReferences[i]);
+ return interfaceReferences;
+ }
+#if ExtendedRuntime
+ public virtual Invariant VisitInvariant(Invariant @invariant){
+ if (@invariant == null) return null;
+ @invariant.Condition = VisitExpression(@invariant.Condition);
+ return @invariant;
+ }
+ public virtual InvariantList VisitInvariantList(InvariantList invariants){
+ if (invariants == null) return null;
+ for (int i = 0, n = invariants.Count; i < n; i++)
+ invariants[i] = this.VisitInvariant(invariants[i]);
+ return invariants;
+ }
+ public virtual ModelfieldContract VisitModelfieldContract(ModelfieldContract mfC) {
+ if (mfC == null) return null;
+ mfC.Witness = this.VisitExpression(mfC.Witness);
+ for (int i = 0, n = mfC.SatisfiesList.Count; i < n; i++)
+ mfC.SatisfiesList[i] = this.VisitExpression(mfC.SatisfiesList[i]);
+ return mfC;
+ }
+ public virtual ModelfieldContractList VisitModelfieldContractList(ModelfieldContractList mfCs) {
+ if (mfCs == null) return null;
+ for (int i = 0, n = mfCs.Count; i < n; i++)
+ mfCs[i] = this.VisitModelfieldContract(mfCs[i]);
+ return mfCs;
+ }
+#endif
+ public virtual InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons)
+ {
+ return (InstanceInitializer)this.VisitMethod(cons);
+ }
+#if !MinimalReader
+ public virtual Statement VisitLabeledStatement(LabeledStatement lStatement)
+ {
+ if (lStatement == null) return null;
+ lStatement.Statement = (Statement)this.Visit(lStatement.Statement);
+ return lStatement;
+ }
+#endif
+ public virtual Expression VisitLiteral(Literal literal)
+ {
+ return literal;
+ }
+ public virtual Expression VisitLocal(Local local)
+ {
+ if (local == null) return null;
+ local.Type = this.VisitTypeReference(local.Type);
+#if !MinimalReader
+ LocalBinding lb = local as LocalBinding;
+ if (lb != null)
+ {
+ Local loc = this.VisitLocal(lb.BoundLocal) as Local;
+ if (loc != null)
+ lb.BoundLocal = loc;
+ }
+#endif
+ return local;
+ }
+#if !MinimalReader
+ public virtual Statement VisitLocalDeclarationsStatement(LocalDeclarationsStatement localDeclarations)
+ {
+ if (localDeclarations == null) return null;
+ localDeclarations.Type = this.VisitTypeReference(localDeclarations.Type);
+ localDeclarations.Declarations = this.VisitLocalDeclarationList(localDeclarations.Declarations);
+ return localDeclarations;
+ }
+ public virtual LocalDeclarationList VisitLocalDeclarationList(LocalDeclarationList localDeclarations)
+ {
+ if (localDeclarations == null) return null;
+ for (int i = 0, n = localDeclarations.Count; i < n; i++)
+ localDeclarations[i] = this.VisitLocalDeclaration(localDeclarations[i]);
+ return localDeclarations;
+ }
+ public virtual LocalDeclaration VisitLocalDeclaration(LocalDeclaration localDeclaration)
+ {
+ if (localDeclaration == null) return null;
+ localDeclaration.InitialValue = this.VisitExpression(localDeclaration.InitialValue);
+ return localDeclaration;
+ }
+ public virtual Statement VisitLock(Lock Lock)
+ {
+ if (Lock == null) return null;
+ Lock.Guard = this.VisitExpression(Lock.Guard);
+ Lock.Body = this.VisitBlock(Lock.Body);
+ return Lock;
+ }
+ public virtual Expression VisitLRExpression(LRExpression expr)
+ {
+ if (expr == null) return null;
+ expr.Expression = this.VisitExpression(expr.Expression);
+ return expr;
+ }
+#endif
+ public virtual Expression VisitMemberBinding(MemberBinding memberBinding)
+ {
+ if (memberBinding == null) return null;
+ memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject);
+ return memberBinding;
+ }
+ public virtual MemberList VisitMemberList(MemberList members)
+ {
+ this.memberListNamesChanged = false;
+ if (members == null) return null;
+ for (int i = 0, n = members.Count; i < n; i++)
+ {
+ Member oldm = members[i];
+ if (oldm != null)
+ {
+ Identifier oldId = oldm.Name;
+ members[i] = (Member)this.Visit(oldm);
+ if (members[i] != null)
+ {
+ if (oldId != null && members[i].Name != null && members[i].Name.UniqueIdKey != oldId.UniqueIdKey)
+ {
+ this.memberListNamesChanged = true;
+ }
+ }
+ }
+ }
+ return members;
+ }
+ public virtual Method VisitMethod(Method method)
+ {
+ if (method == null) return null;
+ method.Attributes = this.VisitAttributeList(method.Attributes);
+ method.ReturnAttributes = this.VisitAttributeList(method.ReturnAttributes);
+ method.SecurityAttributes = this.VisitSecurityAttributeList(method.SecurityAttributes);
+ method.ReturnType = this.VisitTypeReference(method.ReturnType);
+#if !MinimalReader
+ method.ImplementedTypes = this.VisitTypeReferenceList(method.ImplementedTypes);
+#endif
+ method.Parameters = this.VisitParameterList(method.Parameters);
+ if (TargetPlatform.UseGenerics)
+ {
+ method.TemplateArguments = this.VisitTypeReferenceList(method.TemplateArguments);
+ method.TemplateParameters = this.VisitTypeParameterList(method.TemplateParameters);
+ }
+#if ExtendedRuntime
+ method.Contract = this.VisitMethodContract(method.Contract);
+#endif
+ method.Body = this.VisitBlock(method.Body);
+ return method;
+ }
+ public virtual Expression VisitMethodCall(MethodCall call)
+ {
+ if (call == null) return null;
+ call.Callee = this.VisitExpression(call.Callee);
+ call.Operands = this.VisitExpressionList(call.Operands);
+ call.Constraint = this.VisitTypeReference(call.Constraint);
+ return call;
+ }
+#if !MinimalReader
+ public virtual Expression VisitArglistArgumentExpression(ArglistArgumentExpression argexp)
+ {
+ if (argexp == null) return null;
+ argexp.Operands = this.VisitExpressionList(argexp.Operands);
+ return argexp;
+ }
+ public virtual Expression VisitArglistExpression(ArglistExpression argexp)
+ {
+ if (argexp == null) return null;
+ return argexp;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual MethodContract VisitMethodContract(MethodContract contract){
+ if (contract == null) return null;
+ // don't visit contract.DeclaringMethod
+ // don't visit contract.OverriddenMethods
+ contract.Requires = this.VisitRequiresList(contract.Requires);
+ contract.Ensures = this.VisitEnsuresList(contract.Ensures);
+ contract.Modifies = this.VisitExpressionList(contract.Modifies);
+ return contract;
+ }
+#endif
+ public virtual Module VisitModule(Module module)
+ {
+ if (module == null) return null;
+ module.Attributes = this.VisitAttributeList(module.Attributes);
+ module.Types = this.VisitTypeNodeList(module.Types);
+ return module;
+ }
+ public virtual ModuleReference VisitModuleReference(ModuleReference moduleReference)
+ {
+ return moduleReference;
+ }
+#if !MinimalReader
+ public virtual Expression VisitNameBinding(NameBinding nameBinding)
+ {
+ return nameBinding;
+ }
+#endif
+ public virtual Expression VisitNamedArgument(NamedArgument namedArgument)
+ {
+ if (namedArgument == null) return null;
+ namedArgument.Value = this.VisitExpression(namedArgument.Value);
+ return namedArgument;
+ }
+#if !MinimalReader
+ public virtual Namespace VisitNamespace(Namespace nspace)
+ {
+ if (nspace == null) return null;
+ nspace.AliasDefinitions = this.VisitAliasDefinitionList(nspace.AliasDefinitions);
+ nspace.UsedNamespaces = this.VisitUsedNamespaceList(nspace.UsedNamespaces);
+ nspace.Attributes = this.VisitAttributeList(nspace.Attributes);
+ nspace.Types = this.VisitTypeNodeList(nspace.Types);
+ nspace.NestedNamespaces = this.VisitNamespaceList(nspace.NestedNamespaces);
+ return nspace;
+ }
+ public virtual NamespaceList VisitNamespaceList(NamespaceList namespaces)
+ {
+ if (namespaces == null) return null;
+ for (int i = 0, n = namespaces.Count; i < n; i++)
+ namespaces[i] = this.VisitNamespace(namespaces[i]);
+ return namespaces;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual EnsuresNormal VisitEnsuresNormal(EnsuresNormal normal) {
+ if (normal == null) return null;
+ normal.PostCondition = this.VisitExpression(normal.PostCondition);
+ return normal;
+ }
+ public virtual Expression VisitOldExpression(OldExpression oldExpression) {
+ if (oldExpression == null) return null;
+ oldExpression.expression = this.VisitExpression(oldExpression.expression);
+ return oldExpression;
+ }
+ public virtual RequiresOtherwise VisitRequiresOtherwise(RequiresOtherwise otherwise) {
+ if (otherwise == null) return null;
+ otherwise.Condition = this.VisitExpression(otherwise.Condition);
+ otherwise.ThrowException = this.VisitExpression(otherwise.ThrowException);
+ return otherwise;
+ }
+ public virtual RequiresPlain VisitRequiresPlain(RequiresPlain plain) {
+ if (plain == null) return null;
+ plain.Condition = this.VisitExpression(plain.Condition);
+ return plain;
+ }
+#endif
+ public virtual Expression VisitParameter(Parameter parameter)
+ {
+ if (parameter == null) return null;
+ parameter.Attributes = this.VisitAttributeList(parameter.Attributes);
+ parameter.Type = this.VisitTypeReference(parameter.Type);
+ parameter.DefaultValue = this.VisitExpression(parameter.DefaultValue);
+#if !MinimalReader
+ ParameterBinding pb = parameter as ParameterBinding;
+ if (pb != null)
+ {
+ Parameter par = this.VisitParameter(pb.BoundParameter) as Parameter;
+ if (par != null)
+ pb.BoundParameter = par;
+ }
+#endif
+ return parameter;
+ }
+ public virtual ParameterList VisitParameterList(ParameterList parameterList)
+ {
+ if (parameterList == null) return null;
+ for (int i = 0, n = parameterList.Count; i < n; i++)
+ parameterList[i] = (Parameter)this.VisitParameter(parameterList[i]);
+ return parameterList;
+ }
+#if !MinimalReader
+ public virtual Expression VisitPrefixExpression(PrefixExpression pExpr)
+ {
+ if (pExpr == null) return null;
+ pExpr.Expression = this.VisitExpression(pExpr.Expression);
+ return pExpr;
+ }
+ public virtual Expression VisitPostfixExpression(PostfixExpression pExpr)
+ {
+ if (pExpr == null) return null;
+ pExpr.Expression = this.VisitExpression(pExpr.Expression);
+ return pExpr;
+ }
+#endif
+ public virtual Property VisitProperty(Property property)
+ {
+ if (property == null) return null;
+ property.Attributes = this.VisitAttributeList(property.Attributes);
+ property.Parameters = this.VisitParameterList(property.Parameters);
+ property.Type = this.VisitTypeReference(property.Type);
+ return property;
+ }
+#if !MinimalReader
+ public virtual Expression VisitQuantifier(Quantifier quantifier)
+ {
+ if (quantifier == null) return null;
+ quantifier.Comprehension = (Comprehension)this.VisitComprehension(quantifier.Comprehension);
+ return quantifier;
+ }
+ public virtual Expression VisitComprehension(Comprehension comprehension)
+ {
+ if (comprehension == null) return null;
+ comprehension.BindingsAndFilters = this.VisitExpressionList(comprehension.BindingsAndFilters);
+ comprehension.Elements = this.VisitExpressionList(comprehension.Elements);
+ return comprehension;
+ }
+ public virtual ComprehensionBinding VisitComprehensionBinding(ComprehensionBinding comprehensionBinding)
+ {
+ if (comprehensionBinding == null) return null;
+ comprehensionBinding.TargetVariableType = this.VisitTypeReference(comprehensionBinding.TargetVariableType);
+ comprehensionBinding.TargetVariable = this.VisitTargetExpression(comprehensionBinding.TargetVariable);
+ comprehensionBinding.AsTargetVariableType = this.VisitTypeReference(comprehensionBinding.AsTargetVariableType);
+ comprehensionBinding.SourceEnumerable = this.VisitExpression(comprehensionBinding.SourceEnumerable);
+ return comprehensionBinding;
+ }
+ public virtual Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier)
+ {
+ if (qualifiedIdentifier == null) return null;
+ qualifiedIdentifier.Qualifier = this.VisitExpression(qualifiedIdentifier.Qualifier);
+ return qualifiedIdentifier;
+ }
+ public virtual Expression VisitRefValueExpression(RefValueExpression refvalexp)
+ {
+ if (refvalexp == null) return null;
+ refvalexp.Operand1 = this.VisitExpression(refvalexp.Operand1);
+ refvalexp.Operand2 = this.VisitExpression(refvalexp.Operand2);
+ return refvalexp;
+ }
+ public virtual Expression VisitRefTypeExpression(RefTypeExpression reftypexp)
+ {
+ if (reftypexp == null) return null;
+ reftypexp.Operand = this.VisitExpression(reftypexp.Operand);
+ return reftypexp;
+ }
+ public virtual Statement VisitRepeat(Repeat repeat)
+ {
+ if (repeat == null) return null;
+ repeat.Body = this.VisitBlock(repeat.Body);
+ repeat.Condition = this.VisitExpression(repeat.Condition);
+ return repeat;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual RequiresList VisitRequiresList(RequiresList Requires) {
+ if (Requires == null) return null;
+ for (int i = 0, n = Requires.Count; i < n; i++)
+ Requires[i] = (Requires) this.Visit(Requires[i]);
+ return Requires;
+ }
+#endif
+ public virtual Statement VisitReturn(Return Return)
+ {
+ if (Return == null) return null;
+ Return.Expression = this.VisitExpression(Return.Expression);
+ return Return;
+ }
+#if !MinimalReader
+ public virtual Statement VisitAcquire(Acquire @acquire)
+ {
+ if (@acquire == null) return null;
+ @acquire.Target = (Statement)this.Visit(@acquire.Target);
+ @acquire.Condition = this.VisitExpression(@acquire.Condition);
+ @acquire.ConditionFunction = this.VisitExpression(@acquire.ConditionFunction);
+ @acquire.Body = this.VisitBlock(@acquire.Body);
+ return @acquire;
+ }
+ public virtual Statement VisitResourceUse(ResourceUse resourceUse)
+ {
+ if (resourceUse == null) return null;
+ resourceUse.ResourceAcquisition = (Statement)this.Visit(resourceUse.ResourceAcquisition);
+ resourceUse.Body = this.VisitBlock(resourceUse.Body);
+ return resourceUse;
+ }
+#endif
+ public virtual SecurityAttribute VisitSecurityAttribute(SecurityAttribute attribute)
+ {
+ return attribute;
+ }
+ public virtual SecurityAttributeList VisitSecurityAttributeList(SecurityAttributeList attributes)
+ {
+ if (attributes == null) return null;
+ for (int i = 0, n = attributes.Count; i < n; i++)
+ attributes[i] = this.VisitSecurityAttribute(attributes[i]);
+ return attributes;
+ }
+#if !MinimalReader
+ public virtual Expression VisitSetterValue(SetterValue value)
+ {
+ return value;
+ }
+#endif
+ public virtual StatementList VisitStatementList(StatementList statements)
+ {
+ if (statements == null) return null;
+ for (int i = 0, n = statements.Count; i < n; i++)
+ statements[i] = (Statement)this.Visit(statements[i]);
+ return statements;
+ }
+#if !MinimalReader
+ public virtual StatementSnippet VisitStatementSnippet(StatementSnippet snippet)
+ {
+ return snippet;
+ }
+#endif
+ public virtual StaticInitializer VisitStaticInitializer(StaticInitializer cons)
+ {
+ return (StaticInitializer)this.VisitMethod(cons);
+ }
+ public virtual Struct VisitStruct(Struct Struct)
+ {
+ return (Struct)this.VisitTypeNode(Struct);
+ }
+#if !MinimalReader
+ public virtual Statement VisitSwitch(Switch Switch)
+ {
+ if (Switch == null) return null;
+ Switch.Expression = this.VisitExpression(Switch.Expression);
+ Switch.Cases = this.VisitSwitchCaseList(Switch.Cases);
+ return Switch;
+ }
+ public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase)
+ {
+ if (switchCase == null) return null;
+ switchCase.Label = this.VisitExpression(switchCase.Label);
+ switchCase.Body = this.VisitBlock(switchCase.Body);
+ return switchCase;
+ }
+ public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases)
+ {
+ if (switchCases == null) return null;
+ for (int i = 0, n = switchCases.Count; i < n; i++)
+ switchCases[i] = this.Visit(switchCases[i]) as SwitchCase;
+ return switchCases;
+ }
+#endif
+ public virtual Statement VisitSwitchInstruction(SwitchInstruction switchInstruction)
+ {
+ if (switchInstruction == null) return null;
+ switchInstruction.Expression = this.VisitExpression(switchInstruction.Expression);
+ return switchInstruction;
+ }
+#if !MinimalReader
+ public virtual Statement VisitTypeswitch(Typeswitch Typeswitch)
+ {
+ if (Typeswitch == null) return null;
+ Typeswitch.Expression = this.VisitExpression(Typeswitch.Expression);
+ Typeswitch.Cases = this.VisitTypeswitchCaseList(Typeswitch.Cases);
+ return Typeswitch;
+ }
+ public virtual TypeswitchCase VisitTypeswitchCase(TypeswitchCase typeswitchCase)
+ {
+ if (typeswitchCase == null) return null;
+ typeswitchCase.LabelType = this.VisitTypeReference(typeswitchCase.LabelType);
+ typeswitchCase.LabelVariable = this.VisitTargetExpression(typeswitchCase.LabelVariable);
+ typeswitchCase.Body = this.VisitBlock(typeswitchCase.Body);
+ return typeswitchCase;
+ }
+ public virtual TypeswitchCaseList VisitTypeswitchCaseList(TypeswitchCaseList typeswitchCases)
+ {
+ if (typeswitchCases == null) return null;
+ for (int i = 0, n = typeswitchCases.Count; i < n; i++)
+ typeswitchCases[i] = this.VisitTypeswitchCase(typeswitchCases[i]);
+ return typeswitchCases;
+ }
+#endif
+ public virtual Expression VisitTargetExpression(Expression expression)
+ {
+ return this.VisitExpression(expression);
+ }
+ public virtual Expression VisitTernaryExpression(TernaryExpression expression)
+ {
+ if (expression == null) return null;
+ expression.Operand1 = this.VisitExpression(expression.Operand1);
+ expression.Operand2 = this.VisitExpression(expression.Operand2);
+ expression.Operand3 = this.VisitExpression(expression.Operand3);
+ return expression;
+ }
+ public virtual Expression VisitThis(This This)
+ {
+ if (This == null) return null;
+ This.Type = this.VisitTypeReference(This.Type);
+#if !MinimalReader
+ ThisBinding tb = This as ThisBinding;
+ if (tb != null)
+ {
+ This boundThis = this.VisitThis(tb.BoundThis) as This;
+ if (boundThis != null)
+ tb.BoundThis = boundThis;
+ }
+#endif
+ return This;
+ }
+ public virtual Statement VisitThrow(Throw Throw)
+ {
+ if (Throw == null) return null;
+ Throw.Expression = this.VisitExpression(Throw.Expression);
+ return Throw;
+ }
+#if !MinimalReader
+ public virtual Statement VisitTry(Try Try)
+ {
+ if (Try == null) return null;
+ Try.TryBlock = this.VisitBlock(Try.TryBlock);
+ Try.Catchers = this.VisitCatchList(Try.Catchers);
+ Try.Filters = this.VisitFilterList(Try.Filters);
+ Try.FaultHandlers = this.VisitFaultHandlerList(Try.FaultHandlers);
+ Try.Finally = (Finally)this.VisitFinally(Try.Finally);
+ return Try;
+ }
+#endif
+#if ExtendedRuntime
+ public virtual TupleType VisitTupleType(TupleType tuple){
+ return (TupleType)this.VisitTypeNode(tuple);
+ }
+ public virtual TypeAlias VisitTypeAlias(TypeAlias tAlias){
+ if (tAlias == null) return null;
+ if (tAlias.AliasedType is ConstrainedType)
+ //The type alias defines the constrained type, rather than just referencing it
+ tAlias.AliasedType = this.VisitConstrainedType((ConstrainedType)tAlias.AliasedType);
+ else
+ tAlias.AliasedType = this.VisitTypeReference(tAlias.AliasedType);
+ return tAlias;
+ }
+ public virtual TypeContract VisitTypeContract(TypeContract contract){
+ if (contract == null) return null;
+ // don't visit contract.DeclaringType
+ // don't visit contract.InheritedContracts
+ contract.Invariants = this.VisitInvariantList(contract.Invariants);
+ contract.ModelfieldContracts = this.VisitModelfieldContractList(contract.ModelfieldContracts);
+ return contract;
+ }
+
+ public virtual TypeIntersection VisitTypeIntersection(TypeIntersection typeIntersection){
+ return (TypeIntersection)this.VisitTypeNode(typeIntersection);
+ }
+#endif
+#if !MinimalReader
+ public virtual TypeMemberSnippet VisitTypeMemberSnippet(TypeMemberSnippet snippet)
+ {
+ return snippet;
+ }
+#endif
+ public virtual TypeModifier VisitTypeModifier(TypeModifier typeModifier)
+ {
+ if (typeModifier == null) return null;
+ typeModifier.Modifier = this.VisitTypeReference(typeModifier.Modifier);
+ typeModifier.ModifiedType = this.VisitTypeReference(typeModifier.ModifiedType);
+ return typeModifier;
+ }
+ public virtual TypeNode VisitTypeNode(TypeNode typeNode)
+ {
+ if (typeNode == null) return null;
+ typeNode.Attributes = this.VisitAttributeList(typeNode.Attributes);
+ typeNode.SecurityAttributes = this.VisitSecurityAttributeList(typeNode.SecurityAttributes);
+ Class c = typeNode as Class;
+ if (c != null) c.BaseClass = (Class)this.VisitTypeReference(c.BaseClass);
+ typeNode.Interfaces = this.VisitInterfaceReferenceList(typeNode.Interfaces);
+ typeNode.TemplateArguments = this.VisitTypeReferenceList(typeNode.TemplateArguments);
+ typeNode.TemplateParameters = this.VisitTypeParameterList(typeNode.TemplateParameters);
+ this.VisitMemberList(typeNode.Members);
+ if (this.memberListNamesChanged) { typeNode.ClearMemberTable(); }
+#if ExtendedRuntime
+ // have to visit this *after* visiting the members since in Normalizer
+ // it creates normalized method bodies for the invariant methods and
+ // those shouldn't be visited again!!
+ // REVIEW!! I don't think the method bodies created in Normalizer are necessarily normalized anymore!!
+ typeNode.Contract = this.VisitTypeContract(typeNode.Contract);
+#endif
+ return typeNode;
+ }
+ public virtual TypeNodeList VisitTypeNodeList(TypeNodeList types)
+ {
+ if (types == null) return null;
+ for (int i = 0; i < types.Count; i++) //Visiting a type may result in a new type being appended to this list
+ types[i] = (TypeNode)this.Visit(types[i]);
+ return types;
+ }
+ public virtual TypeNode VisitTypeParameter(TypeNode typeParameter)
+ {
+ if (typeParameter == null) return null;
+ Class cl = typeParameter as Class;
+ if (cl != null) cl.BaseClass = (Class)this.VisitTypeReference(cl.BaseClass);
+ typeParameter.Attributes = this.VisitAttributeList(typeParameter.Attributes);
+ typeParameter.Interfaces = this.VisitInterfaceReferenceList(typeParameter.Interfaces);
+ return typeParameter;
+ }
+ public virtual TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters)
+ {
+ if (typeParameters == null) return null;
+ for (int i = 0, n = typeParameters.Count; i < n; i++)
+ typeParameters[i] = this.VisitTypeParameter(typeParameters[i]);
+ return typeParameters;
+ }
+ public virtual TypeNode VisitTypeReference(TypeNode type)
+ {
+ return type;
+ }
+#if !MinimalReader
+ public virtual TypeReference VisitTypeReference(TypeReference type)
+ {
+ return type;
+ }
+#endif
+ public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences)
+ {
+ if (typeReferences == null) return null;
+ for (int i = 0, n = typeReferences.Count; i < n; i++)
+ typeReferences[i] = this.VisitTypeReference(typeReferences[i]);
+ return typeReferences;
+ }
+#if ExtendedRuntime
+ public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion){
+ return (TypeUnion)this.VisitTypeNode(typeUnion);
+ }
+#endif
+ public virtual Expression VisitUnaryExpression(UnaryExpression unaryExpression)
+ {
+ if (unaryExpression == null) return null;
+ unaryExpression.Operand = this.VisitExpression(unaryExpression.Operand);
+ return unaryExpression;
+ }
+#if !MinimalReader
+ public virtual Statement VisitVariableDeclaration(VariableDeclaration variableDeclaration)
+ {
+ if (variableDeclaration == null) return null;
+ variableDeclaration.Type = this.VisitTypeReference(variableDeclaration.Type);
+ variableDeclaration.Initializer = this.VisitExpression(variableDeclaration.Initializer);
+ return variableDeclaration;
+ }
+ public virtual UsedNamespace VisitUsedNamespace(UsedNamespace usedNamespace)
+ {
+ return usedNamespace;
+ }
+ public virtual UsedNamespaceList VisitUsedNamespaceList(UsedNamespaceList usedNspaces)
+ {
+ if (usedNspaces == null) return null;
+ for (int i = 0, n = usedNspaces.Count; i < n; i++)
+ usedNspaces[i] = this.VisitUsedNamespace(usedNspaces[i]);
+ return usedNspaces;
+ }
+ public virtual ExpressionList VisitLoopInvariantList(ExpressionList expressions)
+ {
+ if (expressions == null) return null;
+ for (int i = 0, n = expressions.Count; i < n; i++)
+ expressions[i] = this.VisitExpression(expressions[i]);
+ return expressions;
+ }
+ public virtual Statement VisitWhile(While While)
+ {
+ if (While == null) return null;
+ While.Condition = this.VisitExpression(While.Condition);
+ While.Invariants = this.VisitLoopInvariantList(While.Invariants);
+ While.Body = this.VisitBlock(While.Body);
+ return While;
+ }
+ public virtual Statement VisitYield(Yield Yield)
+ {
+ if (Yield == null) return null;
+ Yield.Expression = this.VisitExpression(Yield.Expression);
+ return Yield;
+ }
+#endif
+#if ExtendedRuntime
+ // query nodes
+ public virtual Node VisitQueryAggregate(QueryAggregate qa){
+ if (qa == null) return null;
+ qa.Expression = this.VisitExpression(qa.Expression);
+ return qa;
+ }
+ public virtual Node VisitQueryAlias(QueryAlias alias){
+ if (alias == null) return null;
+ alias.Expression = this.VisitExpression(alias.Expression);
+ return alias;
+ }
+ public virtual Node VisitQueryAxis(QueryAxis axis){
+ if (axis == null) return null;
+ axis.Source = this.VisitExpression( axis.Source );
+ return axis;
+ }
+ public virtual Node VisitQueryCommit(QueryCommit qc){
+ return qc;
+ }
+ public virtual Node VisitQueryContext(QueryContext context){
+ return context;
+ }
+ public virtual Node VisitQueryDelete(QueryDelete delete){
+ if (delete == null) return null;
+ delete.Source = this.VisitExpression(delete.Source);
+ /*delete.Target =*/ this.VisitExpression(delete.Target); //REVIEW: why should this not be updated?
+ return delete;
+ }
+ public virtual Node VisitQueryDifference(QueryDifference diff){
+ if (diff == null) return null;
+ diff.LeftSource = this.VisitExpression(diff.LeftSource);
+ diff.RightSource = this.VisitExpression(diff.RightSource);
+ return diff;
+ }
+ public virtual Node VisitQueryDistinct(QueryDistinct distinct){
+ if (distinct == null) return null;
+ distinct.Source = this.VisitExpression(distinct.Source);
+ return distinct;
+ }
+ public virtual Node VisitQueryExists(QueryExists exists){
+ if (exists == null) return null;
+ exists.Source = this.VisitExpression(exists.Source);
+ return exists;
+ }
+ public virtual Node VisitQueryFilter(QueryFilter filter){
+ if (filter == null) return null;
+ filter.Source = this.VisitExpression(filter.Source);
+ filter.Expression = this.VisitExpression(filter.Expression);
+ return filter;
+ }
+ public virtual Node VisitQueryGroupBy(QueryGroupBy groupby){
+ if (groupby == null) return null;
+ groupby.Source = this.VisitExpression(groupby.Source);
+ groupby.GroupList = this.VisitExpressionList(groupby.GroupList);
+ groupby.Having = this.VisitExpression(groupby.Having);
+ return groupby;
+ }
+ public virtual Statement VisitQueryGeneratedType(QueryGeneratedType qgt){
+ return qgt;
+ }
+ public virtual Node VisitQueryInsert(QueryInsert insert){
+ if (insert == null) return null;
+ insert.Location = this.VisitExpression(insert.Location);
+ insert.HintList = this.VisitExpressionList(insert.HintList);
+ insert.InsertList = this.VisitExpressionList(insert.InsertList);
+ return insert;
+ }
+ public virtual Node VisitQueryIntersection(QueryIntersection intersection){
+ if (intersection == null) return intersection;
+ intersection.LeftSource = this.VisitExpression(intersection.LeftSource);
+ intersection.RightSource = this.VisitExpression(intersection.RightSource);
+ intersection.Type = intersection.LeftSource == null ? null : intersection.LeftSource.Type;
+ return intersection;
+ }
+ public virtual Node VisitQueryIterator(QueryIterator xiterator){
+ if (xiterator == null) return xiterator;
+ xiterator.Expression = this.VisitExpression(xiterator.Expression);
+ xiterator.HintList = this.VisitExpressionList(xiterator.HintList);
+ return xiterator;
+ }
+ public virtual Node VisitQueryJoin(QueryJoin join){
+ if (join == null) return null;
+ join.LeftOperand = this.VisitExpression(join.LeftOperand);
+ join.RightOperand = this.VisitExpression(join.RightOperand);
+ join.JoinExpression = this.VisitExpression(join.JoinExpression);
+ return join;
+ }
+ public virtual Node VisitQueryLimit(QueryLimit limit){
+ if (limit == null) return null;
+ limit.Source = this.VisitExpression(limit.Source);
+ limit.Expression = this.VisitExpression(limit.Expression);
+ return limit;
+ }
+ public virtual Node VisitQueryOrderBy(QueryOrderBy orderby){
+ if (orderby == null) return null;
+ orderby.Source = this.VisitExpression(orderby.Source);
+ orderby.OrderList = this.VisitExpressionList(orderby.OrderList);
+ return orderby;
+ }
+ public virtual Node VisitQueryOrderItem(QueryOrderItem item){
+ if (item == null) return null;
+ item.Expression = this.VisitExpression(item.Expression);
+ return item;
+ }
+ public virtual Node VisitQueryPosition(QueryPosition position){
+ return position;
+ }
+ public virtual Node VisitQueryProject(QueryProject project){
+ if (project == null) return null;
+ project.Source = this.VisitExpression(project.Source);
+ project.ProjectionList = this.VisitExpressionList(project.ProjectionList);
+ return project;
+ }
+ public virtual Node VisitQueryRollback(QueryRollback qr){
+ return qr;
+ }
+ public virtual Node VisitQueryQuantifier(QueryQuantifier qq){
+ if (qq == null) return null;
+ qq.Expression = this.VisitExpression(qq.Expression);
+ return qq;
+ }
+ public virtual Node VisitQueryQuantifiedExpression(QueryQuantifiedExpression qqe){
+ if (qqe == null) return null;
+ qqe.Expression = this.VisitExpression(qqe.Expression);
+ return qqe;
+ }
+ public virtual Node VisitQuerySelect(QuerySelect select){
+ if (select == null) return null;
+ select.Source = this.VisitExpression(select.Source);
+ return select;
+ }
+ public virtual Node VisitQuerySingleton(QuerySingleton singleton){
+ if (singleton == null) return null;
+ singleton.Source = this.VisitExpression(singleton.Source);
+ return singleton;
+ }
+ public virtual Node VisitQueryTransact(QueryTransact qt){
+ if (qt == null) return null;
+ qt.Source = this.VisitExpression(qt.Source);
+ qt.Body = this.VisitBlock(qt.Body);
+ qt.CommitBody = this.VisitBlock(qt.CommitBody);
+ qt.RollbackBody = this.VisitBlock(qt.RollbackBody);
+ return qt;
+ }
+ public virtual Node VisitQueryTypeFilter(QueryTypeFilter filter){
+ if (filter == null) return null;
+ filter.Source = this.VisitExpression(filter.Source);
+ return filter;
+ }
+ public virtual Node VisitQueryUnion(QueryUnion union){
+ if (union == null) return null;
+ union.LeftSource = this.VisitExpression(union.LeftSource);
+ union.RightSource = this.VisitExpression(union.RightSource);
+ return union;
+ }
+ public virtual Node VisitQueryUpdate(QueryUpdate update){
+ if (update == null) return null;
+ update.Source = this.VisitExpression(update.Source);
+ update.UpdateList = this.VisitExpressionList(update.UpdateList);
+ return update;
+ }
+ public virtual Node VisitQueryYielder(QueryYielder yielder){
+ if (yielder == null) return null;
+ yielder.Source = this.VisitExpression(yielder.Source);
+ yielder.Target = this.VisitExpression(yielder.Target);
+ yielder.Body = this.VisitBlock(yielder.Body);
+ return yielder;
+ }
+#endif
+#if !MinimalReader
+ /// <summary>
+ /// Return a type viewer for the current scope.
+ /// [The type viewer acts like the identity function, except for dialects (e.g. Extensible Sing#)
+ /// that allow extensions and differing views of types.]
+ /// null can be returned to represent an identity-function type viewer.
+ /// </summary>
+ public virtual TypeViewer TypeViewer
+ {
+ get
+ {
+ return null;
+ }
+ }
+ /// <summary>
+ /// Return the current scope's view of the argument type, by asking the current scope's type viewer.
+ /// </summary>
+ public virtual TypeNode/*!*/ GetTypeView(TypeNode/*!*/ type)
+ {
+ return TypeViewer.GetTypeView(this.TypeViewer, type);
+ }
+#endif
+ }
+#if !MinimalReader
+ /// <summary>
+ /// Provides methods for invoking a parser to obtain AST nodes corresponding to various types of code snippets.
+ /// </summary>
+ public interface IParser
+ {
+ /// <summary>
+ /// Parses the parser's source document as an entire compilation unit and adds the resulting AST nodes to the
+ /// Nodes list of the given CompilationUnit instance.
+ /// </summary>
+ /// <param name="compilationUnit">The compilation unit whose Nodes list will receive the AST root node(s) that the parser produces.</param>
+ void ParseCompilationUnit(CompilationUnit compilationUnit);
+ Expression ParseExpression();
+ void ParseStatements(StatementList statements);
+ void ParseTypeMembers(TypeNode type);
+ }
+ ///<summary>Provides a way for general purpose code to construct parsers using an standard interface.
+ ///Useful for base classes without complete knowledge of all the different kinds of parsers that might be used in an application.</summary>
+ public interface IParserFactory
+ {
+ IParser CreateParser(string fileName, int lineNumber, DocumentText text, Module symbolTable, ErrorNodeList errorNodes, CompilerParameters options);
+ }
+ public class SnippetParser : StandardVisitor
+ {
+ public IParserFactory/*!*/ DefaultParserFactory;
+ public ErrorNodeList ErrorNodes;
+ public Module SymbolTable;
+ public StatementList CurrentStatementList;
+ public CompilerParameters Options;
+
+ public SnippetParser(IParserFactory/*!*/ defaultParserFactory, Module symbolTable, ErrorNodeList errorNodes, CompilerParameters options)
+ {
+ this.DefaultParserFactory = defaultParserFactory;
+ this.ErrorNodes = errorNodes;
+ this.SymbolTable = symbolTable;
+ this.Options = options;
+ this.CurrentStatementList = new StatementList(0);
+ //^ base();
+ }
+
+ public override Node VisitUnknownNodeType(Node node)
+ {
+ return node; //Do not look for snippets inside unknown node types
+ }
+ public override Block VisitBlock(Block block)
+ {
+ if (block == null) return null;
+ StatementList savedStatementList = this.CurrentStatementList;
+ try
+ {
+ StatementList oldStatements = block.Statements;
+ int n = oldStatements == null ? 0 : oldStatements.Count;
+ StatementList newStatements = this.CurrentStatementList = block.Statements = new StatementList(n);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert oldStatements != null;
+ newStatements.Add((Statement)this.Visit(oldStatements[i]));
+ }
+ return block;
+ }
+ finally
+ {
+ this.CurrentStatementList = savedStatementList;
+ }
+ }
+ public override CompilationUnit VisitCompilationUnitSnippet(CompilationUnitSnippet snippet)
+ {
+ if (snippet == null) return null;
+ Document doc = snippet.SourceContext.Document;
+ if (doc == null) return null;
+ string fileName = doc.Name;
+ int lineNumber = doc.LineNumber;
+ DocumentText sourceText = doc.Text;
+ IParserFactory pf = snippet.ParserFactory;
+ IParser p;
+ if (pf == null)
+ p = this.DefaultParserFactory.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ else
+ p = pf.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ if (p == null) return null;
+ p.ParseCompilationUnit(snippet);
+ return snippet;
+ }
+ public override Expression VisitExpressionSnippet(ExpressionSnippet snippet)
+ {
+ if (snippet == null) return null;
+ Document doc = snippet.SourceContext.Document;
+ if (doc == null) return null;
+ string fileName = doc.Name;
+ int lineNumber = doc.LineNumber;
+ DocumentText sourceText = doc.Text;
+ IParserFactory pf = snippet.ParserFactory;
+ IParser p;
+ if (pf == null)
+ p = this.DefaultParserFactory.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ else
+ p = pf.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ if (p == null) return null;
+ return p.ParseExpression();
+ }
+ public override StatementSnippet VisitStatementSnippet(StatementSnippet snippet)
+ {
+ if (snippet == null) return null;
+ Document doc = snippet.SourceContext.Document;
+ if (doc == null) return null;
+ string fileName = doc.Name;
+ int lineNumber = doc.LineNumber;
+ DocumentText sourceText = doc.Text;
+ IParserFactory pf = snippet.ParserFactory;
+ IParser p;
+ if (pf == null)
+ p = this.DefaultParserFactory.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ else
+ p = pf.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ if (p == null) return null;
+ p.ParseStatements(this.CurrentStatementList);
+ return null;
+ }
+ public override TypeMemberSnippet VisitTypeMemberSnippet(TypeMemberSnippet snippet)
+ {
+ if (snippet == null) return null;
+ Document doc = snippet.SourceContext.Document;
+ if (doc == null) return null;
+ string fileName = doc.Name;
+ int lineNumber = doc.LineNumber;
+ DocumentText sourceText = doc.Text;
+ IParserFactory pf = snippet.ParserFactory;
+ IParser p;
+ if (pf == null)
+ p = this.DefaultParserFactory.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ else
+ p = pf.CreateParser(fileName, lineNumber, sourceText, this.SymbolTable, this.ErrorNodes, this.Options);
+ if (p == null) return null;
+ p.ParseTypeMembers(snippet.DeclaringType);
+ return null;
+ }
+ }
+#endif
+}
diff --git a/tools/Sandcastle/Source/CCI/SystemTypes.cs b/tools/Sandcastle/Source/CCI/SystemTypes.cs
new file mode 100644
index 0000000..d5b8246
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/SystemTypes.cs
@@ -0,0 +1,2154 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+#if FxCop
+using InterfaceList = Microsoft.Cci.InterfaceCollection;
+using TypeNodeList = Microsoft.Cci.TypeNodeCollection;
+using Module = Microsoft.Cci.ModuleNode;
+using Class = Microsoft.Cci.ClassNode;
+using Interface = Microsoft.Cci.InterfaceNode;
+#endif
+#if CCINamespace
+using Microsoft.Cci.Metadata;
+#else
+using System.Compiler.Metadata;
+#endif
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !FxCop
+ public
+#endif
+ sealed class SystemAssemblyLocation
+ {
+ static string location;
+ public static string Location
+ {
+ get
+ {
+ return location;
+ }
+ set
+ {
+ //Debug.Assert(location == null || location == value, string.Format("You attempted to set the mscorlib.dll location to\r\n\r\n{0}\r\n\r\nbut it was already set to\r\n\r\n{1}\r\n\r\nThis may occur if you have multiple projects that target different platforms. Make sure all of your projects target the same platform.\r\n\r\nYou may try to continue, but targeting multiple platforms during the same session is not supported, so you may see erroneous behavior.", value, location));
+ location = value;
+ }
+ }
+ public static AssemblyNode ParsedAssembly;
+ }
+#if ExtendedRuntime
+ public sealed class SystemCompilerRuntimeAssemblyLocation{
+ public static string Location {
+ get { return location; }
+ set {
+ location = value;
+ Identifier id = Identifier.For("System.Compiler.Runtime");
+ AssemblyReference aref = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[id.UniqueIdKey];
+ if (aref == null) {
+ aref = new AssemblyReference(typeof(ComposerAttribute).Assembly.FullName);
+ TargetPlatform.AssemblyReferenceFor[id.UniqueIdKey] = aref;
+ }
+ aref.Location = value;
+ }
+ }
+ private static string location = null; //Can be set by compiler in cross compilation scenarios
+ public static AssemblyNode ParsedAssembly;
+ }
+#endif
+#if !NoData && !ROTOR
+ public sealed class SystemDataAssemblyLocation
+ {
+ public static string Location = null;
+ }
+#endif
+#if !NoXml && !NoRuntimeXml
+ public sealed class SystemXmlAssemblyLocation
+ {
+ public static string Location = null;
+ }
+#endif
+#if !FxCop
+ public
+#endif
+ sealed class TargetPlatform
+ {
+ private TargetPlatform() { }
+ public static bool DoNotLockFiles;
+ public static bool GetDebugInfo;
+ public static char GenericTypeNamesMangleChar = '_';
+
+ public static bool UseGenerics
+ {
+ get
+ {
+ Version v = TargetPlatform.TargetVersion;
+ if (v == null)
+ {
+ v = CoreSystemTypes.SystemAssembly.Version;
+ if (v == null)
+ v = typeof(object).Assembly.GetName().Version;
+ }
+ return v.Major > 1 || v.Minor > 2 || v.Minor == 2 && v.Build >= 3300;
+ }
+ }
+
+ public static void Clear()
+ {
+ SystemAssemblyLocation.Location = null;
+#if ExtendedRuntime
+ SystemCompilerRuntimeAssemblyLocation.Location = null;
+#endif
+#if !NoData && !ROTOR
+ SystemDataAssemblyLocation.Location = null;
+#endif
+#if !NoXml && !NoRuntimeXml
+ SystemXmlAssemblyLocation.Location = null;
+#endif
+ TargetPlatform.DoNotLockFiles = false;
+ TargetPlatform.GetDebugInfo = false;
+ TargetPlatform.PlatformAssembliesLocation = "";
+ SystemTypes.Clear();
+ }
+ public static System.Collections.IDictionary StaticAssemblyCache
+ {
+ get { return Reader.StaticAssemblyCache; }
+ }
+ public static Version TargetVersion =
+#if WHIDBEY
+ new Version(2, 0, 50727); // Default for a WHIDBEY compiler
+#else
+ new Version(1, 0, 5000); // Default for an Everett compiler
+#endif
+ public static string TargetRuntimeVersion;
+
+ public static int LinkerMajorVersion
+ {
+ get
+ {
+ switch (TargetVersion.Major)
+ {
+ case 2: return 8;
+ case 1: return 7;
+ default: return 6;
+ }
+ }
+ }
+ public static int LinkerMinorVersion
+ {
+ get
+ {
+ return TargetVersion.Minor;
+ }
+ }
+
+ public static int MajorVersion { get { return TargetVersion.Major; } }
+ public static int MinorVersion { get { return TargetVersion.Minor; } }
+ public static int Build { get { return TargetVersion.Build; } }
+
+ public static string/*!*/ PlatformAssembliesLocation = String.Empty;
+ private static TrivialHashtable assemblyReferenceFor;
+ public static TrivialHashtable/*!*/ AssemblyReferenceFor
+ {
+ get
+ {
+ if (TargetPlatform.assemblyReferenceFor == null)
+ TargetPlatform.SetupAssemblyReferenceFor();
+ //^ assume TargetPlatform.assemblyReferenceFor != null;
+ return TargetPlatform.assemblyReferenceFor;
+ }
+ set
+ {
+ TargetPlatform.assemblyReferenceFor = value;
+ }
+ }
+#if !FxCop
+ private readonly static string[]/*!*/ FxAssemblyNames =
+ new string[]{"Accessibility", "CustomMarshalers", "IEExecRemote", "IEHost", "IIEHost", "ISymWrapper",
+ "Microsoft.JScript", "Microsoft.VisualBasic", "Microsoft.VisualBasic.Vsa", "Microsoft.VisualC",
+ "Microsoft.Vsa", "Microsoft.Vsa.Vb.CodeDOMProcessor", "mscorcfg", "Regcode", "System",
+ "System.Configuration.Install", "System.Data", "System.Design", "System.DirectoryServices",
+ "System.Drawing", "System.Drawing.Design", "System.EnterpriseServices",
+ "System.Management", "System.Messaging", "System.Runtime.Remoting", "System.Runtime.Serialization.Formatters.Soap",
+ "System.Security", "System.ServiceProcess", "System.Web", "System.Web.Mobile", "System.Web.RegularExpressions",
+ "System.Web.Services", "System.Windows.Forms", "System.Xml", "TlbExpCode", "TlbImpCode", "cscompmgd",
+ "vjswfchtml", "vjswfccw", "VJSWfcBrowserStubLib", "vjswfc", "vjslibcw", "vjslib", "vjscor", "VJSharpCodeProvider"};
+ private readonly static string[]/*!*/ FxAssemblyToken =
+ new string[]{"b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b77a5c561934e089",
+ "b03f5f7f11d50a3a", "b77a5c561934e089", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b77a5c561934e089", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b77a5c561934e089", "b77a5c561934e089", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a",
+ "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a", "b03f5f7f11d50a3a"};
+ private readonly static string[]/*!*/ FxAssemblyVersion1 =
+ new string[]{"1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "7.0.3300.0", "7.0.3300.0", "7.0.3300.0", "7.0.3300.0",
+ "7.0.3300.0", "7.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "7.0.3300.0",
+ "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "1.0.3300.0", "7.0.3300.0"};
+ private readonly static string[]/*!*/ FxAssemblyVersion1_1 =
+ new string[]{"1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "7.0.5000.0", "7.0.5000.0", "7.0.5000.0", "7.0.5000.0",
+ "7.0.5000.0", "7.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "7.0.5000.0",
+ "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "1.0.5000.0", "7.0.5000.0"};
+ private static string[]/*!*/ FxAssemblyVersion2Build3600 =
+ new string[]{"2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "8.0.1200.0", "8.0.1200.0", "8.0.1200.0", "8.0.1200.0",
+ "8.0.1200.0", "8.0.1200.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "8.0.1200.0",
+ "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "2.0.3600.0", "7.0.5000.0"};
+ private static string[]/*!*/ FxAssemblyVersion2 =
+ new string[]{"2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "8.0.0.0", "8.0.0.0", "8.0.0.0", "8.0.0.0",
+ "8.0.0.0", "8.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "8.0.0.0",
+ "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0", "2.0.0.0"};
+#endif
+ private static void SetupAssemblyReferenceFor()
+ {
+#if FxCop
+ TargetPlatform.SetToPostV1_1(Path.GetDirectoryName(typeof(object).Module.Assembly.Location));
+#else
+ Version version = TargetPlatform.TargetVersion;
+ if (version == null) version = typeof(object).Module.Assembly.GetName().Version;
+ TargetPlatform.SetTo(version);
+#endif
+ }
+#if !FxCop
+ public static void SetTo(Version/*!*/ version)
+ {
+ if (version == null) throw new ArgumentNullException();
+ if (version.Major == 1)
+ {
+ if (version.Minor == 0 && version.Build == 3300) TargetPlatform.SetToV1();
+ else if (version.Minor == 0 && version.Build == 5000) TargetPlatform.SetToV1_1();
+ else if (version.Minor == 1 && version.Build == 9999) TargetPlatform.SetToPostV1_1(TargetPlatform.PlatformAssembliesLocation);
+ }
+ else if (version.Major == 2)
+ {
+ if (version.Minor == 0 && version.Build == 3600) TargetPlatform.SetToV2Beta1();
+ else TargetPlatform.SetToV2();
+ }
+ else
+ TargetPlatform.SetToV1();
+ }
+ public static void SetTo(Version/*!*/ version, string/*!*/ platformAssembliesLocation)
+ {
+ if (version == null || platformAssembliesLocation == null) throw new ArgumentNullException();
+ if (version.Major == 1)
+ {
+ if (version.Minor == 0 && version.Build == 3300) TargetPlatform.SetToV1(platformAssembliesLocation);
+ else if (version.Minor == 0 && version.Build == 5000) TargetPlatform.SetToV1_1(platformAssembliesLocation);
+ else if (version.Minor == 1 && version.Build == 9999) TargetPlatform.SetToPostV1_1(platformAssembliesLocation);
+ }
+ else if (version.Major == 2)
+ {
+ if (version.Minor == 0 && version.Build == 3600) TargetPlatform.SetToV2Beta1(platformAssembliesLocation);
+ else TargetPlatform.SetToV2(platformAssembliesLocation);
+ }
+ else
+ TargetPlatform.SetToV1(platformAssembliesLocation);
+ }
+ public static void SetToV1()
+ {
+ TargetPlatform.SetToV1(TargetPlatform.PlatformAssembliesLocation);
+ }
+ public static void SetToV1(string platformAssembliesLocation)
+ {
+ TargetPlatform.TargetVersion = new Version(1, 0, 3300);
+ TargetPlatform.TargetRuntimeVersion = "v1.0.3705";
+ if (platformAssembliesLocation == null || platformAssembliesLocation.Length == 0)
+ platformAssembliesLocation = TargetPlatform.PlatformAssembliesLocation = Path.Combine(Path.GetDirectoryName(typeof(object).Module.Assembly.Location), "..\\v1.0.3705");
+ else
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.InitializeStandardAssemblyLocationsWithDefaultValues(platformAssembliesLocation);
+ TrivialHashtable assemblyReferenceFor = new TrivialHashtable(46);
+ for (int i = 0, n = TargetPlatform.FxAssemblyNames.Length; i < n; i++)
+ {
+ string name = TargetPlatform.FxAssemblyNames[i];
+ string version = TargetPlatform.FxAssemblyVersion1[i];
+ string token = TargetPlatform.FxAssemblyToken[i];
+ AssemblyReference aref = new AssemblyReference(name + ", Version=" + version + ", Culture=neutral, PublicKeyToken=" + token);
+ aref.Location = platformAssembliesLocation + "\\" + name + ".dll";
+ //^ assume name != null;
+ assemblyReferenceFor[Identifier.For(name).UniqueIdKey] = aref;
+ }
+ TargetPlatform.assemblyReferenceFor = assemblyReferenceFor;
+#if ExtendedRuntime
+ SystemCompilerRuntimeAssemblyLocation.Location = SystemCompilerRuntimeAssemblyLocation.Location;
+#endif
+ }
+ public static void SetToV1_1()
+ {
+ TargetPlatform.SetToV1_1(TargetPlatform.PlatformAssembliesLocation);
+ }
+ public static void SetToV1_1(string/*!*/ platformAssembliesLocation)
+ {
+ TargetPlatform.TargetVersion = new Version(1, 0, 5000);
+ TargetPlatform.TargetRuntimeVersion = "v1.1.4322";
+ if (platformAssembliesLocation == null || platformAssembliesLocation.Length == 0)
+ platformAssembliesLocation = TargetPlatform.PlatformAssembliesLocation = Path.Combine(Path.GetDirectoryName(typeof(object).Module.Assembly.Location), "..\\v1.1.4322");
+ else
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.InitializeStandardAssemblyLocationsWithDefaultValues(platformAssembliesLocation);
+ TrivialHashtable assemblyReferenceFor = new TrivialHashtable(46);
+ for (int i = 0, n = TargetPlatform.FxAssemblyNames.Length; i < n; i++)
+ {
+ string name = TargetPlatform.FxAssemblyNames[i];
+ string version = TargetPlatform.FxAssemblyVersion1_1[i];
+ string token = TargetPlatform.FxAssemblyToken[i];
+ AssemblyReference aref = new AssemblyReference(name + ", Version=" + version + ", Culture=neutral, PublicKeyToken=" + token);
+ aref.Location = platformAssembliesLocation + "\\" + name + ".dll";
+ //^ assume name != null;
+ assemblyReferenceFor[Identifier.For(name).UniqueIdKey] = aref;
+ }
+ TargetPlatform.assemblyReferenceFor = assemblyReferenceFor;
+ }
+ public static void SetToV2()
+ {
+ TargetPlatform.SetToV2(TargetPlatform.PlatformAssembliesLocation);
+ }
+ public static void SetToV2(string platformAssembliesLocation)
+ {
+ TargetPlatform.TargetVersion = new Version(2, 0, 50727);
+ TargetPlatform.TargetRuntimeVersion = "v2.0.50727";
+ TargetPlatform.GenericTypeNamesMangleChar = '`';
+ if (platformAssembliesLocation == null || platformAssembliesLocation.Length == 0)
+ platformAssembliesLocation = TargetPlatform.PlatformAssembliesLocation = Path.Combine(Path.GetDirectoryName(typeof(object).Module.Assembly.Location), "..\\v2.0.50727");
+ else
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.InitializeStandardAssemblyLocationsWithDefaultValues(platformAssembliesLocation);
+ TrivialHashtable assemblyReferenceFor = new TrivialHashtable(46);
+ for (int i = 0, n = TargetPlatform.FxAssemblyNames.Length; i < n; i++)
+ {
+ string name = TargetPlatform.FxAssemblyNames[i];
+ string version = TargetPlatform.FxAssemblyVersion2[i];
+ string token = TargetPlatform.FxAssemblyToken[i];
+ AssemblyReference aref = new AssemblyReference(name + ", Version=" + version + ", Culture=neutral, PublicKeyToken=" + token);
+ aref.Location = platformAssembliesLocation + "\\" + name + ".dll";
+ //^ assume name != null;
+ assemblyReferenceFor[Identifier.For(name).UniqueIdKey] = aref;
+ }
+ TargetPlatform.assemblyReferenceFor = assemblyReferenceFor;
+#if ExtendedRuntime
+ SystemCompilerRuntimeAssemblyLocation.Location = SystemCompilerRuntimeAssemblyLocation.Location;
+#endif
+ }
+ public static void SetToV2Beta1()
+ {
+ TargetPlatform.SetToV2Beta1(TargetPlatform.PlatformAssembliesLocation);
+ }
+ public static void SetToV2Beta1(string/*!*/ platformAssembliesLocation)
+ {
+ TargetPlatform.TargetVersion = new Version(2, 0, 3600);
+ TargetPlatform.GenericTypeNamesMangleChar = '!';
+ string dotNetDirLocation = null;
+ if (platformAssembliesLocation == null || platformAssembliesLocation.Length == 0)
+ {
+ DirectoryInfo dotNetDir = new FileInfo(new Uri(typeof(object).Module.Assembly.Location).LocalPath).Directory.Parent;
+ dotNetDirLocation = dotNetDir.FullName;
+ if (dotNetDirLocation != null) dotNetDirLocation = dotNetDirLocation.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
+ DateTime creationTime = DateTime.MinValue;
+ foreach (DirectoryInfo subdir in dotNetDir.GetDirectories("v2.0*"))
+ {
+ if (subdir == null) continue;
+ if (subdir.CreationTime < creationTime) continue;
+ FileInfo[] mscorlibs = subdir.GetFiles("mscorlib.dll");
+ if (mscorlibs != null && mscorlibs.Length == 1)
+ {
+ platformAssembliesLocation = subdir.FullName;
+ creationTime = subdir.CreationTime;
+ }
+ }
+ }
+ else
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ if (dotNetDirLocation != null && (platformAssembliesLocation == null || platformAssembliesLocation.Length == 0))
+ {
+ int pos = dotNetDirLocation.IndexOf("FRAMEWORK");
+ if (pos > 0 && dotNetDirLocation.IndexOf("FRAMEWORK64") < 0)
+ {
+ dotNetDirLocation = dotNetDirLocation.Replace("FRAMEWORK", "FRAMEWORK64");
+ if (Directory.Exists(dotNetDirLocation))
+ {
+ DirectoryInfo dotNetDir = new DirectoryInfo(dotNetDirLocation);
+ DateTime creationTime = DateTime.MinValue;
+ foreach (DirectoryInfo subdir in dotNetDir.GetDirectories("v2.0*"))
+ {
+ if (subdir == null) continue;
+ if (subdir.CreationTime < creationTime) continue;
+ FileInfo[] mscorlibs = subdir.GetFiles("mscorlib.dll");
+ if (mscorlibs != null && mscorlibs.Length == 1)
+ {
+ platformAssembliesLocation = subdir.FullName;
+ creationTime = subdir.CreationTime;
+ }
+ }
+ }
+ }
+ }
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.InitializeStandardAssemblyLocationsWithDefaultValues(platformAssembliesLocation);
+ TrivialHashtable assemblyReferenceFor = new TrivialHashtable(46);
+ for (int i = 0, n = TargetPlatform.FxAssemblyNames.Length; i < n; i++)
+ {
+ string name = TargetPlatform.FxAssemblyNames[i];
+ string version = TargetPlatform.FxAssemblyVersion2Build3600[i];
+ string token = TargetPlatform.FxAssemblyToken[i];
+ AssemblyReference aref = new AssemblyReference(name + ", Version=" + version + ", Culture=neutral, PublicKeyToken=" + token);
+ aref.Location = platformAssembliesLocation + "\\" + name + ".dll";
+ //^ assume name != null;
+ assemblyReferenceFor[Identifier.For(name).UniqueIdKey] = aref;
+ }
+ TargetPlatform.assemblyReferenceFor = assemblyReferenceFor;
+#if ExtendedRuntime
+ SystemCompilerRuntimeAssemblyLocation.Location = SystemCompilerRuntimeAssemblyLocation.Location;
+#endif
+ }
+#endif
+ /// <summary>
+ /// Use this to set the target platform to a platform with a superset of the platform assemblies in version 1.1, but
+ /// where the public key tokens and versions numbers are determined by reading in the actual assemblies from
+ /// the supplied location. Only assemblies recognized as platform assemblies in version 1.1 will be unified.
+ /// </summary>
+ public static void SetToPostV1_1(string/*!*/ platformAssembliesLocation)
+ {
+ TargetPlatform.PlatformAssembliesLocation = platformAssembliesLocation;
+ TargetPlatform.TargetVersion = new Version(1, 1, 9999);
+ TargetPlatform.TargetRuntimeVersion = "v1.1.9999";
+ TargetPlatform.InitializeStandardAssemblyLocationsWithDefaultValues(platformAssembliesLocation);
+#if FxCop
+ TargetPlatform.assemblyReferenceFor = new TrivialHashtable(0);
+#else
+ TargetPlatform.assemblyReferenceFor = new TrivialHashtable(46);
+ string[] dlls = Directory.GetFiles(platformAssembliesLocation, "*.dll");
+ foreach (string dll in dlls)
+ {
+ if (dll == null) continue;
+ string assemName = Path.GetFileNameWithoutExtension(dll);
+ int i = Array.IndexOf(TargetPlatform.FxAssemblyNames, assemName);
+ if (i < 0) continue;
+ AssemblyNode assem = AssemblyNode.GetAssembly(Path.Combine(platformAssembliesLocation, dll));
+ if (assem == null) continue;
+ TargetPlatform.assemblyReferenceFor[Identifier.For(assem.Name).UniqueIdKey] = new AssemblyReference(assem);
+ }
+#endif
+#if ExtendedRuntime
+ SystemCompilerRuntimeAssemblyLocation.Location = SystemCompilerRuntimeAssemblyLocation.Location;
+#endif
+ }
+ private static void InitializeStandardAssemblyLocationsWithDefaultValues(string platformAssembliesLocation)
+ {
+ SystemAssemblyLocation.Location = platformAssembliesLocation + "\\mscorlib.dll";
+#if ExtendedRuntime
+ if (SystemCompilerRuntimeAssemblyLocation.Location == null)
+#if CCINamespace
+ SystemCompilerRuntimeAssemblyLocation.Location = platformAssembliesLocation+"\\Microsoft.Cci.Runtime.dll";
+#else
+ SystemCompilerRuntimeAssemblyLocation.Location = platformAssembliesLocation+"\\system.compiler.runtime.dll";
+#endif
+ // If the System.Compiler.Runtime assembly does not exist at this location, DO NOTHING (don't load another one)
+ // as this signals the fact that the types may need to be loaded from the SystemAssembly instead.
+#endif
+#if !NoData && !ROTOR
+ if (SystemDataAssemblyLocation.Location == null)
+ SystemDataAssemblyLocation.Location = platformAssembliesLocation + "\\system.data.dll";
+#endif
+#if !NoXml && !NoRuntimeXml
+ if (SystemXmlAssemblyLocation.Location == null)
+ SystemXmlAssemblyLocation.Location = platformAssembliesLocation + "\\system.xml.dll";
+#endif
+ }
+ }
+#if ExtendedRuntime
+ public sealed class ExtendedRuntimeTypes{ //TODO: move all types from System.Compiler.Runtime into here.
+ public static AssemblyNode/*!*/ SystemCompilerRuntimeAssembly;
+
+ public static Interface/*!*/ ConstrainedType;
+ public static Interface/*!*/ ITemplateParameter;
+ public static Class/*!*/ NullableType;
+ public static Class/*!*/ NonNullType;
+ public static Class/*!*/ NotNullAttribute;
+ public static Class/*!*/ NotNullGenericArgumentsAttribute;
+ public static Class/*!*/ DelayedAttribute;
+ public static Class/*!*/ NotDelayedAttribute;
+ public static Class/*!*/ EncodedTypeSpecAttribute;
+ public static Class/*!*/ StrictReadonlyAttribute;
+ public static Interface/*!*/ TupleType;
+ public static Interface/*!*/ TypeAlias;
+ public static Interface/*!*/ TypeDefinition;
+ public static Interface/*!*/ TypeIntersection;
+ public static Interface/*!*/ TypeUnion;
+
+ public static Method nonNullTypeAssertInitialized;
+ public static Method NonNullTypeAssertInitialized {
+ get {
+ if (nonNullTypeAssertInitialized == null) {
+ if (NonNullType != null) {
+ nonNullTypeAssertInitialized = NonNullType.GetMethod(Identifier.For("AssertInitialized"), SystemTypes.Object);
+ }
+ }
+ return nonNullTypeAssertInitialized;
+ }
+ }
+
+ public static Method nonNullTypeAssertInitializedGeneric;
+ public static Method NonNullTypeAssertInitializedGeneric {
+ get {
+ if (nonNullTypeAssertInitializedGeneric != null) {
+ return nonNullTypeAssertInitializedGeneric;
+ }
+
+ if (NonNullType != null) {
+ MemberList ml = NonNullType.GetMembersNamed(Identifier.For("AssertInitialized"));
+ if (ml != null && ml.Count > 0) {
+ foreach (Member mem in ml) {
+ Method m = mem as Method;
+ if (m == null) continue;
+ if (m.IsGeneric) {
+ nonNullTypeAssertInitializedGeneric = m;
+ break;
+ }
+ }
+ }
+ }
+
+ return nonNullTypeAssertInitializedGeneric;
+ }
+ }
+ static ExtendedRuntimeTypes(){
+ ExtendedRuntimeTypes.Initialize(TargetPlatform.DoNotLockFiles, TargetPlatform.GetDebugInfo);
+ }
+
+ public static void Initialize(bool doNotLockFile, bool getDebugInfo) {
+ SystemCompilerRuntimeAssembly = ExtendedRuntimeTypes.GetSystemCompilerRuntimeAssembly(doNotLockFile, getDebugInfo);
+ if (SystemCompilerRuntimeAssembly == null) throw new InvalidOperationException(ExceptionStrings.InternalCompilerError);
+#if CCINamespace
+ const string CciNs = "Microsoft.Cci";
+ const string ContractsNs = "Microsoft.Contracts";
+ //const string CompilerGuardsNs = "Microsoft.Contracts";
+#else
+ const string CciNs = "System.Compiler";
+ const string ContractsNs = "Microsoft.Contracts";
+ //const string CompilerGuardsNs = "Microsoft.Contracts";
+#endif
+ ConstrainedType = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "IConstrainedType", ElementType.Class);
+ ITemplateParameter = (Interface)GetCompilerRuntimeTypeNodeFor(CciNs, "ITemplateParameter", ElementType.Class);
+ NullableType = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NullableType", ElementType.Class);
+ NonNullType = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NonNullType", ElementType.Class);
+ NotNullAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NotNullAttribute", ElementType.Class);
+ NotNullGenericArgumentsAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NotNullGenericArgumentsAttribute", ElementType.Class);
+ DelayedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "DelayedAttribute", ElementType.Class);
+ NotDelayedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NotDelayedAttribute", ElementType.Class);
+ EncodedTypeSpecAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "EncodedTypeSpecAttribute", ElementType.Class);
+ StrictReadonlyAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "StrictReadonlyAttribute", ElementType.Class);
+ TupleType = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ITupleType", ElementType.Class);
+ TypeAlias = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ITypeAlias", ElementType.Class);
+ TypeDefinition = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ITypeDefinition", ElementType.Class);
+ TypeIntersection = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ITypeIntersection", ElementType.Class);
+ TypeUnion = (Interface)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ITypeUnion", ElementType.Class);
+ }
+
+ public static void Clear(){
+ lock (Module.GlobalLock){
+ if (ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly != AssemblyNode.Dummy && ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly != null) {
+ ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly.Dispose();
+ ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly = null;
+ }
+ ConstrainedType = null;
+ ITemplateParameter = null;
+ NullableType = null;
+ NonNullType = null;
+ NotNullAttribute = null;
+ NotNullGenericArgumentsAttribute = null;
+ DelayedAttribute = null;
+ NotDelayedAttribute = null;
+ EncodedTypeSpecAttribute = null;
+ StrictReadonlyAttribute = null;
+ TupleType = null;
+ TypeAlias = null;
+ TypeDefinition = null;
+ TypeIntersection = null;
+ TypeUnion = null;
+ nonNullTypeAssertInitialized = null;
+ nonNullTypeAssertInitializedGeneric = null;
+ }
+ }
+ private static AssemblyNode/*!*/ GetSystemCompilerRuntimeAssembly(bool doNotLockFile, bool getDebugInfo) {
+ if (SystemCompilerRuntimeAssemblyLocation.ParsedAssembly != null)
+ return SystemCompilerRuntimeAssemblyLocation.ParsedAssembly;
+ if (SystemCompilerRuntimeAssemblyLocation.Location == null || SystemCompilerRuntimeAssemblyLocation.Location.Length == 0)
+ SystemCompilerRuntimeAssemblyLocation.Location = typeof(ComposerAttribute).Module.Assembly.Location;
+ AssemblyNode result = (AssemblyNode)(new Reader(SystemCompilerRuntimeAssemblyLocation.Location, null, doNotLockFile, getDebugInfo, true, false)).ReadModule();
+ if (result == null) {
+ if (CoreSystemTypes.SystemAssembly.GetType(Identifier.For("Microsoft.Contracts"), Identifier.For("NonNullType")) != null) {
+ result = SystemTypes.SystemAssembly;
+ } else {
+ SystemCompilerRuntimeAssemblyLocation.Location = typeof(ComposerAttribute).Module.Assembly.Location;
+ result = (AssemblyNode)(new Reader(SystemCompilerRuntimeAssemblyLocation.Location, null, doNotLockFile, getDebugInfo, true, false)).ReadModule();
+ }
+ }
+ if (result == null) {
+ result = new AssemblyNode();
+ System.Reflection.AssemblyName aname = typeof(ComposerAttribute).Module.Assembly.GetName();
+ result.Name = aname.Name;
+ result.Version = aname.Version;
+ result.PublicKeyOrToken = aname.GetPublicKeyToken();
+ }
+ TargetPlatform.AssemblyReferenceFor[Identifier.For(result.Name).UniqueIdKey] = new AssemblyReference(result);
+ return result;
+ }
+ private static TypeNode/*!*/ GetCompilerRuntimeTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode) {
+ return ExtendedRuntimeTypes.GetCompilerRuntimeTypeNodeFor(nspace, name, 0, typeCode);
+ }
+ private static TypeNode/*!*/ GetCompilerRuntimeTypeNodeFor(string/*!*/ nspace, string/*!*/ name, int numParams, ElementType typeCode) {
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0 && numParams > 0)
+ name = name + TargetPlatform.GenericTypeNamesMangleChar + numParams;
+ TypeNode result = null;
+ if (SystemCompilerRuntimeAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemCompilerRuntimeAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemCompilerRuntimeAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+ }
+#endif
+#if !FxCop
+ public
+#endif
+ sealed class CoreSystemTypes
+ {
+ private CoreSystemTypes() { }
+ internal static bool Initialized;
+
+ internal static bool IsInitialized { get { return Initialized; } }
+ //system assembly (the basic runtime)
+ public static AssemblyNode/*!*/ SystemAssembly;
+
+ //Special base types
+ public static Class/*!*/ Object;
+ public static Class/*!*/ String;
+ public static Class/*!*/ ValueType;
+ public static Class/*!*/ Enum;
+ public static Class/*!*/ MulticastDelegate;
+ public static Class/*!*/ Array;
+ public static Class/*!*/ Type;
+#if !FxCop
+ public static Class/*!*/ Delegate;
+ public static Class/*!*/ Exception;
+ public static Class/*!*/ Attribute;
+#endif
+ //primitive types
+ public static Struct/*!*/ Boolean;
+ public static Struct/*!*/ Char;
+ public static Struct/*!*/ Int8;
+ public static Struct/*!*/ UInt8;
+ public static Struct/*!*/ Int16;
+ public static Struct/*!*/ UInt16;
+ public static Struct/*!*/ Int32;
+ public static Struct/*!*/ UInt32;
+ public static Struct/*!*/ Int64;
+ public static Struct/*!*/ UInt64;
+ public static Struct/*!*/ Single;
+ public static Struct/*!*/ Double;
+ public static Struct/*!*/ IntPtr;
+ public static Struct/*!*/ UIntPtr;
+ public static Struct/*!*/ DynamicallyTypedReference;
+
+#if !MinimalReader
+ //Classes need for System.TypeCode
+ public static Class/*!*/ DBNull;
+ public static Struct/*!*/ DateTime;
+ public static Struct/*!*/ Decimal;
+#endif
+
+ //Special types
+ public static Class/*!*/ IsVolatile;
+ public static Struct/*!*/ Void;
+ public static Struct/*!*/ ArgIterator;
+ public static Struct/*!*/ RuntimeFieldHandle;
+ public static Struct/*!*/ RuntimeMethodHandle;
+ public static Struct/*!*/ RuntimeTypeHandle;
+#if !MinimalReader
+ public static Struct/*!*/ RuntimeArgumentHandle;
+#endif
+ //Special attributes
+ public static EnumNode SecurityAction;
+
+ static CoreSystemTypes()
+ {
+ CoreSystemTypes.Initialize(TargetPlatform.DoNotLockFiles, TargetPlatform.GetDebugInfo);
+ }
+
+ public static void Clear()
+ {
+ lock (Module.GlobalLock)
+ {
+ if (Reader.StaticAssemblyCache != null)
+ {
+ foreach (AssemblyNode cachedAssembly in new System.Collections.ArrayList(Reader.StaticAssemblyCache.Values))
+ {
+ if (cachedAssembly != null) cachedAssembly.Dispose();
+ }
+ Reader.StaticAssemblyCache.Clear();
+ }
+ //Dispose the system assemblies in case they were not in the static cache. It is safe to dispose an assembly more than once.
+ if (CoreSystemTypes.SystemAssembly != null && CoreSystemTypes.SystemAssembly != AssemblyNode.Dummy)
+ {
+ CoreSystemTypes.SystemAssembly.Dispose();
+ CoreSystemTypes.SystemAssembly = null;
+ }
+ CoreSystemTypes.ClearStatics();
+ CoreSystemTypes.Initialized = false;
+ TargetPlatform.AssemblyReferenceFor = new TrivialHashtable(0);
+ }
+ }
+ public static void Initialize(bool doNotLockFile, bool getDebugInfo)
+ {
+ if (CoreSystemTypes.Initialized) CoreSystemTypes.Clear();
+ if (SystemAssembly == null)
+ SystemAssembly = CoreSystemTypes.GetSystemAssembly(doNotLockFile, getDebugInfo);
+ if (SystemAssembly == null) throw new InvalidOperationException(ExceptionStrings.InternalCompilerError);
+ if (TargetPlatform.TargetVersion == null)
+ {
+ TargetPlatform.TargetVersion = SystemAssembly.Version;
+ if (TargetPlatform.TargetVersion == null)
+ TargetPlatform.TargetVersion = typeof(object).Module.Assembly.GetName().Version;
+ }
+ if (TargetPlatform.TargetVersion != null)
+ {
+ if (TargetPlatform.TargetVersion.Major > 1 || TargetPlatform.TargetVersion.Minor > 1 ||
+ (TargetPlatform.TargetVersion.Minor == 1 && TargetPlatform.TargetVersion.Build == 9999))
+ {
+ if (SystemAssembly.IsValidTypeName(StandardIds.System, Identifier.For("Nullable`1")))
+ TargetPlatform.GenericTypeNamesMangleChar = '`';
+ else if (SystemAssembly.IsValidTypeName(StandardIds.System, Identifier.For("Nullable!1")))
+ TargetPlatform.GenericTypeNamesMangleChar = '!';
+ else if (TargetPlatform.TargetVersion.Major == 1 && TargetPlatform.TargetVersion.Minor == 2)
+ TargetPlatform.GenericTypeNamesMangleChar = (char)0;
+ }
+ }
+ // This must be done in the order: Object, ValueType, Char, String
+ // or else some of the generic type instantiations don't get filled
+ // in correctly. (String ends up implementing IEnumerable<string>
+ // instead of IEnumerable<char>.)
+ Object = (Class)GetTypeNodeFor("System", "Object", ElementType.Object);
+ ValueType = (Class)GetTypeNodeFor("System", "ValueType", ElementType.Class);
+ Char = (Struct)GetTypeNodeFor("System", "Char", ElementType.Char);
+ String = (Class)GetTypeNodeFor("System", "String", ElementType.String);
+ Enum = (Class)GetTypeNodeFor("System", "Enum", ElementType.Class);
+ MulticastDelegate = (Class)GetTypeNodeFor("System", "MulticastDelegate", ElementType.Class);
+ Array = (Class)GetTypeNodeFor("System", "Array", ElementType.Class);
+ Type = (Class)GetTypeNodeFor("System", "Type", ElementType.Class);
+ Boolean = (Struct)GetTypeNodeFor("System", "Boolean", ElementType.Boolean);
+ Int8 = (Struct)GetTypeNodeFor("System", "SByte", ElementType.Int8);
+ UInt8 = (Struct)GetTypeNodeFor("System", "Byte", ElementType.UInt8);
+ Int16 = (Struct)GetTypeNodeFor("System", "Int16", ElementType.Int16);
+ UInt16 = (Struct)GetTypeNodeFor("System", "UInt16", ElementType.UInt16);
+ Int32 = (Struct)GetTypeNodeFor("System", "Int32", ElementType.Int32);
+ UInt32 = (Struct)GetTypeNodeFor("System", "UInt32", ElementType.UInt32);
+ Int64 = (Struct)GetTypeNodeFor("System", "Int64", ElementType.Int64);
+ UInt64 = (Struct)GetTypeNodeFor("System", "UInt64", ElementType.UInt64);
+ Single = (Struct)GetTypeNodeFor("System", "Single", ElementType.Single);
+ Double = (Struct)GetTypeNodeFor("System", "Double", ElementType.Double);
+ IntPtr = (Struct)GetTypeNodeFor("System", "IntPtr", ElementType.IntPtr);
+ UIntPtr = (Struct)GetTypeNodeFor("System", "UIntPtr", ElementType.UIntPtr);
+ DynamicallyTypedReference = (Struct)GetTypeNodeFor("System", "TypedReference", ElementType.DynamicallyTypedReference);
+#if !MinimalReader
+ Delegate = (Class)GetTypeNodeFor("System", "Delegate", ElementType.Class);
+ Exception = (Class)GetTypeNodeFor("System", "Exception", ElementType.Class);
+ Attribute = (Class)GetTypeNodeFor("System", "Attribute", ElementType.Class);
+ DBNull = (Class)GetTypeNodeFor("System", "DBNull", ElementType.Class);
+ DateTime = (Struct)GetTypeNodeFor("System", "DateTime", ElementType.ValueType);
+ Decimal = (Struct)GetTypeNodeFor("System", "Decimal", ElementType.ValueType);
+#endif
+ ArgIterator = (Struct)GetTypeNodeFor("System", "ArgIterator", ElementType.ValueType);
+ IsVolatile = (Class)GetTypeNodeFor("System.Runtime.CompilerServices", "IsVolatile", ElementType.Class);
+ Void = (Struct)GetTypeNodeFor("System", "Void", ElementType.Void);
+ RuntimeFieldHandle = (Struct)GetTypeNodeFor("System", "RuntimeFieldHandle", ElementType.ValueType);
+ RuntimeMethodHandle = (Struct)GetTypeNodeFor("System", "RuntimeMethodHandle", ElementType.ValueType);
+ RuntimeTypeHandle = (Struct)GetTypeNodeFor("System", "RuntimeTypeHandle", ElementType.ValueType);
+#if !MinimalReader
+ RuntimeArgumentHandle = (Struct)GetTypeNodeFor("System", "RuntimeArgumentHandle", ElementType.ValueType);
+#endif
+ SecurityAction = GetTypeNodeFor("System.Security.Permissions", "SecurityAction", ElementType.ValueType) as EnumNode;
+ CoreSystemTypes.Initialized = true;
+ CoreSystemTypes.InstantiateGenericInterfaces();
+#if !NoWriter
+ Literal.Initialize();
+#endif
+ object dummy = TargetPlatform.AssemblyReferenceFor; //Force selection of target platform
+ if (dummy == null) return;
+ }
+ private static void ClearStatics()
+ {
+ //Special base types
+ Object = null;
+ String = null;
+ ValueType = null;
+ Enum = null;
+ MulticastDelegate = null;
+ Array = null;
+ Type = null;
+#if !MinimalReader
+ Delegate = null;
+ Exception = null;
+ Attribute = null;
+#endif
+ //primitive types
+ Boolean = null;
+ Char = null;
+ Int8 = null;
+ UInt8 = null;
+ Int16 = null;
+ UInt16 = null;
+ Int32 = null;
+ UInt32 = null;
+ Int64 = null;
+ UInt64 = null;
+ Single = null;
+ Double = null;
+ IntPtr = null;
+ UIntPtr = null;
+ DynamicallyTypedReference = null;
+
+ //Special types
+#if !MinimalReader
+ DBNull = null;
+ DateTime = null;
+ Decimal = null;
+ RuntimeArgumentHandle = null;
+#endif
+ ArgIterator = null;
+ RuntimeFieldHandle = null;
+ RuntimeMethodHandle = null;
+ RuntimeTypeHandle = null;
+ IsVolatile = null;
+ Void = null;
+ SecurityAction = null;
+ }
+ private static void InstantiateGenericInterfaces()
+ {
+ if (TargetPlatform.TargetVersion != null && (TargetPlatform.TargetVersion.Major < 2 && TargetPlatform.TargetVersion.Minor < 2)) return;
+ InstantiateGenericInterfaces(String);
+ InstantiateGenericInterfaces(Boolean);
+ InstantiateGenericInterfaces(Char);
+ InstantiateGenericInterfaces(Int8);
+ InstantiateGenericInterfaces(UInt8);
+ InstantiateGenericInterfaces(Int16);
+ InstantiateGenericInterfaces(UInt16);
+ InstantiateGenericInterfaces(Int32);
+ InstantiateGenericInterfaces(UInt32);
+ InstantiateGenericInterfaces(Int64);
+ InstantiateGenericInterfaces(UInt64);
+ InstantiateGenericInterfaces(Single);
+ InstantiateGenericInterfaces(Double);
+#if !MinimalReader
+ InstantiateGenericInterfaces(DBNull);
+ InstantiateGenericInterfaces(DateTime);
+ InstantiateGenericInterfaces(Decimal);
+#endif
+ }
+ private static void InstantiateGenericInterfaces(TypeNode type)
+ {
+ if (type == null) return;
+ InterfaceList interfaces = type.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ InterfaceExpression ifaceExpr = interfaces[i] as InterfaceExpression;
+ if (ifaceExpr == null) continue;
+ if (ifaceExpr.Template == null) { Debug.Assert(false); continue; }
+ TypeNodeList templArgs = ifaceExpr.TemplateArguments;
+ for (int j = 0, m = templArgs.Count; j < m; j++)
+ {
+ InterfaceExpression ie = templArgs[j] as InterfaceExpression;
+ if (ie != null)
+ templArgs[j] = ie.Template.GetGenericTemplateInstance(type.DeclaringModule, ie.ConsolidatedTemplateArguments);
+ }
+ interfaces[i] = (Interface)ifaceExpr.Template.GetGenericTemplateInstance(type.DeclaringModule, ifaceExpr.ConsolidatedTemplateArguments);
+ }
+ }
+
+ private static AssemblyNode/*!*/ GetSystemAssembly(bool doNotLockFile, bool getDebugInfo)
+ {
+ AssemblyNode result = SystemAssemblyLocation.ParsedAssembly;
+ if (result != null)
+ {
+ result.TargetRuntimeVersion = TargetPlatform.TargetRuntimeVersion;
+ result.MetadataFormatMajorVersion = 1;
+ result.MetadataFormatMinorVersion = 1;
+ result.LinkerMajorVersion = 8;
+ result.LinkerMinorVersion = 0;
+ return result;
+ }
+ if (SystemAssemblyLocation.Location == null || SystemAssemblyLocation.Location.Length == 0)
+ SystemAssemblyLocation.Location = typeof(object).Module.Assembly.Location;
+ result = (AssemblyNode)(new Reader(SystemAssemblyLocation.Location, null, doNotLockFile, getDebugInfo, true, false)).ReadModule();
+ if (result == null && TargetPlatform.TargetVersion != null && TargetPlatform.TargetVersion == typeof(object).Module.Assembly.GetName().Version)
+ {
+ SystemAssemblyLocation.Location = typeof(object).Module.Assembly.Location;
+ result = (AssemblyNode)(new Reader(SystemAssemblyLocation.Location, null, doNotLockFile, getDebugInfo, true, false)).ReadModule();
+ }
+ if (result == null)
+ {
+ result = new AssemblyNode();
+ System.Reflection.AssemblyName aname = typeof(object).Module.Assembly.GetName();
+ result.Name = aname.Name;
+ result.Version = TargetPlatform.TargetVersion;
+ result.PublicKeyOrToken = aname.GetPublicKeyToken();
+ }
+ return result;
+ }
+ private static TypeNode/*!*/ GetTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode)
+ {
+ TypeNode result = null;
+ if (SystemAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+
+ internal static TypeNode/*!*/ GetDummyTypeNode(AssemblyNode declaringAssembly, string/*!*/ nspace, string/*!*/ name, ElementType typeCode)
+ {
+ TypeNode result = null;
+ switch (typeCode)
+ {
+ case ElementType.Object:
+ case ElementType.String:
+ case ElementType.Class:
+ if (name.Length > 1 && name[0] == 'I' && char.IsUpper(name[1]))
+ result = new Interface();
+ else if (name == "MulticastDelegate" || name == "Delegate")
+ result = new Class();
+ else if (name.EndsWith("Callback") || name.EndsWith("Delegate") || name == "ThreadStart" || name == "FrameGuardGetter" || name == "GuardThreadStart")
+ result = new DelegateNode();
+ else
+ result = new Class();
+ break;
+ default:
+ if (name == "CciMemberKind")
+ result = new EnumNode();
+ else
+ result = new Struct();
+ break;
+ }
+ result.Name = Identifier.For(name);
+ result.Namespace = Identifier.For(nspace);
+ result.DeclaringModule = declaringAssembly;
+ return result;
+ }
+ }
+#if !FxCop
+ public
+#endif
+ sealed class SystemTypes
+ {
+ private SystemTypes() { }
+ private static bool Initialized;
+
+ //system assembly (the basic runtime)
+ public static AssemblyNode/*!*/ SystemAssembly
+ {
+ get { return CoreSystemTypes.SystemAssembly; }
+ set { CoreSystemTypes.SystemAssembly = value; }
+ }
+#if ExtendedRuntime
+ public static AssemblyNode/*!*/ SystemCompilerRuntimeAssembly {
+ get{return ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly;}
+ set{ExtendedRuntimeTypes.SystemCompilerRuntimeAssembly = value;}
+ }
+#if !NoData
+ public static AssemblyNode/*!*/ SystemDataAssembly;
+#endif
+#if !NoXml && !NoRuntimeXml
+ public static AssemblyNode /*!*/SystemXmlAssembly;
+#endif
+#endif
+#if !FxCop
+ //Special base types
+ public static Class/*!*/ Object { get { return CoreSystemTypes.Object; } }
+ public static Class/*!*/ String { get { return CoreSystemTypes.String; } }
+ public static Class/*!*/ ValueType { get { return CoreSystemTypes.ValueType; } }
+ public static Class/*!*/ Enum { get { return CoreSystemTypes.Enum; } }
+ public static Class/*!*/ Delegate { get { return CoreSystemTypes.Delegate; } }
+ public static Class/*!*/ MulticastDelegate { get { return CoreSystemTypes.MulticastDelegate; } }
+ public static Class/*!*/ Array { get { return CoreSystemTypes.Array; } }
+ public static Class/*!*/ Type { get { return CoreSystemTypes.Type; } }
+ public static Class/*!*/ Exception { get { return CoreSystemTypes.Exception; } }
+ public static Class/*!*/ Attribute { get { return CoreSystemTypes.Attribute; } }
+
+ //primitive types
+ public static Struct/*!*/ Boolean { get { return CoreSystemTypes.Boolean; } }
+ public static Struct/*!*/ Char { get { return CoreSystemTypes.Char; } }
+ public static Struct/*!*/ Int8 { get { return CoreSystemTypes.Int8; } }
+ public static Struct/*!*/ UInt8 { get { return CoreSystemTypes.UInt8; } }
+ public static Struct/*!*/ Int16 { get { return CoreSystemTypes.Int16; } }
+ public static Struct/*!*/ UInt16 { get { return CoreSystemTypes.UInt16; } }
+ public static Struct/*!*/ Int32 { get { return CoreSystemTypes.Int32; } }
+ public static Struct/*!*/ UInt32 { get { return CoreSystemTypes.UInt32; } }
+ public static Struct/*!*/ Int64 { get { return CoreSystemTypes.Int64; } }
+ public static Struct/*!*/ UInt64 { get { return CoreSystemTypes.UInt64; } }
+ public static Struct/*!*/ Single { get { return CoreSystemTypes.Single; } }
+ public static Struct/*!*/ Double { get { return CoreSystemTypes.Double; } }
+ public static Struct/*!*/ IntPtr { get { return CoreSystemTypes.IntPtr; } }
+ public static Struct/*!*/ UIntPtr { get { return CoreSystemTypes.UIntPtr; } }
+ public static Struct/*!*/ DynamicallyTypedReference { get { return CoreSystemTypes.DynamicallyTypedReference; } }
+#endif
+
+ // Types required for a complete rendering
+ // of binary attribute information
+ public static Class/*!*/ AttributeUsageAttribute;
+ public static Class/*!*/ ConditionalAttribute;
+ public static Class/*!*/ DefaultMemberAttribute;
+ public static Class/*!*/ InternalsVisibleToAttribute;
+ public static Class/*!*/ ObsoleteAttribute;
+
+ // Types required to render arrays
+ public static Interface/*!*/ GenericICollection;
+ public static Interface/*!*/ GenericIEnumerable;
+ public static Interface/*!*/ GenericIList;
+ public static Interface/*!*/ ICloneable;
+ public static Interface/*!*/ ICollection;
+ public static Interface/*!*/ IEnumerable;
+ public static Interface/*!*/ IList;
+
+#if !MinimalReader
+ //Special types
+ public static Struct/*!*/ ArgIterator { get { return CoreSystemTypes.ArgIterator; } }
+ public static Class/*!*/ IsVolatile { get { return CoreSystemTypes.IsVolatile; } }
+ public static Struct/*!*/ Void { get { return CoreSystemTypes.Void; } }
+ public static Struct/*!*/ RuntimeFieldHandle { get { return CoreSystemTypes.RuntimeTypeHandle; } }
+ public static Struct/*!*/ RuntimeMethodHandle { get { return CoreSystemTypes.RuntimeTypeHandle; } }
+ public static Struct/*!*/ RuntimeTypeHandle { get { return CoreSystemTypes.RuntimeTypeHandle; } }
+ public static Struct/*!*/ RuntimeArgumentHandle { get { return CoreSystemTypes.RuntimeArgumentHandle; } }
+
+ //Special attributes
+ public static Class/*!*/ AllowPartiallyTrustedCallersAttribute;
+ public static Class/*!*/ AssemblyCompanyAttribute;
+ public static Class/*!*/ AssemblyConfigurationAttribute;
+ public static Class/*!*/ AssemblyCopyrightAttribute;
+ public static Class/*!*/ AssemblyCultureAttribute;
+ public static Class/*!*/ AssemblyDelaySignAttribute;
+ public static Class/*!*/ AssemblyDescriptionAttribute;
+ public static Class/*!*/ AssemblyFileVersionAttribute;
+ public static Class/*!*/ AssemblyFlagsAttribute;
+ public static Class/*!*/ AssemblyInformationalVersionAttribute;
+ public static Class/*!*/ AssemblyKeyFileAttribute;
+ public static Class/*!*/ AssemblyKeyNameAttribute;
+ public static Class/*!*/ AssemblyProductAttribute;
+ public static Class/*!*/ AssemblyTitleAttribute;
+ public static Class/*!*/ AssemblyTrademarkAttribute;
+ public static Class/*!*/ AssemblyVersionAttribute;
+ public static Class/*!*/ ClassInterfaceAttribute;
+ public static Class/*!*/ CLSCompliantAttribute;
+ public static Class/*!*/ ComImportAttribute;
+ public static Class/*!*/ ComRegisterFunctionAttribute;
+ public static Class/*!*/ ComSourceInterfacesAttribute;
+ public static Class/*!*/ ComUnregisterFunctionAttribute;
+ public static Class/*!*/ ComVisibleAttribute;
+ public static Class/*!*/ DebuggableAttribute;
+ public static Class/*!*/ DebuggerHiddenAttribute;
+ public static Class/*!*/ DebuggerStepThroughAttribute;
+ public static EnumNode DebuggingModes;
+ public static Class/*!*/ DllImportAttribute;
+ public static Class/*!*/ FieldOffsetAttribute;
+ public static Class/*!*/ FlagsAttribute;
+ public static Class/*!*/ GuidAttribute;
+ public static Class/*!*/ ImportedFromTypeLibAttribute;
+ public static Class/*!*/ InAttribute;
+ public static Class/*!*/ IndexerNameAttribute;
+ public static Class/*!*/ InterfaceTypeAttribute;
+ public static Class/*!*/ MethodImplAttribute;
+ public static Class/*!*/ NonSerializedAttribute;
+ public static Class/*!*/ OptionalAttribute;
+ public static Class/*!*/ OutAttribute;
+ public static Class/*!*/ ParamArrayAttribute;
+ public static Class/*!*/ RuntimeCompatibilityAttribute;
+ public static Class/*!*/ SatelliteContractVersionAttribute;
+ public static Class/*!*/ SerializableAttribute;
+ public static Class/*!*/ SecurityAttribute;
+ public static Class/*!*/ SecurityCriticalAttribute;
+ public static Class/*!*/ SecurityTransparentAttribute;
+ public static Class/*!*/ SecurityTreatAsSafeAttribute;
+ public static Class/*!*/ STAThreadAttribute;
+ public static Class/*!*/ StructLayoutAttribute;
+ public static Class/*!*/ SuppressMessageAttribute;
+ public static Class/*!*/ SuppressUnmanagedCodeSecurityAttribute;
+ public static EnumNode SecurityAction;
+
+ //Classes need for System.TypeCode
+ public static Class/*!*/ DBNull;
+ public static Struct/*!*/ DateTime;
+ public static Struct/*!*/ Decimal { get { return CoreSystemTypes.Decimal; } }
+ public static Struct/*!*/ TimeSpan;
+
+ //Classes and interfaces used by the Framework
+ public static Class/*!*/ Activator;
+ public static Class/*!*/ AppDomain;
+ public static Class/*!*/ ApplicationException;
+ public static Class/*!*/ ArgumentException;
+ public static Class/*!*/ ArgumentNullException;
+ public static Class/*!*/ ArgumentOutOfRangeException;
+ public static Class/*!*/ ArrayList;
+ public static DelegateNode/*!*/ AsyncCallback;
+ public static Class/*!*/ Assembly;
+ public static Class/*!*/ CodeAccessPermission;
+ public static Class/*!*/ CollectionBase;
+ public static Class/*!*/ CultureInfo;
+ public static Class/*!*/ DictionaryBase;
+ public static Struct/*!*/ DictionaryEntry;
+ public static Class/*!*/ DuplicateWaitObjectException;
+ public static Class/*!*/ Environment;
+ public static Class/*!*/ EventArgs;
+ public static Class/*!*/ ExecutionEngineException;
+ public static Struct/*!*/ GenericArraySegment;
+#if !WHIDBEYwithGenerics
+ public static Class/*!*/ GenericArrayToIEnumerableAdapter;
+#endif
+ public static Class/*!*/ GenericDictionary;
+ public static Interface/*!*/ GenericIComparable;
+ public static Interface/*!*/ GenericIComparer;
+ public static Interface/*!*/ GenericIDictionary;
+ public static Interface/*!*/ GenericIEnumerator;
+ public static Struct/*!*/ GenericKeyValuePair;
+ public static Class/*!*/ GenericList;
+ public static Struct/*!*/ GenericNullable;
+ public static Class/*!*/ GenericQueue;
+ public static Class/*!*/ GenericSortedDictionary;
+ public static Class/*!*/ GenericStack;
+ public static Class/*!*/ GC;
+ public static Struct/*!*/ Guid;
+ public static Class/*!*/ __HandleProtector;
+ public static Struct/*!*/ HandleRef;
+ public static Class/*!*/ Hashtable;
+ public static Interface/*!*/ IASyncResult;
+ public static Interface/*!*/ IComparable;
+ public static Interface/*!*/ IDictionary;
+ public static Interface/*!*/ IComparer;
+ public static Interface/*!*/ IDisposable;
+ public static Interface/*!*/ IEnumerator;
+ public static Interface/*!*/ IFormatProvider;
+ public static Interface/*!*/ IHashCodeProvider;
+ public static Interface/*!*/ IMembershipCondition;
+ public static Class/*!*/ IndexOutOfRangeException;
+ public static Class/*!*/ InvalidCastException;
+ public static Class/*!*/ InvalidOperationException;
+ public static Interface/*!*/ IPermission;
+ public static Interface/*!*/ ISerializable;
+ public static Interface/*!*/ IStackWalk;
+ public static Class/*!*/ Marshal;
+ public static Class/*!*/ MarshalByRefObject;
+ public static Class/*!*/ MemberInfo;
+ public static Struct/*!*/ NativeOverlapped;
+ public static Class/*!*/ Monitor;
+ public static Class/*!*/ NotSupportedException;
+ public static Class/*!*/ NullReferenceException;
+ public static Class/*!*/ OutOfMemoryException;
+ public static Class/*!*/ ParameterInfo;
+ public static Class/*!*/ Queue;
+ public static Class/*!*/ ReadOnlyCollectionBase;
+ public static Class/*!*/ ResourceManager;
+ public static Class/*!*/ ResourceSet;
+ public static Class/*!*/ SerializationInfo;
+ public static Class/*!*/ Stack;
+ public static Class/*!*/ StackOverflowException;
+ public static Class/*!*/ Stream;
+ public static Struct/*!*/ StreamingContext;
+ public static Class/*!*/ StringBuilder;
+ public static Class/*!*/ StringComparer;
+ public static EnumNode StringComparison;
+ public static Class/*!*/ SystemException;
+ public static Class/*!*/ Thread;
+ public static Class/*!*/ WindowsImpersonationContext;
+#endif
+#if ExtendedRuntime
+ public static Interface/*!*/ ConstrainedType { get { return ExtendedRuntimeTypes.ConstrainedType; } }
+ public static Interface/*!*/ TupleType { get { return ExtendedRuntimeTypes.TupleType; } }
+ public static Interface/*!*/ TypeAlias { get { return ExtendedRuntimeTypes.TypeAlias; } }
+ public static Interface/*!*/ TypeDefinition { get { return ExtendedRuntimeTypes.TypeDefinition; } }
+ public static Interface/*!*/ TypeIntersection { get { return ExtendedRuntimeTypes.TypeIntersection; } }
+ public static Interface/*!*/ TypeUnion { get { return ExtendedRuntimeTypes.TypeUnion; } }
+ public static Class/*!*/ AnonymousAttribute;
+ public static TypeNode/*!*/ AnonymityEnum;
+ public static Class/*!*/ ComposerAttribute;
+ public static Class/*!*/ CustomVisitorAttribute;
+ public static Class/*!*/ TemplateAttribute;
+ public static Class/*!*/ TemplateInstanceAttribute;
+ public static Class/*!*/ UnmanagedStructTemplateParameterAttribute;
+ public static Class/*!*/ TemplateParameterFlagsAttribute;
+ public static Struct/*!*/ GenericBoxed;
+ public static Class/*!*/ GenericIEnumerableToGenericIListAdapter;
+ public static Struct/*!*/ GenericInvariant;
+ public static Struct/*!*/ GenericNonEmptyIEnumerable;
+ public static Struct/*!*/ GenericNonNull;
+ public static Class/*!*/ GenericStreamUtility;
+ public static Class/*!*/ GenericUnboxer;
+ public static Interface/*!*/ ITemplateParameter { get { return ExtendedRuntimeTypes.ITemplateParameter; } }
+ public static Class/*!*/ ElementTypeAttribute;
+ public static Interface/*!*/ IDbTransactable;
+ public static Interface/*!*/ IAggregate;
+ public static Interface/*!*/ IAggregateGroup;
+ public static Class/*!*/ StreamNotSingletonException;
+ public static EnumNode SqlHint;
+ public static Class/*!*/ SqlFunctions;
+ public static Class/*!*/ XmlAttributeAttributeClass;
+ public static Class/*!*/ XmlChoiceIdentifierAttributeClass;
+ public static Class/*!*/ XmlElementAttributeClass;
+ public static Class/*!*/ XmlIgnoreAttributeClass;
+ public static Class/*!*/ XmlTypeAttributeClass;
+ public static Interface/*!*/ INullable;
+ public static Struct/*!*/ SqlBinary;
+ public static Struct/*!*/ SqlBoolean;
+ public static Struct/*!*/ SqlByte;
+ public static Struct/*!*/ SqlDateTime;
+ public static Struct/*!*/ SqlDecimal;
+ public static Struct/*!*/ SqlDouble;
+ public static Struct/*!*/ SqlGuid;
+ public static Struct/*!*/ SqlInt16;
+ public static Struct/*!*/ SqlInt32;
+ public static Struct/*!*/ SqlInt64;
+ public static Struct/*!*/ SqlMoney;
+ public static Struct/*!*/ SqlSingle;
+ public static Struct/*!*/ SqlString;
+ public static Interface/*!*/ IDbConnection;
+ public static Interface/*!*/ IDbTransaction;
+ public static EnumNode IsolationLevel;
+
+ //OrdinaryExceptions
+ public static Class/*!*/ NoChoiceException;
+ public static Class/*!*/ IllegalUpcastException;
+ public static EnumNode/*!*/ CciMemberKind;
+ public static Class/*!*/ CciMemberKindAttribute;
+ //NonNull
+ public static Class/*!*/ Range;
+ //Invariants
+ public static DelegateNode/*!*/ InitGuardSetsDelegate;
+ public static DelegateNode/*!*/ CheckInvariantDelegate;
+ public static DelegateNode/*!*/ FrameGuardGetter;
+ public static Class/*!*/ ObjectInvariantException;
+ public static DelegateNode/*!*/ ThreadConditionDelegate;
+ public static DelegateNode/*!*/ GuardThreadStart;
+ public static Class/*!*/ Guard;
+ public static Class/*!*/ ContractMarkers;
+ //public static Interface IReduction;
+ public static Class/*!*/ AssertHelpers;
+ public static DelegateNode/*!*/ ThreadStart;
+ //CheckedExceptions
+ public static Interface/*!*/ ICheckedException;
+ public static Class/*!*/ CheckedException;
+
+ // Contracts
+ public static Class/*!*/ UnreachableException;
+ public static Class/*!*/ ContractException;
+ public static Class/*!*/ NullTypeException;
+ public static Class/*!*/ AssertException;
+ public static Class/*!*/ AssumeException;
+ public static Class/*!*/ InvalidContractException;
+ public static Class/*!*/ RequiresException;
+ public static Class/*!*/ EnsuresException;
+ public static Class/*!*/ ModifiesException;
+ public static Class/*!*/ ThrowsException;
+ public static Class/*!*/ DoesException;
+ public static Class/*!*/ InvariantException;
+ public static Class/*!*/ ContractMarkerException;
+
+ public static Class/*!*/ AdditiveAttribute;
+ public static Class/*!*/ InsideAttribute;
+ public static Class/*!*/ SpecPublicAttribute;
+ public static Class/*!*/ SpecProtectedAttribute;
+ public static Class/*!*/ SpecInternalAttribute;
+ public static Class/*!*/ PureAttribute;
+ public static Class/*!*/ OwnedAttribute;
+ public static Class/*!*/ RepAttribute;
+ public static Class/*!*/ PeerAttribute;
+ public static Class/*!*/ CapturedAttribute;
+ public static Class/*!*/ LockProtectedAttribute;
+ public static Class/*!*/ RequiresLockProtectedAttribute;
+ public static Class/*!*/ ImmutableAttribute;
+ public static Class/*!*/ RequiresImmutableAttribute;
+ public static Class/*!*/ RequiresCanWriteAttribute;
+ public static Class/*!*/ StateIndependentAttribute;
+ public static Class/*!*/ ConfinedAttribute;
+ public static Class/*!*/ ModelfieldContractAttribute;
+ public static Class/*!*/ ModelfieldAttribute;
+ public static Class/*!*/ SatisfiesAttribute; //Stores a satisfies clause of a modelfield
+ public static Class/*!*/ ModelfieldException;
+
+ public static Class/*!*/ OnceAttribute;
+ public static Class/*!*/ WriteConfinedAttribute;
+ public static Class/*!*/ GlobalReadAttribute;
+ public static Class/*!*/ GlobalAccessAttribute;
+ public static Class/*!*/ GlobalWriteAttribute;
+ public static Class/*!*/ FreshAttribute;
+ public static Class/*!*/ EscapesAttribute;
+
+ public static Class/*!*/ ModelAttribute;
+ public static Class/*!*/ RequiresAttribute;
+ public static Class/*!*/ EnsuresAttribute;
+ public static Class/*!*/ ModifiesAttribute;
+ public static Class/*!*/ HasWitnessAttribute;
+ public static Class/*!*/ InferredReturnValueAttribute;
+ public static Class/*!*/ ThrowsAttribute;
+ public static Class/*!*/ DoesAttribute;
+ public static Class/*!*/ InvariantAttribute;
+ public static Class/*!*/ NoDefaultActivityAttribute;
+ public static Class/*!*/ NoDefaultContractAttribute;
+ public static Class/*!*/ ReaderAttribute;
+ public static Class/*!*/ ShadowsAssemblyAttribute;
+ public static Class/*!*/ VerifyAttribute;
+ public static Class/*!*/ NonNullType { get { return ExtendedRuntimeTypes.NonNullType; } }
+ public static Method NonNullTypeAssertInitialized { get { return ExtendedRuntimeTypes.NonNullTypeAssertInitialized; } }
+ public static Method NonNullTypeAssertInitializedGeneric { get { return ExtendedRuntimeTypes.NonNullTypeAssertInitializedGeneric; } }
+
+ public static Class/*!*/ NullableType { get { return ExtendedRuntimeTypes.NullableType; } }
+ public static Class/*!*/ NotNullAttribute { get { return ExtendedRuntimeTypes.NotNullAttribute; } }
+ public static Class/*!*/ NotNullGenericArgumentsAttribute { get { return ExtendedRuntimeTypes.NotNullGenericArgumentsAttribute; } }
+ public static Class/*!*/ EncodedTypeSpecAttribute { get { return ExtendedRuntimeTypes.EncodedTypeSpecAttribute; } }
+ public static Class/*!*/ DependentAttribute;
+ public static Class/*!*/ ElementsRepAttribute;
+ public static Class/*!*/ ElementsPeerAttribute;
+ public static Class/*!*/ ElementAttribute;
+ public static Class/*!*/ ElementCollectionAttribute;
+ public static Class/*!*/ RecursionTerminationAttribute;
+ public static Class/*!*/ NoReferenceComparisonAttribute;
+ public static Class/*!*/ ResultNotNewlyAllocatedAttribute;
+
+ // This attribute is recognized by the Bartok compiler and marks methods without heap allocation.
+ // Thus the presence of this attribute implies [ResultNotNewlyAllocated] for pure methods.
+ public static Class/*!*/ BartokNoHeapAllocationAttribute {
+ //^ [NoDefaultContract]
+ get
+ //^ modifies noHeapAllocationAttribute;
+ {
+ if(noHeapAllocationAttribute == null) {
+ noHeapAllocationAttribute = (Class)GetCompilerRuntimeTypeNodeFor(
+ @"System.Runtime.CompilerServices", @"NoHeapAllocationAttribute", ElementType.Class);
+ }
+ return noHeapAllocationAttribute;
+ }
+ }
+ private static Class noHeapAllocationAttribute;
+#endif
+
+ static SystemTypes()
+ {
+ SystemTypes.Initialize(TargetPlatform.DoNotLockFiles, TargetPlatform.GetDebugInfo);
+ }
+
+#if FxCop
+ internal static event EventHandler<EventArgs> ClearingSystemTypes;
+ internal static void RaiseClearingSystemTypes()
+ {
+ EventHandler<EventArgs> handler = ClearingSystemTypes;
+ if (handler != null) handler(null, EventArgs.Empty);
+ }
+#endif
+ public static void Clear()
+ {
+ lock (Module.GlobalLock)
+ {
+ CoreSystemTypes.Clear();
+#if FxCop
+ RaiseClearingSystemTypes();
+#endif
+#if ExtendedRuntime
+ ExtendedRuntimeTypes.Clear();
+ if (SystemTypes.SystemCompilerRuntimeAssembly != null && SystemTypes.SystemCompilerRuntimeAssembly != AssemblyNode.Dummy) {
+ SystemTypes.SystemCompilerRuntimeAssembly.Dispose();
+ SystemTypes.SystemCompilerRuntimeAssembly = null;
+ }
+#if !NoData && !ROTOR
+ if (SystemTypes.SystemDataAssembly != null && SystemTypes.SystemDataAssembly != AssemblyNode.Dummy) {
+ SystemTypes.SystemDataAssembly.Dispose();
+ SystemTypes.SystemDataAssembly = null;
+ }
+#endif
+#if !NoXml && !NoRuntimeXml
+ if (SystemTypes.SystemXmlAssembly != null && SystemTypes.SystemXmlAssembly != AssemblyNode.Dummy) {
+ SystemTypes.SystemXmlAssembly.Dispose();
+ SystemTypes.SystemXmlAssembly = null;
+ }
+#endif
+#endif
+ SystemTypes.ClearStatics();
+ SystemTypes.Initialized = false;
+ }
+ }
+ public static void Initialize(bool doNotLockFile, bool getDebugInfo)
+ {
+ if (SystemTypes.Initialized)
+ {
+ SystemTypes.Clear();
+ CoreSystemTypes.Initialize(doNotLockFile, getDebugInfo);
+#if ExtendedRuntime
+ ExtendedRuntimeTypes.Initialize(doNotLockFile, getDebugInfo);
+#endif
+ }
+ else if (!CoreSystemTypes.Initialized)
+ {
+ CoreSystemTypes.Initialize(doNotLockFile, getDebugInfo);
+#if ExtendedRuntime
+ ExtendedRuntimeTypes.Clear();
+ ExtendedRuntimeTypes.Initialize(doNotLockFile, getDebugInfo);
+#endif
+ }
+
+ if (TargetPlatform.TargetVersion == null)
+ {
+ TargetPlatform.TargetVersion = SystemAssembly.Version;
+ if (TargetPlatform.TargetVersion == null)
+ TargetPlatform.TargetVersion = typeof(object).Module.Assembly.GetName().Version;
+ }
+ //TODO: throw an exception when the result is null
+#if ExtendedRuntime
+#if !NoData && !ROTOR
+ SystemDataAssembly = SystemTypes.GetSystemDataAssembly(doNotLockFile, getDebugInfo);
+#endif
+#if !NoXml && !NoRuntimeXml
+ SystemXmlAssembly = SystemTypes.GetSystemXmlAssembly(doNotLockFile, getDebugInfo);
+#endif
+#endif
+ AttributeUsageAttribute = (Class)GetTypeNodeFor("System", "AttributeUsageAttribute", ElementType.Class);
+ ConditionalAttribute = (Class)GetTypeNodeFor("System.Diagnostics", "ConditionalAttribute", ElementType.Class);
+ DefaultMemberAttribute = (Class)GetTypeNodeFor("System.Reflection", "DefaultMemberAttribute", ElementType.Class);
+ InternalsVisibleToAttribute = (Class)GetTypeNodeFor("System.Runtime.CompilerServices", "InternalsVisibleToAttribute", ElementType.Class);
+ ObsoleteAttribute = (Class)GetTypeNodeFor("System", "ObsoleteAttribute", ElementType.Class);
+
+ GenericICollection = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "ICollection", 1, ElementType.Class);
+ GenericIEnumerable = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IEnumerable", 1, ElementType.Class);
+ GenericIList = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IList", 1, ElementType.Class);
+ ICloneable = (Interface)GetTypeNodeFor("System", "ICloneable", ElementType.Class);
+ ICollection = (Interface)GetTypeNodeFor("System.Collections", "ICollection", ElementType.Class);
+ IEnumerable = (Interface)GetTypeNodeFor("System.Collections", "IEnumerable", ElementType.Class);
+ IList = (Interface)GetTypeNodeFor("System.Collections", "IList", ElementType.Class);
+
+#if !MinimalReader
+ AllowPartiallyTrustedCallersAttribute = (Class)GetTypeNodeFor("System.Security", "AllowPartiallyTrustedCallersAttribute", ElementType.Class);
+ AssemblyCompanyAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyCompanyAttribute", ElementType.Class);
+ AssemblyConfigurationAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyConfigurationAttribute", ElementType.Class);
+ AssemblyCopyrightAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyCopyrightAttribute", ElementType.Class);
+ AssemblyCultureAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyCultureAttribute", ElementType.Class);
+ AssemblyDelaySignAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyDelaySignAttribute", ElementType.Class);
+ AssemblyDescriptionAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyDescriptionAttribute", ElementType.Class);
+ AssemblyFileVersionAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyFileVersionAttribute", ElementType.Class);
+ AssemblyFlagsAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyFlagsAttribute", ElementType.Class);
+ AssemblyInformationalVersionAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyInformationalVersionAttribute", ElementType.Class);
+ AssemblyKeyFileAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyKeyFileAttribute", ElementType.Class);
+ AssemblyKeyNameAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyKeyNameAttribute", ElementType.Class);
+ AssemblyProductAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyProductAttribute", ElementType.Class);
+ AssemblyTitleAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyTitleAttribute", ElementType.Class);
+ AssemblyTrademarkAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyTrademarkAttribute", ElementType.Class);
+ AssemblyVersionAttribute = (Class)GetTypeNodeFor("System.Reflection", "AssemblyVersionAttribute", ElementType.Class);
+ ClassInterfaceAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ClassInterfaceAttribute", ElementType.Class);
+ CLSCompliantAttribute = (Class)GetTypeNodeFor("System", "CLSCompliantAttribute", ElementType.Class);
+ ComImportAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ComImportAttribute", ElementType.Class);
+ ComRegisterFunctionAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ComRegisterFunctionAttribute", ElementType.Class);
+ ComSourceInterfacesAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ComSourceInterfacesAttribute", ElementType.Class);
+ ComUnregisterFunctionAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ComUnregisterFunctionAttribute", ElementType.Class);
+ ComVisibleAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ComVisibleAttribute", ElementType.Class);
+ DebuggableAttribute = (Class)GetTypeNodeFor("System.Diagnostics", "DebuggableAttribute", ElementType.Class);
+ DebuggerHiddenAttribute = (Class)GetTypeNodeFor("System.Diagnostics", "DebuggerHiddenAttribute", ElementType.Class);
+ DebuggerStepThroughAttribute = (Class)GetTypeNodeFor("System.Diagnostics", "DebuggerStepThroughAttribute", ElementType.Class);
+ DebuggingModes = DebuggableAttribute == null ? null : DebuggableAttribute.GetNestedType(Identifier.For("DebuggingModes")) as EnumNode;
+ DllImportAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "DllImportAttribute", ElementType.Class);
+ FieldOffsetAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "FieldOffsetAttribute", ElementType.Class);
+ FlagsAttribute = (Class)GetTypeNodeFor("System", "FlagsAttribute", ElementType.Class);
+ Guid = (Struct)GetTypeNodeFor("System", "Guid", ElementType.ValueType);
+ GuidAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "GuidAttribute", ElementType.Class);
+ ImportedFromTypeLibAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "ImportedFromTypeLibAttribute", ElementType.Class);
+ InAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "InAttribute", ElementType.Class);
+ IndexerNameAttribute = (Class)GetTypeNodeFor("System.Runtime.CompilerServices", "IndexerNameAttribute", ElementType.Class);
+ InterfaceTypeAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "InterfaceTypeAttribute", ElementType.Class);
+ MethodImplAttribute = (Class)GetTypeNodeFor("System.Runtime.CompilerServices", "MethodImplAttribute", ElementType.Class);
+ NonSerializedAttribute = (Class)GetTypeNodeFor("System", "NonSerializedAttribute", ElementType.Class);
+ OptionalAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "OptionalAttribute", ElementType.Class);
+ OutAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "OutAttribute", ElementType.Class);
+ ParamArrayAttribute = (Class)GetTypeNodeFor("System", "ParamArrayAttribute", ElementType.Class);
+ RuntimeCompatibilityAttribute = (Class)GetTypeNodeFor("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute", ElementType.Class);
+ SatelliteContractVersionAttribute = (Class)GetTypeNodeFor("System.Resources", "SatelliteContractVersionAttribute", ElementType.Class);
+ SerializableAttribute = (Class)GetTypeNodeFor("System", "SerializableAttribute", ElementType.Class);
+ SecurityAttribute = (Class)GetTypeNodeFor("System.Security.Permissions", "SecurityAttribute", ElementType.Class);
+ SecurityCriticalAttribute = (Class)GetTypeNodeFor("System.Security", "SecurityCriticalAttribute", ElementType.Class);
+ SecurityTransparentAttribute = (Class)GetTypeNodeFor("System.Security", "SecurityTransparentAttribute", ElementType.Class);
+ SecurityTreatAsSafeAttribute = (Class)GetTypeNodeFor("System.Security", "SecurityTreatAsSafeAttribute", ElementType.Class);
+ STAThreadAttribute = (Class)GetTypeNodeFor("System", "STAThreadAttribute", ElementType.Class);
+ StructLayoutAttribute = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "StructLayoutAttribute", ElementType.Class);
+ SuppressMessageAttribute = (Class)GetTypeNodeFor("System.Diagnostics.CodeAnalysis", "SuppressMessageAttribute", ElementType.Class);
+ SuppressUnmanagedCodeSecurityAttribute = (Class)GetTypeNodeFor("System.Security", "SuppressUnmanagedCodeSecurityAttribute", ElementType.Class);
+ SecurityAction = GetTypeNodeFor("System.Security.Permissions", "SecurityAction", ElementType.ValueType) as EnumNode;
+ DBNull = (Class)GetTypeNodeFor("System", "DBNull", ElementType.Class);
+ DateTime = (Struct)GetTypeNodeFor("System", "DateTime", ElementType.ValueType);
+ TimeSpan = (Struct)GetTypeNodeFor("System", "TimeSpan", ElementType.ValueType);
+ Activator = (Class)GetTypeNodeFor("System", "Activator", ElementType.Class);
+ AppDomain = (Class)GetTypeNodeFor("System", "AppDomain", ElementType.Class);
+ ApplicationException = (Class)GetTypeNodeFor("System", "ApplicationException", ElementType.Class);
+ ArgumentException = (Class)GetTypeNodeFor("System", "ArgumentException", ElementType.Class);
+ ArgumentNullException = (Class)GetTypeNodeFor("System", "ArgumentNullException", ElementType.Class);
+ ArgumentOutOfRangeException = (Class)GetTypeNodeFor("System", "ArgumentOutOfRangeException", ElementType.Class);
+ ArrayList = (Class)GetTypeNodeFor("System.Collections", "ArrayList", ElementType.Class);
+ AsyncCallback = (DelegateNode)GetTypeNodeFor("System", "AsyncCallback", ElementType.Class);
+ Assembly = (Class)GetTypeNodeFor("System.Reflection", "Assembly", ElementType.Class);
+ CodeAccessPermission = (Class)GetTypeNodeFor("System.Security", "CodeAccessPermission", ElementType.Class);
+ CollectionBase = (Class)GetTypeNodeFor("System.Collections", "CollectionBase", ElementType.Class);
+ CultureInfo = (Class)GetTypeNodeFor("System.Globalization", "CultureInfo", ElementType.Class);
+ DictionaryBase = (Class)GetTypeNodeFor("System.Collections", "DictionaryBase", ElementType.Class);
+ DictionaryEntry = (Struct)GetTypeNodeFor("System.Collections", "DictionaryEntry", ElementType.ValueType);
+ DuplicateWaitObjectException = (Class)GetTypeNodeFor("System", "DuplicateWaitObjectException", ElementType.Class);
+ Environment = (Class)GetTypeNodeFor("System", "Environment", ElementType.Class);
+ EventArgs = (Class)GetTypeNodeFor("System", "EventArgs", ElementType.Class);
+ ExecutionEngineException = (Class)GetTypeNodeFor("System", "ExecutionEngineException", ElementType.Class);
+ GenericArraySegment = (Struct)GetGenericRuntimeTypeNodeFor("System", "ArraySegment", 1, ElementType.ValueType);
+ GenericDictionary = (Class)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "Dictionary", 2, ElementType.Class);
+ GenericIComparable = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IComparable", 1, ElementType.Class);
+ GenericIComparer = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IComparer", 1, ElementType.Class);
+ GenericIDictionary = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IDictionary", 2, ElementType.Class);
+ GenericIEnumerator = (Interface)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "IEnumerator", 1, ElementType.Class);
+ GenericKeyValuePair = (Struct)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "KeyValuePair", 2, ElementType.ValueType);
+ GenericList = (Class)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "List", 1, ElementType.Class);
+ GenericNullable = (Struct)GetGenericRuntimeTypeNodeFor("System", "Nullable", 1, ElementType.ValueType);
+ GenericQueue = (Class)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "Queue", 1, ElementType.Class);
+ GenericSortedDictionary = (Class)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "SortedDictionary", 2, ElementType.Class);
+ GenericStack = (Class)GetGenericRuntimeTypeNodeFor("System.Collections.Generic", "Stack", 1, ElementType.Class);
+ GC = (Class)GetTypeNodeFor("System", "GC", ElementType.Class);
+ __HandleProtector = (Class)GetTypeNodeFor("System.Threading", "__HandleProtector", ElementType.Class);
+ HandleRef = (Struct)GetTypeNodeFor("System.Runtime.InteropServices", "HandleRef", ElementType.ValueType);
+ Hashtable = (Class)GetTypeNodeFor("System.Collections", "Hashtable", ElementType.Class);
+ IASyncResult = (Interface)GetTypeNodeFor("System", "IAsyncResult", ElementType.Class);
+ IComparable = (Interface)GetTypeNodeFor("System", "IComparable", ElementType.Class);
+ IComparer = (Interface)GetTypeNodeFor("System.Collections", "IComparer", ElementType.Class);
+ IDictionary = (Interface)GetTypeNodeFor("System.Collections", "IDictionary", ElementType.Class);
+ IDisposable = (Interface)GetTypeNodeFor("System", "IDisposable", ElementType.Class);
+ IEnumerator = (Interface)GetTypeNodeFor("System.Collections", "IEnumerator", ElementType.Class);
+ IFormatProvider = (Interface)GetTypeNodeFor("System", "IFormatProvider", ElementType.Class);
+ IHashCodeProvider = (Interface)GetTypeNodeFor("System.Collections", "IHashCodeProvider", ElementType.Class);
+ IMembershipCondition = (Interface)GetTypeNodeFor("System.Security.Policy", "IMembershipCondition", ElementType.Class);
+ IndexOutOfRangeException = (Class)GetTypeNodeFor("System", "IndexOutOfRangeException", ElementType.Class);
+ InvalidCastException = (Class)GetTypeNodeFor("System", "InvalidCastException", ElementType.Class);
+ InvalidOperationException = (Class)GetTypeNodeFor("System", "InvalidOperationException", ElementType.Class);
+ IPermission = (Interface)GetTypeNodeFor("System.Security", "IPermission", ElementType.Class);
+ ISerializable = (Interface)GetTypeNodeFor("System.Runtime.Serialization", "ISerializable", ElementType.Class);
+ IStackWalk = (Interface)GetTypeNodeFor("System.Security", "IStackWalk", ElementType.Class);
+ Marshal = (Class)GetTypeNodeFor("System.Runtime.InteropServices", "Marshal", ElementType.Class);
+ MarshalByRefObject = (Class)GetTypeNodeFor("System", "MarshalByRefObject", ElementType.Class);
+ MemberInfo = (Class)GetTypeNodeFor("System.Reflection", "MemberInfo", ElementType.Class);
+ Monitor = (Class)GetTypeNodeFor("System.Threading", "Monitor", ElementType.Class);
+ NativeOverlapped = (Struct)GetTypeNodeFor("System.Threading", "NativeOverlapped", ElementType.ValueType);
+ NotSupportedException = (Class)GetTypeNodeFor("System", "NotSupportedException", ElementType.Class);
+ NullReferenceException = (Class)GetTypeNodeFor("System", "NullReferenceException", ElementType.Class);
+ OutOfMemoryException = (Class)GetTypeNodeFor("System", "OutOfMemoryException", ElementType.Class);
+ ParameterInfo = (Class)GetTypeNodeFor("System.Reflection", "ParameterInfo", ElementType.Class);
+ Queue = (Class)GetTypeNodeFor("System.Collections", "Queue", ElementType.Class);
+ ReadOnlyCollectionBase = (Class)GetTypeNodeFor("System.Collections", "ReadOnlyCollectionBase", ElementType.Class);
+ ResourceManager = (Class)GetTypeNodeFor("System.Resources", "ResourceManager", ElementType.Class);
+ ResourceSet = (Class)GetTypeNodeFor("System.Resources", "ResourceSet", ElementType.Class);
+ SerializationInfo = (Class)GetTypeNodeFor("System.Runtime.Serialization", "SerializationInfo", ElementType.Class);
+ Stack = (Class)GetTypeNodeFor("System.Collections", "Stack", ElementType.Class);
+ StackOverflowException = (Class)GetTypeNodeFor("System", "StackOverflowException", ElementType.Class);
+ Stream = (Class)GetTypeNodeFor("System.IO", "Stream", ElementType.Class);
+ StreamingContext = (Struct)GetTypeNodeFor("System.Runtime.Serialization", "StreamingContext", ElementType.ValueType);
+ StringBuilder = (Class)GetTypeNodeFor("System.Text", "StringBuilder", ElementType.Class);
+ StringComparer = (Class)GetTypeNodeFor("System", "StringComparer", ElementType.Class);
+ StringComparison = GetTypeNodeFor("System", "StringComparison", ElementType.ValueType) as EnumNode;
+ SystemException = (Class)GetTypeNodeFor("System", "SystemException", ElementType.Class);
+ Thread = (Class)GetTypeNodeFor("System.Threading", "Thread", ElementType.Class);
+ WindowsImpersonationContext = (Class)GetTypeNodeFor("System.Security.Principal", "WindowsImpersonationContext", ElementType.Class);
+#endif
+#if ExtendedRuntime
+#if !NoXml && !NoRuntimeXml
+ XmlAttributeAttributeClass = (Class)GetXmlTypeNodeFor("System.Xml.Serialization", "XmlAttributeAttribute", ElementType.Class);
+ XmlChoiceIdentifierAttributeClass = (Class)GetXmlTypeNodeFor("System.Xml.Serialization", "XmlChoiceIdentifierAttribute", ElementType.Class);
+ XmlElementAttributeClass = (Class)GetXmlTypeNodeFor("System.Xml.Serialization", "XmlElementAttribute", ElementType.Class);
+ XmlIgnoreAttributeClass = (Class)GetXmlTypeNodeFor("System.Xml.Serialization", "XmlIgnoreAttribute", ElementType.Class);
+ XmlTypeAttributeClass = (Class)GetXmlTypeNodeFor("System.Xml.Serialization", "XmlTypeAttribute", ElementType.Class);
+#endif
+
+#if !NoData
+ INullable = (Interface) GetDataTypeNodeFor("System.Data.SqlTypes", "INullable", ElementType.Class);
+ SqlBinary = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlBinary", ElementType.ValueType);
+ SqlBoolean = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlBoolean", ElementType.ValueType);
+ SqlByte = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlByte", ElementType.ValueType);
+ SqlDateTime = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlDateTime", ElementType.ValueType);
+ SqlDecimal = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlDecimal", ElementType.ValueType);
+ SqlDouble = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlDouble", ElementType.ValueType);
+ SqlGuid = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlGuid", ElementType.ValueType);
+ SqlInt16 = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlInt16", ElementType.ValueType);
+ SqlInt32 = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlInt32", ElementType.ValueType);
+ SqlInt64 = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlInt64", ElementType.ValueType);
+ SqlMoney = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlMoney", ElementType.ValueType);
+ SqlSingle = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlSingle", ElementType.ValueType);
+ SqlString = (Struct)GetDataTypeNodeFor("System.Data.SqlTypes", "SqlString", ElementType.ValueType);
+ IDbConnection = (Interface)GetDataTypeNodeFor("System.Data", "IDbConnection", ElementType.Class);
+ IDbTransaction = (Interface)GetDataTypeNodeFor("System.Data", "IDbTransaction", ElementType.Class);
+ IsolationLevel = GetDataTypeNodeFor("System.Data", "IsolationLevel", ElementType.ValueType) as EnumNode;
+#endif
+#if CCINamespace
+ const string CciNs = "Microsoft.Cci";
+ const string ContractsNs = "Microsoft.Contracts";
+ const string CompilerGuardsNs = "Microsoft.Contracts";
+#else
+ const string CciNs = "System.Compiler";
+ const string ContractsNs = "Microsoft.Contracts";
+ const string CompilerGuardsNs = "Microsoft.Contracts";
+#endif
+ const string GuardsNs = "Microsoft.Contracts";
+ AnonymousAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "AnonymousAttribute", ElementType.Class);
+ AnonymityEnum = GetCompilerRuntimeTypeNodeFor(CciNs, "Anonymity", ElementType.ValueType);
+ ComposerAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "ComposerAttribute", ElementType.Class);
+ CustomVisitorAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "CustomVisitorAttribute", ElementType.Class);
+ TemplateAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "TemplateAttribute", ElementType.Class);
+ TemplateInstanceAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "TemplateInstanceAttribute", ElementType.Class);
+ UnmanagedStructTemplateParameterAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "UnmanagedStructTemplateParameterAttribute", ElementType.Class);
+ TemplateParameterFlagsAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "TemplateParameterFlagsAttribute", ElementType.Class);
+#if !WHIDBEYwithGenerics
+ GenericArrayToIEnumerableAdapter = (Class)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "ArrayToIEnumerableAdapter", 1, ElementType.Class);
+#endif
+ GenericBoxed = (Struct)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "Boxed", 1, ElementType.ValueType);
+ GenericIEnumerableToGenericIListAdapter = (Class)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "GenericIEnumerableToGenericIListAdapter", 1, ElementType.Class);
+ GenericInvariant = (Struct)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "Invariant", 1, ElementType.ValueType);
+ GenericNonEmptyIEnumerable = (Struct)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "NonEmptyIEnumerable", 1, ElementType.ValueType);
+ GenericNonNull = (Struct)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "NonNull", 1, ElementType.ValueType);
+ GenericStreamUtility = (Class)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "StreamUtility", 1, ElementType.Class);
+ GenericUnboxer = (Class)GetCompilerRuntimeTypeNodeFor("StructuralTypes", "Unboxer", 1, ElementType.Class);
+ ElementTypeAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "ElementTypeAttribute", ElementType.Class);
+ IDbTransactable = (Interface)GetCompilerRuntimeTypeNodeFor("System.Data", "IDbTransactable", ElementType.Class);
+ IAggregate = (Interface)GetCompilerRuntimeTypeNodeFor("System.Query", "IAggregate", ElementType.Class);
+ IAggregateGroup = (Interface)GetCompilerRuntimeTypeNodeFor("System.Query", "IAggregateGroup", ElementType.Class);
+ StreamNotSingletonException = (Class)GetCompilerRuntimeTypeNodeFor("System.Query", "StreamNotSingletonException", ElementType.Class);
+ SqlHint = GetCompilerRuntimeTypeNodeFor("System.Query", "SqlHint", ElementType.ValueType) as EnumNode;
+ SqlFunctions = (Class)GetCompilerRuntimeTypeNodeFor("System.Query", "SqlFunctions", ElementType.Class);
+
+ #region Contracts
+ Range = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "Range", ElementType.Class);
+ //Ordinary Exceptions
+ NoChoiceException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NoChoiceException", ElementType.Class);
+ IllegalUpcastException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "IllegalUpcastException", ElementType.Class);
+ CciMemberKind = (EnumNode)GetCompilerRuntimeTypeNodeFor(CciNs, "CciMemberKind", ElementType.ValueType);
+ CciMemberKindAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CciNs, "CciMemberKindAttribute", ElementType.Class);
+ //Checked Exceptions
+ ICheckedException = (Interface)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ICheckedException", ElementType.Class);
+ CheckedException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "CheckedException", ElementType.Class);
+ ContractMarkers = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ContractMarkers", ElementType.Class);
+ //Invariant
+ InitGuardSetsDelegate = (DelegateNode) GetCompilerRuntimeTypeNodeFor(GuardsNs, "InitGuardSetsDelegate", ElementType.Class);
+ CheckInvariantDelegate = (DelegateNode) GetCompilerRuntimeTypeNodeFor(GuardsNs, "CheckInvariantDelegate", ElementType.Class);
+ FrameGuardGetter = (DelegateNode) GetCompilerRuntimeTypeNodeFor(GuardsNs, "FrameGuardGetter", ElementType.Class);
+ ObjectInvariantException = (Class)GetCompilerRuntimeTypeNodeFor("Microsoft.Contracts", "ObjectInvariantException", ElementType.Class);
+ ThreadConditionDelegate = (DelegateNode) GetCompilerRuntimeTypeNodeFor(GuardsNs, "ThreadConditionDelegate", ElementType.Class);
+ GuardThreadStart = (DelegateNode) GetCompilerRuntimeTypeNodeFor(GuardsNs, "GuardThreadStart", ElementType.Class);
+ Guard = (Class) GetCompilerRuntimeTypeNodeFor(GuardsNs, "Guard", ElementType.Class);
+ ThreadStart = (DelegateNode) GetTypeNodeFor("System.Threading", "ThreadStart", ElementType.Class);
+ AssertHelpers = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "AssertHelpers", ElementType.Class);
+ #region Exceptions
+ UnreachableException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "UnreachableException", ElementType.Class);
+ ContractException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ContractException", ElementType.Class);
+ NullTypeException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NullTypeException", ElementType.Class);
+ AssertException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "AssertException", ElementType.Class);
+ AssumeException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "AssumeException", ElementType.Class);
+ InvalidContractException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "InvalidContractException", ElementType.Class);
+ RequiresException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "RequiresException", ElementType.Class);
+ EnsuresException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "EnsuresException", ElementType.Class);
+ ModifiesException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ModifiesException", ElementType.Class);
+ ThrowsException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ThrowsException", ElementType.Class);
+ DoesException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "DoesException", ElementType.Class);
+ InvariantException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "InvariantException", ElementType.Class);
+ ContractMarkerException = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ContractMarkerException", ElementType.Class);
+ #endregion
+ #region Attributes
+ AdditiveAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "AdditiveAttribute", ElementType.Class);
+ InsideAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "InsideAttribute", ElementType.Class);
+ PureAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "PureAttribute", ElementType.Class);
+ ConfinedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "ConfinedAttribute", ElementType.Class);
+
+ #region modelfield attributes and exceptions
+ ModelfieldContractAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ModelfieldContractAttribute", ElementType.Class);
+ ModelfieldAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ModelfieldAttribute", ElementType.Class);
+ SatisfiesAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "SatisfiesAttribute", ElementType.Class);
+ ModelfieldException = (Class)GetCompilerRuntimeTypeNodeFor("Microsoft.Contracts", "ModelfieldException", ElementType.Class);
+ #endregion
+
+ /* Diego's Attributes for Purity and WriteEffects */
+ OnceAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "OnceAttribute", ElementType.Class);
+ WriteConfinedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "WriteConfinedAttribute", ElementType.Class);
+ GlobalReadAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "GlobalReadAttribute", ElementType.Class);
+ GlobalWriteAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "GlobalWriteAttribute", ElementType.Class);
+ GlobalAccessAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "GlobalAccessAttribute", ElementType.Class);
+ FreshAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "FreshAttribute", ElementType.Class);
+ EscapesAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "EscapesAttribute", ElementType.Class);
+ /* */
+
+ StateIndependentAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "StateIndependentAttribute", ElementType.Class);
+ SpecPublicAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "SpecPublicAttribute", ElementType.Class);
+ SpecProtectedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "SpecProtectedAttribute", ElementType.Class);
+ SpecInternalAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "SpecInternalAttribute", ElementType.Class);
+
+ OwnedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "OwnedAttribute", ElementType.Class);
+ RepAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "RepAttribute", ElementType.Class);
+ PeerAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "PeerAttribute", ElementType.Class);
+ CapturedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "CapturedAttribute", ElementType.Class);
+ LockProtectedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "LockProtectedAttribute", ElementType.Class);
+ RequiresLockProtectedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "RequiresLockProtectedAttribute", ElementType.Class);
+ ImmutableAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "ImmutableAttribute", ElementType.Class);
+ RequiresImmutableAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "RequiresImmutableAttribute", ElementType.Class);
+ RequiresCanWriteAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "RequiresCanWriteAttribute", ElementType.Class);
+
+ ModelAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ModelAttribute", ElementType.Class);
+ RequiresAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "RequiresAttribute", ElementType.Class);
+ EnsuresAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "EnsuresAttribute", ElementType.Class);
+ ModifiesAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ModifiesAttribute", ElementType.Class);
+ HasWitnessAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "HasWitnessAttribute", ElementType.Class);
+ InferredReturnValueAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "InferredReturnValueAttribute", ElementType.Class);
+ ThrowsAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ThrowsAttribute", ElementType.Class);
+ DoesAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "DoesAttribute", ElementType.Class);
+ InvariantAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "InvariantAttribute", ElementType.Class);
+ NoDefaultActivityAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "NoDefaultActivityAttribute", ElementType.Class);
+ NoDefaultContractAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "NoDefaultContractAttribute", ElementType.Class);
+ ReaderAttribute = (Class)GetCompilerRuntimeTypeNodeFor(CompilerGuardsNs, "ReaderAttribute", ElementType.Class);
+
+ ShadowsAssemblyAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ShadowsAssemblyAttribute", ElementType.Class);
+ VerifyAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "VerifyAttribute", ElementType.Class);
+ DependentAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "DependentAttribute", ElementType.Class);
+ ElementsRepAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ElementsRepAttribute", ElementType.Class);
+ ElementsPeerAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ElementsPeerAttribute", ElementType.Class);
+ ElementAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ElementAttribute", ElementType.Class);
+ ElementCollectionAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ElementCollectionAttribute", ElementType.Class);
+ RecursionTerminationAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "RecursionTerminationAttribute", ElementType.Class);
+ NoReferenceComparisonAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "NoReferenceComparisonAttribute", ElementType.Class);
+ ResultNotNewlyAllocatedAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "ResultNotNewlyAllocatedAttribute", ElementType.Class);
+ #endregion
+ #endregion
+#endif
+ SystemTypes.Initialized = true;
+ object dummy = TargetPlatform.AssemblyReferenceFor; //Force selection of target platform
+ if (dummy == null) return;
+ }
+ private static void ClearStatics()
+ {
+ AttributeUsageAttribute = null;
+ ConditionalAttribute = null;
+ DefaultMemberAttribute = null;
+ InternalsVisibleToAttribute = null;
+ ObsoleteAttribute = null;
+
+ GenericICollection = null;
+ GenericIEnumerable = null;
+ GenericIList = null;
+ ICloneable = null;
+ ICollection = null;
+ IEnumerable = null;
+ IList = null;
+#if !MinimalReader
+ //Special attributes
+ AllowPartiallyTrustedCallersAttribute = null;
+ AssemblyCompanyAttribute = null;
+ AssemblyConfigurationAttribute = null;
+ AssemblyCopyrightAttribute = null;
+ AssemblyCultureAttribute = null;
+ AssemblyDelaySignAttribute = null;
+ AssemblyDescriptionAttribute = null;
+ AssemblyFileVersionAttribute = null;
+ AssemblyFlagsAttribute = null;
+ AssemblyInformationalVersionAttribute = null;
+ AssemblyKeyFileAttribute = null;
+ AssemblyKeyNameAttribute = null;
+ AssemblyProductAttribute = null;
+ AssemblyTitleAttribute = null;
+ AssemblyTrademarkAttribute = null;
+ AssemblyVersionAttribute = null;
+ ClassInterfaceAttribute = null;
+ CLSCompliantAttribute = null;
+ ComImportAttribute = null;
+ ComRegisterFunctionAttribute = null;
+ ComSourceInterfacesAttribute = null;
+ ComUnregisterFunctionAttribute = null;
+ ComVisibleAttribute = null;
+ DebuggableAttribute = null;
+ DebuggerHiddenAttribute = null;
+ DebuggerStepThroughAttribute = null;
+ DebuggingModes = null;
+ DllImportAttribute = null;
+ FieldOffsetAttribute = null;
+ FlagsAttribute = null;
+ GuidAttribute = null;
+ ImportedFromTypeLibAttribute = null;
+ InAttribute = null;
+ IndexerNameAttribute = null;
+ InterfaceTypeAttribute = null;
+ MethodImplAttribute = null;
+ NonSerializedAttribute = null;
+ OptionalAttribute = null;
+ OutAttribute = null;
+ ParamArrayAttribute = null;
+ RuntimeCompatibilityAttribute = null;
+ SatelliteContractVersionAttribute = null;
+ SerializableAttribute = null;
+ SecurityAttribute = null;
+ SecurityCriticalAttribute = null;
+ SecurityTransparentAttribute = null;
+ SecurityTreatAsSafeAttribute = null;
+ STAThreadAttribute = null;
+ StructLayoutAttribute = null;
+ SuppressMessageAttribute = null;
+ SuppressUnmanagedCodeSecurityAttribute = null;
+ SecurityAction = null;
+
+ //Classes need for System.TypeCode
+ DBNull = null;
+ DateTime = null;
+ TimeSpan = null;
+
+ //Classes and interfaces used by the Framework
+ Activator = null;
+ AppDomain = null;
+ ApplicationException = null;
+ ArgumentException = null;
+ ArgumentNullException = null;
+ ArgumentOutOfRangeException = null;
+ ArrayList = null;
+ AsyncCallback = null;
+ Assembly = null;
+ CodeAccessPermission = null;
+ CollectionBase = null;
+ CultureInfo = null;
+ DictionaryBase = null;
+ DictionaryEntry = null;
+ DuplicateWaitObjectException = null;
+ Environment = null;
+ EventArgs = null;
+ ExecutionEngineException = null;
+ GenericArraySegment = null;
+#if !WHIDBEYwithGenerics
+ GenericArrayToIEnumerableAdapter = null;
+#endif
+ GenericDictionary = null;
+ GenericIComparable = null;
+ GenericIComparer = null;
+ GenericIDictionary = null;
+ GenericIEnumerator = null;
+ GenericKeyValuePair = null;
+ GenericList = null;
+ GenericNullable = null;
+ GenericQueue = null;
+ GenericSortedDictionary = null;
+ GenericStack = null;
+ GC = null;
+ Guid = null;
+ __HandleProtector = null;
+ HandleRef = null;
+ Hashtable = null;
+ IASyncResult = null;
+ IComparable = null;
+ IDictionary = null;
+ IComparer = null;
+ IDisposable = null;
+ IEnumerator = null;
+ IFormatProvider = null;
+ IHashCodeProvider = null;
+ IMembershipCondition = null;
+ IndexOutOfRangeException = null;
+ InvalidCastException = null;
+ InvalidOperationException = null;
+ IPermission = null;
+ ISerializable = null;
+ IStackWalk = null;
+ Marshal = null;
+ MarshalByRefObject = null;
+ MemberInfo = null;
+ NativeOverlapped = null;
+ Monitor = null;
+ NotSupportedException = null;
+ NullReferenceException = null;
+ OutOfMemoryException = null;
+ ParameterInfo = null;
+ Queue = null;
+ ReadOnlyCollectionBase = null;
+ ResourceManager = null;
+ ResourceSet = null;
+ SerializationInfo = null;
+ Stack = null;
+ StackOverflowException = null;
+ Stream = null;
+ StreamingContext = null;
+ StringBuilder = null;
+ StringComparer = null;
+ StringComparison = null;
+ SystemException = null;
+ Thread = null;
+ WindowsImpersonationContext = null;
+#endif
+#if ExtendedRuntime
+ AnonymousAttribute = null;
+ AnonymityEnum = null;
+ ComposerAttribute = null;
+ CustomVisitorAttribute = null;
+ TemplateAttribute = null;
+ TemplateInstanceAttribute = null;
+ UnmanagedStructTemplateParameterAttribute = null;
+ TemplateParameterFlagsAttribute = null;
+ GenericBoxed = null;
+ GenericIEnumerableToGenericIListAdapter = null;
+ GenericInvariant = null;
+ GenericNonEmptyIEnumerable = null;
+ GenericNonNull = null;
+ GenericStreamUtility = null;
+ GenericUnboxer = null;
+ ElementTypeAttribute = null;
+ IDbTransactable = null;
+ IAggregate = null;
+ IAggregateGroup = null;
+ StreamNotSingletonException = null;
+ SqlHint = null;
+ SqlFunctions = null;
+ XmlAttributeAttributeClass = null;
+ XmlChoiceIdentifierAttributeClass = null;
+ XmlElementAttributeClass = null;
+ XmlIgnoreAttributeClass = null;
+ XmlTypeAttributeClass = null;
+ INullable = null;
+ SqlBinary = null;
+ SqlBoolean = null;
+ SqlByte = null;
+ SqlDateTime = null;
+ SqlDecimal = null;
+ SqlDouble = null;
+ SqlGuid = null;
+ SqlInt16 = null;
+ SqlInt32 = null;
+ SqlInt64 = null;
+ SqlMoney = null;
+ SqlSingle = null;
+ SqlString = null;
+ IDbConnection = null;
+ IDbTransaction = null;
+ IsolationLevel = null;
+
+ //OrdinaryExceptions
+ NoChoiceException = null;
+ IllegalUpcastException = null;
+ //NonNull
+ Range = null;
+ //Invariants
+ InitGuardSetsDelegate = null;
+ CheckInvariantDelegate = null;
+ ObjectInvariantException = null;
+ ThreadConditionDelegate = null;
+ GuardThreadStart = null;
+ Guard = null;
+ ContractMarkers = null;
+ //IReduction = null;
+ AssertHelpers = null;
+ ThreadStart = null;
+ //CheckedExceptions
+ ICheckedException = null;
+ CheckedException = null;
+
+ // Contracts
+ UnreachableException = null;
+ ContractException = null;
+ NullTypeException = null;
+ AssertException = null;
+ AssumeException = null;
+ InvalidContractException = null;
+ RequiresException = null;
+ EnsuresException = null;
+ ModifiesException = null;
+ ThrowsException = null;
+ DoesException = null;
+ InvariantException = null;
+ ContractMarkerException = null;
+
+ AdditiveAttribute = null;
+ InsideAttribute = null;
+ SpecPublicAttribute = null;
+ SpecProtectedAttribute = null;
+ SpecInternalAttribute = null;
+ PureAttribute = null;
+ OwnedAttribute = null;
+ RepAttribute = null;
+ PeerAttribute = null;
+ CapturedAttribute = null;
+ LockProtectedAttribute = null;
+ RequiresLockProtectedAttribute = null;
+ ImmutableAttribute = null;
+ RequiresImmutableAttribute = null;
+ RequiresCanWriteAttribute = null;
+ StateIndependentAttribute = null;
+ ConfinedAttribute = null;
+ ModelfieldContractAttribute = null;
+ ModelfieldAttribute = null;
+ SatisfiesAttribute = null;
+ ModelfieldException = null;
+
+ /* Diego's Attributes for Purity Analysis and Write effects */
+ OnceAttribute = null;
+ WriteConfinedAttribute = null;
+ GlobalReadAttribute = null;
+ GlobalWriteAttribute = null;
+ GlobalAccessAttribute = null;
+ FreshAttribute = null;
+ EscapesAttribute = null;
+ /* */
+
+ ModelAttribute = null;
+ RequiresAttribute = null;
+ EnsuresAttribute = null;
+ ModifiesAttribute = null;
+ HasWitnessAttribute = null;
+ InferredReturnValueAttribute = null;
+ ThrowsAttribute = null;
+ DoesAttribute = null;
+ InvariantAttribute = null;
+ NoDefaultActivityAttribute = null;
+ NoDefaultContractAttribute = null;
+ ReaderAttribute = null;
+ ShadowsAssemblyAttribute = null;
+ VerifyAttribute = null;
+ DependentAttribute = null;
+ ElementsRepAttribute = null;
+ ElementsPeerAttribute = null;
+ ElementAttribute = null;
+ ElementCollectionAttribute = null;
+ RecursionTerminationAttribute = null;
+ NoReferenceComparisonAttribute = null;
+ ResultNotNewlyAllocatedAttribute = null;
+ noHeapAllocationAttribute = null;
+#endif
+ }
+
+#if !NoData && !ROTOR
+ private static AssemblyNode/*!*/ GetSystemDataAssembly(bool doNotLockFile, bool getDebugInfo)
+ {
+ System.Reflection.AssemblyName aName = typeof(System.Data.IDataReader).Module.Assembly.GetName();
+ Identifier SystemDataId = Identifier.For(aName.Name);
+ AssemblyReference aref = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[SystemDataId.UniqueIdKey];
+ if (aref == null)
+ {
+ aref = new AssemblyReference();
+ aref.Name = aName.Name;
+ aref.PublicKeyOrToken = aName.GetPublicKeyToken();
+ aref.Version = TargetPlatform.TargetVersion;
+ TargetPlatform.AssemblyReferenceFor[SystemDataId.UniqueIdKey] = aref;
+ }
+ if (SystemDataAssemblyLocation.Location == null || SystemDataAssemblyLocation.Location.Length == 0)
+ SystemDataAssemblyLocation.Location = typeof(System.Data.IDataReader).Module.Assembly.Location;
+ if (aref.assembly == null) aref.Location = SystemDataAssemblyLocation.Location;
+ return aref.assembly = AssemblyNode.GetAssembly(aref);
+ }
+#endif
+#if !NoXml && !NoRuntimeXml
+ private static AssemblyNode/*!*/ GetSystemXmlAssembly(bool doNotLockFile, bool getDebugInfo)
+ {
+ System.Reflection.AssemblyName aName = typeof(System.Xml.XmlNode).Module.Assembly.GetName();
+ Identifier SystemXmlId = Identifier.For(aName.Name);
+ AssemblyReference aref = (AssemblyReference)TargetPlatform.AssemblyReferenceFor[SystemXmlId.UniqueIdKey];
+ if (aref == null)
+ {
+ aref = new AssemblyReference();
+ aref.Name = aName.Name;
+ aref.PublicKeyOrToken = aName.GetPublicKeyToken();
+ aref.Version = TargetPlatform.TargetVersion;
+ TargetPlatform.AssemblyReferenceFor[SystemXmlId.UniqueIdKey] = aref;
+ }
+ if (SystemXmlAssemblyLocation.Location == null || SystemXmlAssemblyLocation.Location.Length == 0)
+ SystemXmlAssemblyLocation.Location = typeof(System.Xml.XmlNode).Module.Assembly.Location;
+ if (aref.assembly == null) aref.Location = SystemXmlAssemblyLocation.Location;
+ return aref.assembly = AssemblyNode.GetAssembly(aref);
+ }
+#endif
+ private static TypeNode/*!*/ GetGenericRuntimeTypeNodeFor(string/*!*/ nspace, string/*!*/ name, int numParams, ElementType typeCode)
+ {
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0) name = name + TargetPlatform.GenericTypeNamesMangleChar + numParams;
+#if ExtendedRuntime
+ if (TargetPlatform.TargetVersion != null && TargetPlatform.TargetVersion.Major == 1 && TargetPlatform.TargetVersion.Minor < 2)
+ return SystemTypes.GetCompilerRuntimeTypeNodeFor(nspace, name, typeCode);
+ else
+#endif
+ return SystemTypes.GetTypeNodeFor(nspace, name, typeCode);
+ }
+ private static TypeNode/*!*/ GetTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode)
+ {
+ TypeNode result = null;
+ if (SystemAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+#if ExtendedRuntime
+ private static TypeNode/*!*/ GetCompilerRuntimeTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode) {
+ return SystemTypes.GetCompilerRuntimeTypeNodeFor(nspace, name, 0, typeCode);
+ }
+ private static TypeNode/*!*/ GetCompilerRuntimeTypeNodeFor(string/*!*/ nspace, string/*!*/ name, int numParams, ElementType typeCode) {
+ if (TargetPlatform.GenericTypeNamesMangleChar != 0 && numParams > 0)
+ name = name + TargetPlatform.GenericTypeNamesMangleChar + numParams;
+ TypeNode result = null;
+ if (SystemCompilerRuntimeAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemCompilerRuntimeAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemCompilerRuntimeAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+#if !NoData
+ private static TypeNode/*!*/ GetDataTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode) {
+ TypeNode result = null;
+ if (SystemDataAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemDataAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemDataAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+#endif
+#if !NoXml && !NoRuntimeXml
+ private static TypeNode/*!*/ GetXmlTypeNodeFor(string/*!*/ nspace, string/*!*/ name, ElementType typeCode) {
+ TypeNode result = null;
+ if (SystemXmlAssembly == null)
+ Debug.Assert(false);
+ else
+ result = SystemXmlAssembly.GetType(Identifier.For(nspace), Identifier.For(name));
+ if (result == null) result = CoreSystemTypes.GetDummyTypeNode(SystemXmlAssembly, nspace, name, typeCode);
+ result.typeCode = typeCode;
+ return result;
+ }
+#endif
+#endif
+ }
+}
diff --git a/tools/Sandcastle/Source/CCI/Unstacker.cs b/tools/Sandcastle/Source/CCI/Unstacker.cs
new file mode 100644
index 0000000..49d88ab
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Unstacker.cs
@@ -0,0 +1,383 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !MinimalReader || !NoWriter
+using System;
+using System.Collections;
+using System.Diagnostics;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ /// <summary>
+ /// Walks a normalized IR, removing push, pop and dup instructions, replacing them with references to local variables.
+ /// Requires all Blocks to be basic blocks. I.e. any transfer statement is always the last statement in a block.
+ /// (This precondition is established by Reader but not by Normalizer.)
+ /// </summary>
+ public class Unstacker : StandardVisitor
+ {
+ private TrivialHashtable/*!*/ SucessorBlock = new TrivialHashtable();
+ private TrivialHashtable/*!*/ StackLocalsAtEntry = new TrivialHashtable();
+ private LocalsStack/*!*/ localsStack = new LocalsStack();
+
+ public Unstacker()
+ {
+ //^ base();
+ }
+
+ public override Statement VisitAssignmentStatement(AssignmentStatement assignment)
+ {
+ if (assignment == null) return null;
+ assignment.Source = this.VisitExpression(assignment.Source);
+ assignment.Target = this.VisitTargetExpression(assignment.Target);
+ return assignment;
+ }
+ public override Expression VisitBinaryExpression(BinaryExpression binaryExpression)
+ {
+ if (binaryExpression == null) return null;
+ binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2);
+ binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1);
+ if (binaryExpression.Type == null) binaryExpression.Type = binaryExpression.Operand1.Type; //Hack: need proper inferencing
+ return binaryExpression;
+ }
+ public override Block VisitBlock(Block block)
+ {
+ if (block == null) return null;
+ LocalsStack stackLocalsAtEntry = (LocalsStack)this.StackLocalsAtEntry[block.UniqueKey];
+ if (stackLocalsAtEntry == null)
+ {
+ //Unreachable code, or the very first block
+ stackLocalsAtEntry = new LocalsStack();
+ }
+ this.localsStack = stackLocalsAtEntry.Clone();
+ base.VisitBlock(block);
+ Block successor = (Block)this.SucessorBlock[block.UniqueKey];
+ if (successor != null)
+ {
+ //Dropping off into successor.
+ LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[successor.UniqueKey];
+ if (targetStack != null && targetStack.top >= 0)
+ {
+ //Another predecessor block has already decided what the stack for the successor block is going to look like.
+ //Reconcile the stack from this block with the stack expected by the successor block.
+ this.localsStack.Transfer(targetStack, block.Statements);
+ }
+ else
+ {
+ this.StackLocalsAtEntry[successor.UniqueKey] = this.localsStack;
+ }
+ }
+ return block;
+ }
+ public override Statement VisitBranch(Branch branch)
+ {
+ if (branch == null) return null;
+ if (branch.Target == null) return null;
+ branch.Condition = this.VisitExpression(branch.Condition);
+ int n = this.localsStack.top + 1;
+ LocalsStack targetStack = (LocalsStack)this.StackLocalsAtEntry[branch.Target.UniqueKey];
+ if (targetStack == null)
+ {
+ this.StackLocalsAtEntry[branch.Target.UniqueKey] = this.localsStack.Clone();
+ return branch;
+ }
+ //Target block has an entry stack that is different from the current stack. Need to copy stack before branching.
+ if (n <= 0) return branch; //Empty stack, no need to copy
+ StatementList statements = new StatementList(n + 1);
+ this.localsStack.Transfer(targetStack, statements);
+ statements.Add(branch);
+ return new Block(statements);
+ }
+ public override Statement VisitSwitchInstruction(SwitchInstruction switchInstruction)
+ {
+ if (switchInstruction == null) return null;
+ switchInstruction.Expression = this.VisitExpression(switchInstruction.Expression);
+ for (int i = 0, n = switchInstruction.Targets == null ? 0 : switchInstruction.Targets.Count; i < n; i++)
+ {
+ Block target = switchInstruction.Targets[i];
+ if (target == null) continue;
+ this.StackLocalsAtEntry[target.UniqueKey] = this.localsStack.Clone();
+ }
+ return switchInstruction;
+ }
+ public override ExpressionList VisitExpressionList(ExpressionList expressions)
+ {
+ if (expressions == null) return null;
+ for (int i = expressions.Count - 1; i >= 0; i--)
+ expressions[i] = this.VisitExpression(expressions[i]);
+ return expressions;
+ }
+ public override Statement VisitExpressionStatement(ExpressionStatement statement)
+ {
+ if (statement == null) return null;
+ Expression e = statement.Expression = this.VisitExpression(statement.Expression);
+ if (e == null || e.Type == CoreSystemTypes.Void) return statement;
+ if (e.NodeType == NodeType.Dup) return this.localsStack.Dup();
+ return this.localsStack.Push(e);
+ }
+ public override Expression VisitExpression(Expression expression)
+ {
+ if (expression == null) return null;
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ case NodeType.Arglist:
+ return expression;
+ case NodeType.Pop:
+ UnaryExpression uex = expression as UnaryExpression;
+ if (uex != null)
+ {
+ Expression e = uex.Operand = this.VisitExpression(uex.Operand);
+ if (e == null) return null;
+ uex.Type = CoreSystemTypes.Void;
+ return uex;
+ }
+ return this.localsStack.Pop();
+ default:
+ return (Expression)this.Visit(expression);
+ }
+ }
+ public override Expression VisitIndexer(Indexer indexer)
+ {
+ if (indexer == null) return null;
+ indexer.Operands = this.VisitExpressionList(indexer.Operands);
+ indexer.Object = this.VisitExpression(indexer.Object);
+ return indexer;
+ }
+ public override Method VisitMethod(Method method)
+ {
+ // body might not have been materialized, so make sure we do that first!
+ Block body = method.Body;
+
+ if (method == null) return null;
+ BlockSorter blockSorter = new BlockSorter();
+ BlockList sortedBlocks = blockSorter.SortedBlocks;
+ this.SucessorBlock = blockSorter.SuccessorBlock;
+ this.StackLocalsAtEntry = new TrivialHashtable();
+ this.localsStack = new LocalsStack();
+ ExceptionHandlerList ehandlers = method.ExceptionHandlers;
+ for (int i = 0, n = ehandlers == null ? 0 : ehandlers.Count; i < n; i++)
+ {
+ ExceptionHandler ehandler = ehandlers[i];
+ if (ehandler == null) continue;
+ Block handlerStart = ehandler.HandlerStartBlock;
+ if (handlerStart == null) continue;
+ LocalsStack lstack = new LocalsStack();
+ this.StackLocalsAtEntry[handlerStart.UniqueKey] = lstack;
+ if (ehandler.HandlerType == NodeType.Catch)
+ {
+ lstack.exceptionHandlerType = CoreSystemTypes.Object;
+ if (ehandler.FilterType != null) lstack.exceptionHandlerType = ehandler.FilterType;
+ }
+ else if (ehandler.HandlerType == NodeType.Filter)
+ {
+ lstack.exceptionHandlerType = CoreSystemTypes.Object;
+ if (ehandler.FilterExpression != null)
+ {
+ lstack = new LocalsStack();
+ lstack.exceptionHandlerType = CoreSystemTypes.Object;
+ this.StackLocalsAtEntry[ehandler.FilterExpression.UniqueKey] = lstack;
+ }
+ }
+ }
+ blockSorter.VisitMethodBody(body);
+ for (int i = 0, n = sortedBlocks.Count; i < n; i++)
+ {
+ Block b = sortedBlocks[i];
+ if (b == null) { Debug.Assert(false); continue; }
+ this.VisitBlock(b);
+ }
+ return method;
+ }
+ public override Expression VisitMethodCall(MethodCall call)
+ {
+ if (call == null) return null;
+ call.Operands = this.VisitExpressionList(call.Operands);
+ call.Callee = this.VisitExpression(call.Callee);
+ return call;
+ }
+ public override Expression VisitTernaryExpression(TernaryExpression expression)
+ {
+ if (expression == null) return null;
+ expression.Operand3 = this.VisitExpression(expression.Operand3);
+ expression.Operand2 = this.VisitExpression(expression.Operand2);
+ expression.Operand1 = this.VisitExpression(expression.Operand1);
+ return expression;
+ }
+
+ private class LocalsStack
+ {
+ private Local[]/*!*/ elements;
+ internal int top = -1;
+ internal TypeNode exceptionHandlerType;
+
+ private void Grow()
+ {
+ int n = this.elements.Length;
+ Local[] newElements = new Local[n + 8];
+ for (int i = 0; i < n; i++) newElements[i] = this.elements[i];
+ this.elements = newElements;
+ }
+ internal LocalsStack()
+ {
+ this.elements = new Local[8];
+ //^ base();
+ }
+ private LocalsStack(LocalsStack/*!*/ other)
+ {
+ this.top = other.top;
+ this.exceptionHandlerType = other.exceptionHandlerType;
+ Local[] otherElements = other.elements;
+ int n = otherElements.Length;
+ Local[] elements = this.elements = new Local[n];
+ //^ base();
+ n = this.top + 1;
+ for (int i = 0; i < n; i++)
+ elements[i] = otherElements[i];
+ }
+ internal LocalsStack/*!*/ Clone()
+ {
+ return new LocalsStack(this);
+ }
+ internal AssignmentStatement Dup()
+ {
+ int i = this.top;
+ Expression topVal;
+ if (this.top == -1 && this.exceptionHandlerType != null)
+ {
+ topVal = new Expression(NodeType.Dup, this.exceptionHandlerType);
+ }
+ else
+ {
+ Debug.Assert(i >= 0 && i < this.elements.Length);
+ topVal = this.elements[i];
+ //^ assume topVal != null;
+ }
+ Local dup = new Local(topVal.Type);
+ if ((i = ++this.top) >= this.elements.Length) this.Grow();
+ this.elements[i] = dup;
+ return new AssignmentStatement(dup, topVal);
+ }
+ internal AssignmentStatement Push(Expression/*!*/ expr)
+ {
+ //Debug.Assert(expr != null && expr.Type != null);
+ int i = ++this.top;
+ Debug.Assert(i >= 0);
+ if (i >= this.elements.Length) this.Grow();
+ Local loc = this.elements[i];
+ if (loc == null || loc.Type != expr.Type)
+ this.elements[i] = loc = new Local(expr.Type);
+ return new AssignmentStatement(loc, expr);
+ }
+ internal Expression Pop()
+ {
+ if (this.top == -1 && this.exceptionHandlerType != null)
+ {
+ TypeNode t = this.exceptionHandlerType;
+ this.exceptionHandlerType = null;
+ return new Expression(NodeType.Pop, t);
+ }
+ int i = this.top--;
+ Debug.Assert(i >= 0 && i < this.elements.Length);
+ return this.elements[i];
+ }
+ internal void Transfer(LocalsStack/*!*/ targetStack, StatementList/*!*/ statements)
+ {
+ Debug.Assert(targetStack != null);
+ if (targetStack == this) return;
+ int n = this.top;
+ Debug.Assert(n == targetStack.top);
+ for (int i = 0; i <= n; i++)
+ {
+ Local sloc = this.elements[i];
+ Local tloc = targetStack.elements[i];
+ if (sloc == tloc) continue;
+ Debug.Assert(sloc != null && tloc != null);
+ statements.Add(new AssignmentStatement(tloc, sloc));
+ }
+ }
+ }
+ private class BlockSorter : StandardVisitor
+ {
+ private TrivialHashtable/*!*/ VisitedBlocks = new TrivialHashtable();
+ private TrivialHashtable/*!*/ BlocksThatDropThrough = new TrivialHashtable();
+ private bool lastBranchWasUnconditional = false;
+ internal BlockList/*!*/ SortedBlocks = new BlockList();
+ internal TrivialHashtable/*!*/ SuccessorBlock = new TrivialHashtable();
+
+ internal BlockSorter()
+ {
+ //^ base();
+ }
+
+ internal void VisitMethodBody(Block body)
+ {
+ if (body == null) return;
+ StatementList statements = body.Statements;
+ Block previousBlock = null;
+ for (int i = 0, n = statements.Count; i < n; i++)
+ {
+ Block b = statements[i] as Block;
+ if (b == null) { Debug.Assert(false); continue; }
+ if (previousBlock != null && this.BlocksThatDropThrough[previousBlock.UniqueKey] != null)
+ {
+ this.SuccessorBlock[previousBlock.UniqueKey] = b;
+ }
+ this.VisitBlock(b);
+ previousBlock = b;
+ }
+ }
+ public override Block VisitBlock(Block block)
+ {
+ if (block == null) return null;
+ if (this.VisitedBlocks[block.UniqueKey] != null)
+ {
+ return block;
+ }
+ this.VisitedBlocks[block.UniqueKey] = block;
+ this.SortedBlocks.Add(block);
+ this.lastBranchWasUnconditional = false;
+ base.VisitBlock(block);
+ if (!this.lastBranchWasUnconditional)
+ this.BlocksThatDropThrough[block.UniqueKey] = block;
+ return block;
+ }
+ public override Statement VisitBranch(Branch branch)
+ {
+ if (branch == null) return null;
+ if (branch.Target == null) return null;
+ this.VisitBlock(branch.Target);
+ this.lastBranchWasUnconditional = branch.Condition == null;
+ return branch;
+ }
+ public override Statement VisitReturn(Return ret)
+ {
+ this.lastBranchWasUnconditional = true;
+ return ret;
+ }
+ public override Statement VisitSwitchInstruction(SwitchInstruction switchInstruction)
+ {
+ if (switchInstruction == null) return null;
+ switchInstruction.Expression = this.VisitExpression(switchInstruction.Expression);
+ for (int i = 0, n = switchInstruction.Targets == null ? 0 : switchInstruction.Targets.Count; i < n; i++)
+ {
+ Block target = switchInstruction.Targets[i];
+ if (target == null) continue;
+ this.VisitBlock(target);
+ }
+ return switchInstruction;
+ }
+ public override Statement VisitThrow(Throw Throw)
+ {
+ this.lastBranchWasUnconditional = true;
+ return Throw;
+ }
+ }
+ }
+}
+#endif
diff --git a/tools/Sandcastle/Source/CCI/Updater.cs b/tools/Sandcastle/Source/CCI/Updater.cs
new file mode 100644
index 0000000..18c015a
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Updater.cs
@@ -0,0 +1,2979 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !MinimalReader
+using System;
+using System.Diagnostics;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+ public class UpdateSpecification
+ {
+ public Node Original;
+ public Node Changes;
+ public Node Deletions;
+ public Node Insertions;
+ //TODO: source change list?
+ }
+ public class Updater
+ {
+ public static void UpdateOriginal(UpdateSpecification update)
+ {
+ if (update == null) { Debug.Assert(false); return; }
+ Updater updater = new Updater();
+ updater.Visit(update.Original, update.Changes, update.Deletions, update.Insertions);
+ }
+
+ public Updater callingVisitor;
+ public int currentSourcePositionDelta;
+ public Document currentDocument;
+
+ public Updater()
+ {
+ }
+ public Updater(Updater callingVisitor)
+ {
+ this.callingVisitor = callingVisitor;
+ }
+ public virtual Node VisitUnknownNodeType(Node node, Node changes, Node deletions, Node insertions)
+ {
+ Updater visitor = this.GetVisitorFor(node);
+ if (visitor == null) return node;
+ if (this.callingVisitor != null)
+ //Allow specialized state (unknown to this visitor) to propagate all the way down to the new visitor
+ this.callingVisitor.TransferStateTo(visitor);
+ this.TransferStateTo(visitor);
+ node = visitor.Visit(node, changes, deletions, insertions);
+ visitor.TransferStateTo(this);
+ if (this.callingVisitor != null)
+ //Propagate specialized state (unknown to this visitor) all the way up the chain
+ visitor.TransferStateTo(this.callingVisitor);
+ return node;
+ }
+ public virtual void TransferStateTo(Updater target)
+ {
+ if (target == null) return;
+ target.currentSourcePositionDelta = this.currentSourcePositionDelta;
+ }
+ public virtual Updater GetVisitorFor(Node node)
+ {
+ if (node == null) return null;
+ return (Updater)node.GetVisitorFor(this, this.GetType().Name);
+ }
+ public virtual Node Visit(Node node, Node changes, Node deletions, Node insertions)
+ {
+ if (node == null) return changes;
+ switch (node.NodeType)
+ {
+ case NodeType.AddressDereference:
+ return this.VisitAddressDereference((AddressDereference)node, changes as AddressDereference, deletions as AddressDereference, insertions as AddressDereference);
+ case NodeType.AliasDefinition:
+ return this.VisitAliasDefinition((AliasDefinition)node, changes as AliasDefinition, deletions as AliasDefinition, insertions as AliasDefinition);
+ case NodeType.AnonymousNestedFunction:
+ return this.VisitAnonymousNestedFunction((AnonymousNestedFunction)node, changes as AnonymousNestedFunction, deletions as AnonymousNestedFunction, insertions as AnonymousNestedFunction);
+ case NodeType.ApplyToAll:
+ return this.VisitApplyToAll((ApplyToAll)node, changes as ApplyToAll, deletions as ApplyToAll, insertions as ApplyToAll);
+ case NodeType.Arglist:
+ return this.VisitExpression((Expression)node, changes as Expression, deletions as Expression, insertions as Expression);
+ case NodeType.ArrayType:
+ Debug.Assert(false); return null;
+ case NodeType.Assembly:
+ return this.VisitAssembly((AssemblyNode)node, changes as AssemblyNode, deletions as AssemblyNode, insertions as AssemblyNode);
+ case NodeType.AssemblyReference:
+ return this.VisitAssemblyReference((AssemblyReference)node, changes as AssemblyReference, deletions as AssemblyReference, insertions as AssemblyReference);
+ case NodeType.Assertion:
+ return this.VisitAssertion((Assertion)node, changes as Assertion, deletions as Assertion, insertions as Assertion);
+ case NodeType.AssignmentExpression:
+ return this.VisitAssignmentExpression((AssignmentExpression)node, changes as AssignmentExpression, deletions as AssignmentExpression, insertions as AssignmentExpression);
+ case NodeType.AssignmentStatement:
+ return this.VisitAssignmentStatement((AssignmentStatement)node, changes as AssignmentStatement, deletions as AssignmentStatement, insertions as AssignmentStatement);
+ case NodeType.Attribute:
+ return this.VisitAttributeNode((AttributeNode)node, changes as AttributeNode, deletions as AttributeNode, insertions as AttributeNode);
+ case NodeType.Base:
+ return this.VisitBase((Base)node, changes as Base, deletions as Base, insertions as Base);
+ case NodeType.Block:
+ return this.VisitBlock((Block)node, changes as Block, deletions as Block, insertions as Block);
+ case NodeType.BlockExpression:
+ return this.VisitBlockExpression((BlockExpression)node, changes as BlockExpression, deletions as BlockExpression, insertions as BlockExpression);
+ case NodeType.Branch:
+ Debug.Assert(false); return null;
+ case NodeType.Compilation:
+ return this.VisitCompilation((Compilation)node, changes as Compilation, deletions as Compilation, insertions as Compilation);
+ case NodeType.CompilationUnit:
+ return this.VisitCompilationUnit((CompilationUnit)node, changes as CompilationUnit, deletions as CompilationUnit, insertions as CompilationUnit);
+ case NodeType.CompilationUnitSnippet:
+ return this.VisitCompilationUnitSnippet((CompilationUnitSnippet)node, changes as CompilationUnitSnippet, deletions as CompilationUnitSnippet, insertions as CompilationUnitSnippet);
+#if ExtendedRuntime
+ case NodeType.ConstrainedType:
+ return this.VisitConstrainedType((ConstrainedType)node, changes as ConstrainedType, deletions as ConstrainedType, insertions as ConstrainedType);
+#endif
+ case NodeType.Continue:
+ return this.VisitContinue((Continue)node, changes as Continue, deletions as Continue, insertions as Continue);
+ case NodeType.CurrentClosure:
+ return this.VisitCurrentClosure((CurrentClosure)node, changes as CurrentClosure, deletions as CurrentClosure, insertions as CurrentClosure);
+ case NodeType.DebugBreak:
+ return node;
+ case NodeType.Call:
+ case NodeType.Calli:
+ case NodeType.Callvirt:
+ case NodeType.Jmp:
+ case NodeType.MethodCall:
+ return this.VisitMethodCall((MethodCall)node, changes as MethodCall, deletions as MethodCall, insertions as MethodCall);
+ case NodeType.Catch:
+ return this.VisitCatch((Catch)node, changes as Catch, deletions as Catch, insertions as Catch);
+ case NodeType.Class:
+ return this.VisitClass((Class)node, changes as Class, deletions as Class, insertions as Class);
+ case NodeType.CoerceTuple:
+ return this.VisitCoerceTuple((CoerceTuple)node, changes as CoerceTuple, deletions as CoerceTuple, insertions as CoerceTuple);
+ case NodeType.CollectionEnumerator:
+ return this.VisitCollectionEnumerator((CollectionEnumerator)node, changes as CollectionEnumerator, deletions as CollectionEnumerator, insertions as CollectionEnumerator);
+ case NodeType.Composition:
+ return this.VisitComposition((Composition)node, changes as Composition, deletions as Composition, insertions as Composition);
+ case NodeType.Construct:
+ return this.VisitConstruct((Construct)node, changes as Construct, deletions as Construct, insertions as Construct);
+ case NodeType.ConstructArray:
+ return this.VisitConstructArray((ConstructArray)node, changes as ConstructArray, deletions as ConstructArray, insertions as ConstructArray);
+ case NodeType.ConstructDelegate:
+ return this.VisitConstructDelegate((ConstructDelegate)node, changes as ConstructDelegate, deletions as ConstructDelegate, insertions as ConstructDelegate);
+ case NodeType.ConstructFlexArray:
+ return this.VisitConstructFlexArray((ConstructFlexArray)node, changes as ConstructFlexArray, deletions as ConstructFlexArray, insertions as ConstructFlexArray);
+ case NodeType.ConstructIterator:
+ return this.VisitConstructIterator((ConstructIterator)node, changes as ConstructIterator, deletions as ConstructIterator, insertions as ConstructIterator);
+ case NodeType.ConstructTuple:
+ return this.VisitConstructTuple((ConstructTuple)node, changes as ConstructTuple, deletions as ConstructTuple, insertions as ConstructTuple);
+ case NodeType.DelegateNode:
+ return this.VisitDelegateNode((DelegateNode)node, changes as DelegateNode, deletions as DelegateNode, insertions as DelegateNode);
+ case NodeType.DoWhile:
+ return this.VisitDoWhile((DoWhile)node, changes as DoWhile, deletions as DoWhile, insertions as DoWhile);
+ case NodeType.Dup:
+ return this.VisitExpression((Expression)node, changes as Expression, deletions as Expression, insertions as Expression);
+ case NodeType.EndFilter:
+ return this.VisitEndFilter((EndFilter)node, changes as EndFilter, deletions as EndFilter, insertions as EndFilter);
+ case NodeType.EndFinally:
+ return this.VisitEndFinally((EndFinally)node, changes as EndFinally, deletions as EndFinally, insertions as EndFinally);
+ case NodeType.EnumNode:
+ return this.VisitEnumNode((EnumNode)node, changes as EnumNode, deletions as EnumNode, insertions as EnumNode);
+ case NodeType.Event:
+ return this.VisitEvent((Event)node, changes as Event, deletions as Event, insertions as Event);
+ case NodeType.Exit:
+ return this.VisitExit((Exit)node, changes as Exit, deletions as Exit, insertions as Exit);
+ case NodeType.ExpressionSnippet:
+ return this.VisitExpressionSnippet((ExpressionSnippet)node, changes as ExpressionSnippet, deletions as ExpressionSnippet, insertions as ExpressionSnippet);
+ case NodeType.ExpressionStatement:
+ return this.VisitExpressionStatement((ExpressionStatement)node, changes as ExpressionStatement, deletions as ExpressionStatement, insertions as ExpressionStatement);
+ case NodeType.FaultHandler:
+ return this.VisitFaultHandler((FaultHandler)node, changes as FaultHandler, deletions as FaultHandler, insertions as FaultHandler);
+ case NodeType.Field:
+ return this.VisitField((Field)node, changes as Field, deletions as Field, insertions as Field);
+ case NodeType.FieldInitializerBlock:
+ return this.VisitFieldInitializerBlock((FieldInitializerBlock)node, changes as FieldInitializerBlock, deletions as FieldInitializerBlock, insertions as FieldInitializerBlock);
+ case NodeType.Finally:
+ return this.VisitFinally((Finally)node, changes as Finally, deletions as Finally, insertions as Finally);
+ case NodeType.Filter:
+ return this.VisitFilter((Filter)node, changes as Filter, deletions as Filter, insertions as Filter);
+ case NodeType.Fixed:
+ return this.VisitFixed((Fixed)node, changes as Fixed, deletions as Fixed, insertions as Fixed);
+ case NodeType.For:
+ return this.VisitFor((For)node, changes as For, deletions as For, insertions as For);
+ case NodeType.ForEach:
+ return this.VisitForEach((ForEach)node, changes as ForEach, deletions as ForEach, insertions as ForEach);
+ case NodeType.FunctionDeclaration:
+ return this.VisitFunctionDeclaration((FunctionDeclaration)node, changes as FunctionDeclaration, deletions as FunctionDeclaration, insertions as FunctionDeclaration);
+ case NodeType.Goto:
+ return this.VisitGoto((Goto)node, changes as Goto, deletions as Goto, insertions as Goto);
+ case NodeType.GotoCase:
+ return this.VisitGotoCase((GotoCase)node, changes as GotoCase, deletions as GotoCase, insertions as GotoCase);
+ case NodeType.Identifier:
+ return this.VisitIdentifier((Identifier)node, changes as Identifier, deletions as Identifier, insertions as Identifier);
+ case NodeType.If:
+ return this.VisitIf((If)node, changes as If, deletions as If, insertions as If);
+ case NodeType.ImplicitThis:
+ return this.VisitImplicitThis((ImplicitThis)node, changes as ImplicitThis, deletions as ImplicitThis, insertions as ImplicitThis);
+ case NodeType.Indexer:
+ return this.VisitIndexer((Indexer)node, changes as Indexer, deletions as Indexer, insertions as Indexer);
+ case NodeType.InstanceInitializer:
+ return this.VisitInstanceInitializer((InstanceInitializer)node, changes as InstanceInitializer, deletions as InstanceInitializer, insertions as InstanceInitializer);
+ case NodeType.StaticInitializer:
+ return this.VisitStaticInitializer((StaticInitializer)node, changes as StaticInitializer, deletions as StaticInitializer, insertions as StaticInitializer);
+ case NodeType.Method:
+ return this.VisitMethod((Method)node, changes as Method, deletions as Method, insertions as Method);
+ case NodeType.Interface:
+ return this.VisitInterface((Interface)node, changes as Interface, deletions as Interface, insertions as Interface);
+ case NodeType.LabeledStatement:
+ return this.VisitLabeledStatement((LabeledStatement)node, changes as LabeledStatement, deletions as LabeledStatement, insertions as LabeledStatement);
+ case NodeType.Literal:
+ return this.VisitLiteral((Literal)node, changes as Literal, deletions as Literal, insertions as Literal);
+ case NodeType.Local:
+ return this.VisitLocal((Local)node, changes as Local, deletions as Local, insertions as Local);
+ case NodeType.LocalDeclaration:
+ return this.VisitLocalDeclaration((LocalDeclaration)node, changes as LocalDeclaration, deletions as LocalDeclaration, insertions as LocalDeclaration);
+ case NodeType.LocalDeclarationsStatement:
+ return this.VisitLocalDeclarationsStatement((LocalDeclarationsStatement)node, changes as LocalDeclarationsStatement, deletions as LocalDeclarationsStatement, insertions as LocalDeclarationsStatement);
+ case NodeType.Lock:
+ return this.VisitLock((Lock)node, changes as Lock, deletions as Lock, insertions as Lock);
+ case NodeType.LRExpression:
+ return this.VisitLRExpression((LRExpression)node, changes as LRExpression, deletions as LRExpression, insertions as LRExpression);
+ case NodeType.MemberBinding:
+ return this.VisitMemberBinding((MemberBinding)node, changes as MemberBinding, deletions as MemberBinding, insertions as MemberBinding);
+ case NodeType.TemplateInstance:
+ return this.VisitTemplateInstance((TemplateInstance)node, changes as TemplateInstance, deletions as TemplateInstance, insertions as TemplateInstance);
+ case NodeType.StackAlloc:
+ return this.VisitStackAlloc((StackAlloc)node, changes as StackAlloc, deletions as StackAlloc, insertions as StackAlloc);
+ case NodeType.Module:
+ return this.VisitModule((Module)node, changes as Module, deletions as Module, insertions as Module);
+ case NodeType.ModuleReference:
+ return this.VisitModuleReference((ModuleReference)node, changes as ModuleReference, deletions as ModuleReference, insertions as ModuleReference);
+ case NodeType.NameBinding:
+ return this.VisitNameBinding((NameBinding)node, changes as NameBinding, deletions as NameBinding, insertions as NameBinding);
+ case NodeType.NamedArgument:
+ return this.VisitNamedArgument((NamedArgument)node, changes as NamedArgument, deletions as NamedArgument, insertions as NamedArgument);
+ case NodeType.Namespace:
+ return this.VisitNamespace((Namespace)node, changes as Namespace, deletions as Namespace, insertions as Namespace);
+ case NodeType.Nop:
+ return node;
+ case NodeType.OptionalModifier:
+ case NodeType.RequiredModifier:
+ return this.VisitTypeModifier((TypeModifier)node, changes as TypeModifier, deletions as TypeModifier, insertions as TypeModifier);
+ case NodeType.Parameter:
+ return this.VisitParameter((Parameter)node, changes as Parameter, deletions as Parameter, insertions as Parameter);
+ case NodeType.Pop:
+ return this.VisitExpression((Expression)node, changes as Expression, deletions as Expression, insertions as Expression);
+ case NodeType.PrefixExpression:
+ return this.VisitPrefixExpression((PrefixExpression)node, changes as PrefixExpression, deletions as PrefixExpression, insertions as PrefixExpression);
+ case NodeType.PostfixExpression:
+ return this.VisitPostfixExpression((PostfixExpression)node, changes as PostfixExpression, deletions as PostfixExpression, insertions as PostfixExpression);
+ case NodeType.Property:
+ return this.VisitProperty((Property)node, changes as Property, deletions as Property, insertions as Property);
+ case NodeType.QualifiedIdentifer:
+ return this.VisitQualifiedIdentifier((QualifiedIdentifier)node, changes as QualifiedIdentifier, deletions as QualifiedIdentifier, insertions as QualifiedIdentifier);
+ case NodeType.Rethrow:
+ case NodeType.Throw:
+ return this.VisitThrow((Throw)node, changes as Throw, deletions as Throw, insertions as Throw);
+ case NodeType.Return:
+ return this.VisitReturn((Return)node, changes as Return, deletions as Return, insertions as Return);
+ case NodeType.ResourceUse:
+ return this.VisitResourceUse((ResourceUse)node, changes as ResourceUse, deletions as ResourceUse, insertions as ResourceUse);
+ case NodeType.Repeat:
+ return this.VisitRepeat((Repeat)node, changes as Repeat, deletions as Repeat, insertions as Repeat);
+ case NodeType.SecurityAttribute:
+ return this.VisitSecurityAttribute((SecurityAttribute)node, changes as SecurityAttribute, deletions as SecurityAttribute, insertions as SecurityAttribute);
+ case NodeType.SetterValue:
+ return this.VisitSetterValue((SetterValue)node, changes as SetterValue, deletions as SetterValue, insertions as SetterValue);
+ case NodeType.StatementSnippet:
+ return this.VisitStatementSnippet((StatementSnippet)node, changes as StatementSnippet, deletions as StatementSnippet, insertions as StatementSnippet);
+ case NodeType.Struct:
+ return this.VisitStruct((Struct)node, changes as Struct, deletions as Struct, insertions as Struct);
+ case NodeType.Switch:
+ return this.VisitSwitch((Switch)node, changes as Switch, deletions as Switch, insertions as Switch);
+ case NodeType.SwitchCase:
+ return this.VisitSwitchCase((SwitchCase)node, changes as SwitchCase, deletions as SwitchCase, insertions as SwitchCase);
+ case NodeType.SwitchInstruction:
+ return this.VisitSwitchInstruction((SwitchInstruction)node, changes as SwitchInstruction, deletions as SwitchInstruction, insertions as SwitchInstruction);
+ case NodeType.Typeswitch:
+ return this.VisitTypeswitch((Typeswitch)node, changes as Typeswitch, deletions as Typeswitch, insertions as Typeswitch);
+ case NodeType.TypeswitchCase:
+ return this.VisitTypeswitchCase((TypeswitchCase)node, changes as TypeswitchCase, deletions as TypeswitchCase, insertions as TypeswitchCase);
+ case NodeType.This:
+ return this.VisitThis((This)node, changes as This, deletions as This, insertions as This);
+ case NodeType.Try:
+ return this.VisitTry((Try)node, changes as Try, deletions as Try, insertions as Try);
+#if ExtendedRuntime
+ case NodeType.TupleType:
+ return this.VisitTupleType((TupleType)node, changes as TupleType, deletions as TupleType, insertions as TupleType);
+ case NodeType.TypeAlias:
+ return this.VisitTypeAlias((TypeAlias)node, changes as TypeAlias, deletions as TypeAlias, insertions as TypeAlias);
+ case NodeType.TypeIntersection:
+ return this.VisitTypeIntersection((TypeIntersection)node, changes as TypeIntersection, deletions as TypeIntersection, insertions as TypeIntersection);
+#endif
+ case NodeType.TypeMemberSnippet:
+ return this.VisitTypeMemberSnippet((TypeMemberSnippet)node, changes as TypeMemberSnippet, deletions as TypeMemberSnippet, insertions as TypeMemberSnippet);
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ return this.VisitTypeParameter((TypeNode)node, changes as TypeNode, deletions as TypeNode, insertions as TypeNode);
+ case NodeType.TypeReference:
+ return this.VisitTypeReference((TypeReference)node, changes as TypeReference, deletions as TypeReference, insertions as TypeReference);
+#if ExtendedRuntime
+ case NodeType.TypeUnion:
+ return this.VisitTypeUnion((TypeUnion)node, changes as TypeUnion, deletions as TypeUnion, insertions as TypeUnion);
+#endif
+ case NodeType.UsedNamespace:
+ return this.VisitUsedNamespace((UsedNamespace)node, changes as UsedNamespace, deletions as UsedNamespace, insertions as UsedNamespace);
+ case NodeType.VariableDeclaration:
+ return this.VisitVariableDeclaration((VariableDeclaration)node, changes as VariableDeclaration, deletions as VariableDeclaration, insertions as VariableDeclaration);
+ case NodeType.While:
+ return this.VisitWhile((While)node, changes as While, deletions as While, insertions as While);
+ case NodeType.Yield:
+ return this.VisitYield((Yield)node, changes as Yield, deletions as Yield, insertions as Yield);
+
+ case NodeType.Conditional:
+ case NodeType.Cpblk:
+ case NodeType.Initblk:
+ return this.VisitTernaryExpression((TernaryExpression)node, changes as TernaryExpression, deletions as TernaryExpression, insertions as TernaryExpression);
+
+ case NodeType.Add:
+ case NodeType.Add_Ovf:
+ case NodeType.Add_Ovf_Un:
+ case NodeType.AddEventHandler:
+ case NodeType.And:
+ case NodeType.As:
+ case NodeType.Box:
+ case NodeType.Castclass:
+ case NodeType.Ceq:
+ case NodeType.Cgt:
+ case NodeType.Cgt_Un:
+ case NodeType.Clt:
+ case NodeType.Clt_Un:
+ case NodeType.Comma:
+ case NodeType.Div:
+ case NodeType.Div_Un:
+ case NodeType.Eq:
+ case NodeType.ExplicitCoercion:
+ case NodeType.Ge:
+ case NodeType.Gt:
+ case NodeType.Is:
+ case NodeType.Iff:
+ case NodeType.Implies:
+ case NodeType.Isinst:
+ case NodeType.Ldvirtftn:
+ case NodeType.Le:
+ case NodeType.LogicalAnd:
+ case NodeType.LogicalOr:
+ case NodeType.Lt:
+ case NodeType.Maplet:
+ case NodeType.Mkrefany:
+ case NodeType.Mul:
+ case NodeType.Mul_Ovf:
+ case NodeType.Mul_Ovf_Un:
+ case NodeType.Ne:
+ case NodeType.Or:
+ case NodeType.Range:
+ case NodeType.Refanyval:
+ case NodeType.Rem:
+ case NodeType.Rem_Un:
+ case NodeType.RemoveEventHandler:
+ case NodeType.Shl:
+ case NodeType.Shr:
+ case NodeType.Shr_Un:
+ case NodeType.Sub:
+ case NodeType.Sub_Ovf:
+ case NodeType.Sub_Ovf_Un:
+ case NodeType.Unbox:
+ case NodeType.UnboxAny:
+ case NodeType.Xor:
+ return this.VisitBinaryExpression((BinaryExpression)node, changes as BinaryExpression, deletions as BinaryExpression, insertions as BinaryExpression);
+
+ case NodeType.AddressOf:
+ case NodeType.OutAddress:
+ case NodeType.RefAddress:
+ case NodeType.Ckfinite:
+ case NodeType.Conv_I:
+ case NodeType.Conv_I1:
+ case NodeType.Conv_I2:
+ case NodeType.Conv_I4:
+ case NodeType.Conv_I8:
+ case NodeType.Conv_Ovf_I:
+ case NodeType.Conv_Ovf_I1:
+ case NodeType.Conv_Ovf_I1_Un:
+ case NodeType.Conv_Ovf_I2:
+ case NodeType.Conv_Ovf_I2_Un:
+ case NodeType.Conv_Ovf_I4:
+ case NodeType.Conv_Ovf_I4_Un:
+ case NodeType.Conv_Ovf_I8:
+ case NodeType.Conv_Ovf_I8_Un:
+ case NodeType.Conv_Ovf_I_Un:
+ case NodeType.Conv_Ovf_U:
+ case NodeType.Conv_Ovf_U1:
+ case NodeType.Conv_Ovf_U1_Un:
+ case NodeType.Conv_Ovf_U2:
+ case NodeType.Conv_Ovf_U2_Un:
+ case NodeType.Conv_Ovf_U4:
+ case NodeType.Conv_Ovf_U4_Un:
+ case NodeType.Conv_Ovf_U8:
+ case NodeType.Conv_Ovf_U8_Un:
+ case NodeType.Conv_Ovf_U_Un:
+ case NodeType.Conv_R4:
+ case NodeType.Conv_R8:
+ case NodeType.Conv_R_Un:
+ case NodeType.Conv_U:
+ case NodeType.Conv_U1:
+ case NodeType.Conv_U2:
+ case NodeType.Conv_U4:
+ case NodeType.Conv_U8:
+ case NodeType.Decrement:
+ case NodeType.DefaultValue:
+ case NodeType.Increment:
+ case NodeType.Ldftn:
+ case NodeType.Ldlen:
+ case NodeType.Ldtoken:
+ case NodeType.Localloc:
+ case NodeType.LogicalNot:
+ case NodeType.Neg:
+ case NodeType.Not:
+ case NodeType.Parentheses:
+ case NodeType.Refanytype:
+ case NodeType.Sizeof:
+ case NodeType.SkipCheck:
+ case NodeType.Typeof:
+ case NodeType.UnaryPlus:
+ return this.VisitUnaryExpression((UnaryExpression)node, changes as UnaryExpression, deletions as UnaryExpression, insertions as UnaryExpression);
+#if ExtendedRuntime
+ // query node types
+ case NodeType.QueryAggregate:
+ return this.VisitQueryAggregate((QueryAggregate)node, changes as QueryAggregate, deletions as QueryAggregate, insertions as QueryAggregate);
+ case NodeType.QueryAlias:
+ return this.VisitQueryAlias((QueryAlias)node, changes as QueryAlias, deletions as QueryAlias, insertions as QueryAlias);
+ case NodeType.QueryAll:
+ case NodeType.QueryAny:
+ return this.VisitQueryQuantifier((QueryQuantifier)node, changes as QueryQuantifier, deletions as QueryQuantifier, insertions as QueryQuantifier);
+ case NodeType.QueryAxis:
+ return this.VisitQueryAxis((QueryAxis)node, changes as QueryAxis, deletions as QueryAxis, insertions as QueryAxis);
+ case NodeType.QueryCommit:
+ return this.VisitQueryCommit((QueryCommit)node, changes as QueryCommit, deletions as QueryCommit, insertions as QueryCommit);
+ case NodeType.QueryContext:
+ return this.VisitQueryContext((QueryContext)node, changes as QueryContext, deletions as QueryContext, insertions as QueryContext);
+ case NodeType.QueryDelete:
+ return this.VisitQueryDelete((QueryDelete)node, changes as QueryDelete, deletions as QueryDelete, insertions as QueryDelete);
+ case NodeType.QueryDifference:
+ return this.VisitQueryDifference((QueryDifference)node, changes as QueryDifference, deletions as QueryDifference, insertions as QueryDifference);
+ case NodeType.QueryDistinct:
+ return this.VisitQueryDistinct((QueryDistinct)node, changes as QueryDistinct, deletions as QueryDistinct, insertions as QueryDistinct);
+ case NodeType.QueryExists:
+ return this.VisitQueryExists((QueryExists)node, changes as QueryExists, deletions as QueryExists, insertions as QueryExists);
+ case NodeType.QueryFilter:
+ return this.VisitQueryFilter((QueryFilter)node, changes as QueryFilter, deletions as QueryFilter, insertions as QueryFilter);
+ case NodeType.QueryGeneratedType:
+ return this.VisitQueryGeneratedType((QueryGeneratedType)node, changes as QueryGeneratedType, deletions as QueryGeneratedType, insertions as QueryGeneratedType);
+ case NodeType.QueryGroupBy:
+ return this.VisitQueryGroupBy((QueryGroupBy)node, changes as QueryGroupBy, deletions as QueryGroupBy, insertions as QueryGroupBy);
+ case NodeType.QueryInsert:
+ return this.VisitQueryInsert((QueryInsert)node, changes as QueryInsert, deletions as QueryInsert, insertions as QueryInsert);
+ case NodeType.QueryIntersection:
+ return this.VisitQueryIntersection((QueryIntersection)node, changes as QueryIntersection, deletions as QueryIntersection, insertions as QueryIntersection);
+ case NodeType.QueryIterator:
+ return this.VisitQueryIterator((QueryIterator)node, changes as QueryIterator, deletions as QueryIterator, insertions as QueryIterator);
+ case NodeType.QueryJoin:
+ return this.VisitQueryJoin((QueryJoin)node, changes as QueryJoin, deletions as QueryJoin, insertions as QueryJoin);
+ case NodeType.QueryLimit:
+ return this.VisitQueryLimit((QueryLimit)node, changes as QueryLimit, deletions as QueryLimit, insertions as QueryLimit);
+ case NodeType.QueryOrderBy:
+ return this.VisitQueryOrderBy((QueryOrderBy)node, changes as QueryOrderBy, deletions as QueryOrderBy, insertions as QueryOrderBy);
+ case NodeType.QueryOrderItem:
+ return this.VisitQueryOrderItem((QueryOrderItem)node, changes as QueryOrderItem, deletions as QueryOrderItem, insertions as QueryOrderItem);
+ case NodeType.QueryPosition:
+ return this.VisitQueryPosition((QueryPosition)node, changes as QueryPosition, deletions as QueryPosition, insertions as QueryPosition);
+ case NodeType.QueryProject:
+ return this.VisitQueryProject((QueryProject)node, changes as QueryProject, deletions as QueryProject, insertions as QueryProject);
+ case NodeType.QueryQuantifiedExpression:
+ return this.VisitQueryQuantifiedExpression((QueryQuantifiedExpression)node, changes as QueryQuantifiedExpression, deletions as QueryQuantifiedExpression, insertions as QueryQuantifiedExpression);
+ case NodeType.QueryRollback:
+ return this.VisitQueryRollback((QueryRollback)node, changes as QueryRollback, deletions as QueryRollback, insertions as QueryRollback);
+ case NodeType.QuerySelect:
+ return this.VisitQuerySelect((QuerySelect)node, changes as QuerySelect, deletions as QuerySelect, insertions as QuerySelect);
+ case NodeType.QuerySingleton:
+ return this.VisitQuerySingleton((QuerySingleton)node, changes as QuerySingleton, deletions as QuerySingleton, insertions as QuerySingleton);
+ case NodeType.QueryTransact:
+ return this.VisitQueryTransact((QueryTransact)node, changes as QueryTransact, deletions as QueryTransact, insertions as QueryTransact);
+ case NodeType.QueryTypeFilter:
+ return this.VisitQueryTypeFilter((QueryTypeFilter)node, changes as QueryTypeFilter, deletions as QueryTypeFilter, insertions as QueryTypeFilter);
+ case NodeType.QueryUnion:
+ return this.VisitQueryUnion((QueryUnion)node, changes as QueryUnion, deletions as QueryUnion, insertions as QueryUnion);
+ case NodeType.QueryUpdate:
+ return this.VisitQueryUpdate((QueryUpdate)node, changes as QueryUpdate, deletions as QueryUpdate, insertions as QueryUpdate);
+ case NodeType.QueryYielder:
+ return this.VisitQueryYielder((QueryYielder)node, changes as QueryYielder, deletions as QueryYielder, insertions as QueryYielder);
+#endif
+ default:
+ return this.VisitUnknownNodeType(node, changes, deletions, insertions);
+ }
+ }
+ public virtual void UpdateSourceContext(Node node, Node changes)
+ {
+ }
+ public virtual Expression VisitAddressDereference(AddressDereference addr, AddressDereference changes, AddressDereference deletions, AddressDereference insertions)
+ {
+ this.UpdateSourceContext(addr, changes);
+ if (addr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ addr.Address = this.VisitExpression(addr.Address, changes.Address, deletions.Address, insertions.Address);
+ addr.Alignment = changes.Alignment;
+ addr.Volatile = changes.Volatile;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return addr;
+ }
+ public virtual AliasDefinition VisitAliasDefinition(AliasDefinition aliasDefinition, AliasDefinition changes, AliasDefinition deletions, AliasDefinition insertions)
+ {
+ this.UpdateSourceContext(aliasDefinition, changes);
+ if (aliasDefinition == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ aliasDefinition.Alias = changes.Alias;
+ aliasDefinition.AliasedType = this.VisitTypeReference(aliasDefinition.AliasedType, changes.AliasedType, deletions.AliasedType, insertions.AliasedType);
+ aliasDefinition.AliasedExpression = changes.AliasedExpression;
+ aliasDefinition.AliasedUri = changes.AliasedUri;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return aliasDefinition;
+ }
+ public virtual AliasDefinitionList VisitAliasDefinitionList(AliasDefinitionList aliasDefinitions, AliasDefinitionList changes, AliasDefinitionList deletions, AliasDefinitionList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return aliasDefinitions;
+ int n = aliasDefinitions == null ? 0 : aliasDefinitions.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (aliasDefinitions != null)
+ for (int i = 0; i < n; i++)
+ aliasDefinitions[i] = this.VisitAliasDefinition(aliasDefinitions[i], changes[i], deletions[i], insertions[i]);
+ AliasDefinitionList result = new AliasDefinitionList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func, AnonymousNestedFunction changes, AnonymousNestedFunction deletions, AnonymousNestedFunction insertions)
+ {
+ this.UpdateSourceContext(func, changes);
+ if (func == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ func.Body = this.VisitBlock(func.Body, changes.Body, deletions.Body, insertions.Body);
+ func.Parameters = this.VisitParameterList(func.Parameters, changes.Parameters, deletions.Parameters, insertions.Parameters);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return func;
+ }
+ public virtual Expression VisitApplyToAll(ApplyToAll applyToAll, ApplyToAll changes, ApplyToAll deletions, ApplyToAll insertions)
+ {
+ this.UpdateSourceContext(applyToAll, changes);
+ if (applyToAll == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ applyToAll.Operand1 = this.VisitExpression(applyToAll.Operand1, changes.Operand1, deletions.Operand1, insertions.Operand1);
+ applyToAll.Operand2 = this.VisitExpression(applyToAll.Operand2, changes.Operand2, deletions.Operand2, insertions.Operand2);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return applyToAll;
+ }
+ public virtual AssemblyNode VisitAssembly(AssemblyNode assembly, AssemblyNode changes, AssemblyNode deletions, AssemblyNode insertions)
+ {
+ this.UpdateSourceContext(assembly, changes);
+ if (assembly == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ assembly.AssemblyReferences = this.VisitAssemblyReferenceList(assembly.AssemblyReferences, changes.AssemblyReferences, deletions.AssemblyReferences, insertions.AssemblyReferences);
+ assembly.Attributes = this.VisitAttributeList(assembly.Attributes, changes.Attributes, deletions.Attributes, insertions.Attributes);
+ assembly.Culture = changes.Culture;
+ assembly.ExportedTypes = this.VisitTypeReferenceList(assembly.ExportedTypes, changes.ExportedTypes, deletions.ExportedTypes, insertions.ExportedTypes);
+ assembly.Flags = changes.Flags;
+ assembly.Kind = changes.Kind;
+ assembly.ModuleAttributes = this.VisitAttributeList(assembly.ModuleAttributes, changes.ModuleAttributes, deletions.ModuleAttributes, insertions.ModuleAttributes);
+ assembly.ModuleReferences = this.VisitModuleReferenceList(assembly.ModuleReferences, changes.ModuleReferences, deletions.ModuleReferences, insertions.ModuleReferences);
+ assembly.Name = changes.Name;
+ assembly.SecurityAttributes = this.VisitSecurityAttributeList(assembly.SecurityAttributes, changes.SecurityAttributes, deletions.SecurityAttributes, insertions.SecurityAttributes);
+ assembly.Types = this.VisitTypeNodeList(assembly.Types, changes.Types, deletions.Types, insertions.Types);
+ assembly.Version = changes.Version;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return assembly;
+ }
+ public virtual AssemblyReference VisitAssemblyReference(AssemblyReference assemblyReference, AssemblyReference changes, AssemblyReference deletions, AssemblyReference insertions)
+ {
+ this.UpdateSourceContext(assemblyReference, changes);
+ if (assemblyReference == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ assemblyReference.Culture = changes.Culture;
+ assemblyReference.Flags = changes.Flags;
+ assemblyReference.Name = changes.Name;
+ assemblyReference.PublicKeyOrToken = changes.PublicKeyOrToken;
+ assemblyReference.Version = changes.Version;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return assemblyReference;
+ }
+ public virtual AssemblyReferenceList VisitAssemblyReferenceList(AssemblyReferenceList assemblyReferences, AssemblyReferenceList changes, AssemblyReferenceList deletions, AssemblyReferenceList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return assemblyReferences;
+ int n = assemblyReferences == null ? 0 : assemblyReferences.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (assemblyReferences != null)
+ for (int i = 0; i < n; i++)
+ assemblyReferences[i] = this.VisitAssemblyReference(assemblyReferences[i], changes[i], deletions[i], insertions[i]);
+ AssemblyReferenceList result = new AssemblyReferenceList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Statement VisitAssertion(Assertion assertion, Assertion changes, Assertion deletions, Assertion insertions)
+ {
+ this.UpdateSourceContext(assertion, changes);
+ if (assertion == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ assertion.Condition = this.VisitExpression(assertion.Condition, changes.Condition, deletions.Condition, insertions.Condition);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return assertion;
+ }
+ public virtual Expression VisitAssignmentExpression(AssignmentExpression assignment, AssignmentExpression changes, AssignmentExpression deletions, AssignmentExpression insertions)
+ {
+ this.UpdateSourceContext(assignment, changes);
+ if (assignment == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ assignment.AssignmentStatement = this.VisitAssignmentStatement(assignment.AssignmentStatement as AssignmentStatement, changes.AssignmentStatement as AssignmentStatement, deletions.AssignmentStatement as AssignmentStatement, insertions.AssignmentStatement as AssignmentStatement);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return assignment;
+ }
+ public virtual Statement VisitAssignmentStatement(AssignmentStatement assignment, AssignmentStatement changes, AssignmentStatement deletions, AssignmentStatement insertions)
+ {
+ this.UpdateSourceContext(assignment, changes);
+ if (assignment == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ assignment.Operator = changes.Operator;
+ assignment.Source = this.VisitExpression(assignment.Source, changes.Source, deletions.Source, insertions.Source);
+ assignment.Target = this.VisitExpression(assignment.Target, changes.Target, deletions.Target, insertions.Target);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return assignment;
+ }
+ public virtual AttributeNode VisitAttributeNode(AttributeNode attribute, AttributeNode changes, AttributeNode deletions, AttributeNode insertions)
+ {
+ this.UpdateSourceContext(attribute, changes);
+ if (attribute == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ attribute.AllowMultiple = changes.AllowMultiple;
+ attribute.Constructor = this.VisitExpression(attribute.Constructor, changes.Constructor, deletions.Constructor, insertions.Constructor);
+ attribute.Expressions = this.VisitExpressionList(attribute.Expressions, changes.Expressions, deletions.Expressions, insertions.Expressions);
+ attribute.Target = changes.Target;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return attribute;
+ }
+ public virtual AttributeList VisitAttributeList(AttributeList attributes, AttributeList changes, AttributeList deletions, AttributeList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return attributes;
+ int n = attributes == null ? 0 : attributes.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (attributes != null)
+ for (int i = 0; i < n; i++)
+ attributes[i] = this.VisitAttributeNode(attributes[i], changes[i], deletions[i], insertions[i]);
+ AttributeList result = new AttributeList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Expression VisitBase(Base Base, Base changes, Base deletions, Base insertions)
+ {
+ this.UpdateSourceContext(Base, changes);
+ if (Base == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Base;
+ }
+ public virtual Expression VisitBinaryExpression(BinaryExpression binaryExpression, BinaryExpression changes, BinaryExpression deletions, BinaryExpression insertions)
+ {
+ this.UpdateSourceContext(binaryExpression, changes);
+ if (binaryExpression == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ binaryExpression.NodeType = changes.NodeType;
+ binaryExpression.Operand1 = this.VisitExpression(binaryExpression.Operand1, changes.Operand1, deletions.Operand1, insertions.Operand1);
+ binaryExpression.Operand2 = this.VisitExpression(binaryExpression.Operand2, changes.Operand2, deletions.Operand2, insertions.Operand2);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return binaryExpression;
+ }
+ public virtual Block VisitBlock(Block block, Block changes, Block deletions, Block insertions)
+ {
+ this.UpdateSourceContext(block, changes);
+ if (block == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ block.Checked = changes.Checked;
+ block.Statements = this.VisitStatementList(block.Statements, changes.Statements, deletions.Statements, insertions.Statements);
+ block.SuppressCheck = changes.SuppressCheck;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return block;
+ }
+ public virtual Expression VisitBlockExpression(BlockExpression blockExpression, BlockExpression changes, BlockExpression deletions, BlockExpression insertions)
+ {
+ this.UpdateSourceContext(blockExpression, changes);
+ if (blockExpression == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ blockExpression.Block = this.VisitBlock(blockExpression.Block, changes.Block, deletions.Block, insertions.Block);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return blockExpression;
+ }
+ public virtual BlockList VisitBlockList(BlockList blockList, BlockList changes, BlockList deletions, BlockList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return blockList;
+ int n = blockList == null ? 0 : blockList.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (blockList != null)
+ for (int i = 0; i < n; i++)
+ blockList[i] = this.VisitBlock(blockList[i], changes[i], deletions[i], insertions[i]);
+ BlockList result = new BlockList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Catch VisitCatch(Catch Catch, Catch changes, Catch deletions, Catch insertions)
+ {
+ this.UpdateSourceContext(Catch, changes);
+ if (Catch == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ Catch.Block = this.VisitBlock(Catch.Block, changes.Block, deletions.Block, insertions.Block);
+ Catch.Type = this.VisitTypeReference(Catch.Type, changes.Type);
+ Catch.Variable = this.VisitExpression(Catch.Variable, changes.Variable, deletions.Variable, insertions.Variable);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Catch;
+ }
+ public virtual CatchList VisitCatchList(CatchList catchers, CatchList changes, CatchList deletions, CatchList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return catchers;
+ int n = catchers == null ? 0 : catchers.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (catchers != null)
+ for (int i = 0; i < n; i++)
+ catchers[i] = this.VisitCatch(catchers[i], changes[i], deletions[i], insertions[i]);
+ CatchList result = new CatchList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Class VisitClass(Class Class, Class changes, Class deletions, Class insertions)
+ {
+ TypeNode result = this.VisitTypeNode(Class, changes, deletions, insertions);
+ Debug.Assert(result is Class);
+ return result as Class;
+ }
+ public virtual Expression VisitCoerceTuple(CoerceTuple coerceTuple, CoerceTuple changes, CoerceTuple deletions, CoerceTuple insertions)
+ {
+ this.UpdateSourceContext(coerceTuple, changes);
+ if (coerceTuple == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ coerceTuple.Fields = this.VisitFieldList(coerceTuple.Fields, changes.Fields, deletions.Fields, insertions.Fields);
+ coerceTuple.OriginalTuple = this.VisitExpression(coerceTuple.OriginalTuple, changes.OriginalTuple, deletions.OriginalTuple, insertions.OriginalTuple);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return coerceTuple;
+ }
+ public virtual CollectionEnumerator VisitCollectionEnumerator(CollectionEnumerator ce, CollectionEnumerator changes, CollectionEnumerator deletions, CollectionEnumerator insertions)
+ {
+ this.UpdateSourceContext(ce, changes);
+ if (ce == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ ce.Collection = this.VisitExpression(ce.Collection, changes.Collection, deletions.Collection, insertions.Collection);
+ //REVIEW: update method bindings?
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return ce;
+ }
+ public virtual Compilation VisitCompilation(Compilation compilation, Compilation changes, Compilation deletions, Compilation insertions)
+ {
+ this.UpdateSourceContext(compilation, changes);
+ if (compilation == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ compilation.CompilerParameters = changes.CompilerParameters;
+ compilation.CompilationUnits = this.VisitCompilationUnitList(compilation.CompilationUnits, changes.CompilationUnits, deletions.CompilationUnits, insertions.CompilationUnits);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return compilation;
+ }
+ public virtual CompilationUnit VisitCompilationUnit(CompilationUnit cUnit, CompilationUnit changes, CompilationUnit deletions, CompilationUnit insertions)
+ {
+ this.UpdateSourceContext(cUnit, changes);
+ if (cUnit == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ cUnit.Nodes = this.VisitNodeList(cUnit.Nodes, changes.Nodes, deletions.Nodes, insertions.Nodes);
+ cUnit.PreprocessorDefinedSymbols = changes.PreprocessorDefinedSymbols;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return cUnit;
+ }
+ public virtual CompilationUnitList VisitCompilationUnitList(CompilationUnitList compUnits, CompilationUnitList changes, CompilationUnitList deletions, CompilationUnitList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return compUnits;
+ int n = compUnits == null ? 0 : compUnits.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (compUnits != null)
+ for (int i = 0; i < n; i++)
+ compUnits[i] = this.VisitCompilationUnit(compUnits[i], changes[i], deletions[i], insertions[i]);
+ CompilationUnitList result = new CompilationUnitList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual CompilationUnitSnippet VisitCompilationUnitSnippet(CompilationUnitSnippet snippet, CompilationUnitSnippet changes, CompilationUnitSnippet deletions, CompilationUnitSnippet insertions)
+ {
+ CompilationUnit cu = this.VisitCompilationUnit(snippet, changes, deletions, insertions);
+ Debug.Assert(cu is CompilationUnitSnippet);
+ return cu as CompilationUnitSnippet;
+ }
+ public virtual Node VisitComposition(Composition comp, Composition changes, Composition deletions, Composition insertions)
+ {
+ this.UpdateSourceContext(comp, changes);
+ if (comp == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ comp.Expression = this.VisitExpression(comp.Expression, changes.Expression, deletions.Expression, insertions.Expression);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return comp;
+ }
+ public virtual Expression VisitConstruct(Construct cons, Construct changes, Construct deletions, Construct insertions)
+ {
+ this.UpdateSourceContext(cons, changes);
+ if (cons == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ cons.Constructor = this.VisitExpression(cons.Constructor, changes.Constructor, deletions.Constructor, insertions.Constructor);
+ cons.Operands = this.VisitExpressionList(cons.Operands, changes.Operands, deletions.Operands, insertions.Operands);
+ cons.Owner = this.VisitExpression(cons.Owner, changes.Owner, deletions.Owner, insertions.Owner);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return cons;
+ }
+ public virtual Expression VisitConstructArray(ConstructArray consArr, ConstructArray changes, ConstructArray deletions, ConstructArray insertions)
+ {
+ this.UpdateSourceContext(consArr, changes);
+ if (consArr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ consArr.ElementType = this.VisitTypeReference(consArr.ElementType, changes.ElementType);
+ consArr.Initializers = this.VisitExpressionList(consArr.Initializers, changes.Initializers, deletions.Initializers, insertions.Initializers);
+ consArr.Operands = this.VisitExpressionList(consArr.Operands, changes.Operands, deletions.Operands, insertions.Operands);
+ consArr.Rank = changes.Rank;
+ consArr.Owner = this.VisitExpression(consArr.Owner, changes.Owner, deletions.Owner, insertions.Owner);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return consArr;
+ }
+ public virtual Expression VisitConstructDelegate(ConstructDelegate consDelegate, ConstructDelegate changes, ConstructDelegate deletions, ConstructDelegate insertions)
+ {
+ this.UpdateSourceContext(consDelegate, changes);
+ if (consDelegate == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ consDelegate.DelegateType = this.VisitTypeReference(consDelegate.DelegateType, changes.DelegateType);
+ consDelegate.MethodName = changes.MethodName;
+ consDelegate.TargetObject = this.VisitExpression(consDelegate.TargetObject, changes.TargetObject, deletions.TargetObject, insertions.TargetObject);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return consDelegate;
+ }
+ public virtual Expression VisitConstructFlexArray(ConstructFlexArray consArr, ConstructFlexArray changes, ConstructFlexArray deletions, ConstructFlexArray insertions)
+ {
+ this.UpdateSourceContext(consArr, changes);
+ if (consArr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ consArr.ElementType = this.VisitTypeReference(consArr.ElementType, changes.ElementType);
+ consArr.Initializers = this.VisitExpressionList(consArr.Initializers, changes.Initializers, deletions.Initializers, insertions.Initializers);
+ consArr.Operands = this.VisitExpressionList(consArr.Operands, changes.Operands, deletions.Operands, insertions.Operands);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return consArr;
+ }
+ public virtual Expression VisitConstructIterator(ConstructIterator consIterator, ConstructIterator changes, ConstructIterator deletions, ConstructIterator insertions)
+ {
+ this.UpdateSourceContext(consIterator, changes);
+ if (consIterator == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ consIterator.Body = this.VisitBlock(consIterator.Body, changes.Body, deletions.Body, insertions.Body);
+ consIterator.ElementType = this.VisitTypeReference(consIterator.ElementType, changes.ElementType);
+ consIterator.State = this.VisitClass(consIterator.State, changes.State, deletions.State, insertions.State);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return consIterator;
+ }
+ public virtual Expression VisitConstructTuple(ConstructTuple consTuple, ConstructTuple changes, ConstructTuple deletions, ConstructTuple insertions)
+ {
+ this.UpdateSourceContext(consTuple, changes);
+ if (consTuple == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ consTuple.Fields = this.VisitFieldList(consTuple.Fields, changes.Fields, deletions.Fields, insertions.Fields);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return consTuple;
+ }
+#if ExtendedRuntime
+ public virtual TypeNode VisitConstrainedType(ConstrainedType cType, ConstrainedType changes, ConstrainedType deletions, ConstrainedType insertions){
+ this.UpdateSourceContext(cType, changes);
+ if (cType == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ cType.Constraint = this.VisitExpression(cType.Constraint, changes.Constraint, deletions.Constraint, insertions.Constraint);
+ cType.UnderlyingType = this.VisitTypeReference(cType.UnderlyingType, changes.UnderlyingType);
+ }
+ }else if (deletions != null)
+ return null;
+ return cType;
+ }
+#endif
+ public virtual Statement VisitContinue(Continue Continue, Continue changes, Continue deletions, Continue insertions)
+ {
+ this.UpdateSourceContext(Continue, changes);
+ if (Continue == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ Continue.Level = changes.Level;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Continue;
+ }
+ public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure, CurrentClosure changes, CurrentClosure deletions, CurrentClosure insertions)
+ {
+ this.UpdateSourceContext(currentClosure, changes);
+ if (currentClosure == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return currentClosure;
+ }
+ public virtual DelegateNode VisitDelegateNode(DelegateNode delegateNode, DelegateNode changes, DelegateNode deletions, DelegateNode insertions)
+ {
+ this.UpdateSourceContext(delegateNode, changes);
+ if (delegateNode == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ delegateNode.Attributes = this.VisitAttributeList(delegateNode.Attributes, changes.Attributes, deletions.Attributes, insertions.Attributes);
+#if !NoXml
+ delegateNode.Documentation = changes.Documentation;
+#endif
+ delegateNode.Flags = changes.Flags;
+ delegateNode.Parameters = this.VisitParameterList(delegateNode.Parameters, changes.Parameters, deletions.Parameters, insertions.Parameters);
+ delegateNode.ReturnType = this.VisitTypeReference(delegateNode.ReturnType, changes.ReturnType);
+ delegateNode.SecurityAttributes = this.VisitSecurityAttributeList(delegateNode.SecurityAttributes, changes.SecurityAttributes, deletions.SecurityAttributes, insertions.SecurityAttributes);
+ delegateNode.TemplateParameters = this.VisitTypeReferenceList(delegateNode.TemplateParameters, changes.TemplateParameters, deletions.TemplateParameters, insertions.TemplateParameters);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return delegateNode;
+ }
+ public virtual Statement VisitDoWhile(DoWhile doWhile, DoWhile changes, DoWhile deletions, DoWhile insertions)
+ {
+ this.UpdateSourceContext(doWhile, changes);
+ if (doWhile == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ doWhile.Body = this.VisitBlock(doWhile.Body, changes.Body, deletions.Body, insertions.Body);
+ doWhile.Condition = this.VisitExpression(doWhile.Condition, changes.Condition, deletions.Condition, insertions.Condition);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return doWhile;
+ }
+ public virtual Statement VisitEndFilter(EndFilter endFilter, EndFilter changes, EndFilter deletions, EndFilter insertions)
+ {
+ this.UpdateSourceContext(endFilter, changes);
+ if (endFilter == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ endFilter.Value = this.VisitExpression(endFilter.Value, changes.Value, deletions.Value, insertions.Value);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return endFilter;
+ }
+ public virtual Statement VisitEndFinally(EndFinally endFinally, EndFinally changes, EndFinally deletions, EndFinally insertions)
+ {
+ this.UpdateSourceContext(endFinally, changes);
+ if (endFinally == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return endFinally;
+ }
+ public virtual EnumNode VisitEnumNode(EnumNode enumNode, EnumNode changes, EnumNode deletions, EnumNode insertions)
+ {
+ if (enumNode == null) return changes;
+ TypeNode result = this.VisitTypeNode(enumNode, changes, deletions, insertions);
+ Debug.Assert(result is EnumNode);
+ if (result == enumNode)
+ {
+ Debug.Assert(changes != null);
+ if (changes != null)
+ enumNode.UnderlyingType = this.VisitTypeReference(enumNode.UnderlyingType, changes.UnderlyingType);
+ return enumNode;
+ }
+ return result as EnumNode;
+ }
+ public virtual Event VisitEvent(Event evnt, Event changes, Event deletions, Event insertions)
+ {
+ this.UpdateSourceContext(evnt, changes);
+ if (evnt == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ evnt.Attributes = this.VisitAttributeList(evnt.Attributes, changes.Attributes, deletions.Attributes, insertions.Attributes);
+#if !NoXml
+ evnt.Documentation = changes.Documentation;
+#endif
+ evnt.Flags = changes.Flags;
+ evnt.HandlerAdder = this.VisitMethodReference(evnt.HandlerAdder, changes.HandlerAdder);
+ evnt.HandlerCaller = this.VisitMethodReference(evnt.HandlerCaller, changes.HandlerCaller);
+ evnt.HandlerFlags = changes.HandlerFlags;
+ evnt.HandlerRemover = this.VisitMethodReference(evnt.HandlerRemover, changes.HandlerRemover);
+ evnt.HandlerType = this.VisitTypeReference(evnt.HandlerType, changes.HandlerType);
+ evnt.InitialHandler = this.VisitExpression(evnt.InitialHandler, changes.InitialHandler, deletions.InitialHandler, insertions.InitialHandler);
+ evnt.Name = changes.Name;
+ evnt.OtherMethods = this.VisitMethodReferenceList(evnt.OtherMethods, changes.OtherMethods);
+ evnt.OverridesBaseClassMember = changes.OverridesBaseClassMember;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return evnt;
+ }
+ public virtual Statement VisitExit(Exit exit, Exit changes, Exit deletions, Exit insertions)
+ {
+ this.UpdateSourceContext(exit, changes);
+ if (exit == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ exit.Level = changes.Level;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return exit;
+ }
+ public virtual Expression VisitExpression(Expression expression, Expression changes, Expression deletions, Expression insertions)
+ {
+ return this.Visit(expression, changes, deletions, insertions) as Expression;
+ }
+ public virtual ExpressionList VisitExpressionList(ExpressionList expressions, ExpressionList changes, ExpressionList deletions, ExpressionList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return expressions;
+ int n = expressions == null ? 0 : expressions.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (expressions != null)
+ for (int i = 0; i < n; i++)
+ expressions[i] = this.VisitExpression(expressions[i], changes[i], deletions[i], insertions[i]);
+ ExpressionList result = new ExpressionList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Expression VisitExpressionSnippet(ExpressionSnippet snippet, ExpressionSnippet changes, ExpressionSnippet deletions, ExpressionSnippet insertions)
+ {
+ this.UpdateSourceContext(snippet, changes);
+ if (snippet == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return snippet;
+ }
+ public virtual Statement VisitExpressionStatement(ExpressionStatement statement, ExpressionStatement changes, ExpressionStatement deletions, ExpressionStatement insertions)
+ {
+ this.UpdateSourceContext(statement, changes);
+ if (statement == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ statement.Expression = this.VisitExpression(statement.Expression, changes.Expression, deletions.Expression, insertions.Expression);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return statement;
+ }
+ public virtual FaultHandler VisitFaultHandler(FaultHandler faultHandler, FaultHandler changes, FaultHandler deletions, FaultHandler insertions)
+ {
+ this.UpdateSourceContext(faultHandler, changes);
+ if (faultHandler == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ faultHandler.Block = this.VisitBlock(faultHandler.Block, changes.Block, deletions.Block, insertions.Block);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return faultHandler;
+ }
+ public virtual FaultHandlerList VisitFaultHandlerList(FaultHandlerList faultHandlers, FaultHandlerList changes, FaultHandlerList deletions, FaultHandlerList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return faultHandlers;
+ int n = faultHandlers == null ? 0 : faultHandlers.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (faultHandlers != null)
+ for (int i = 0; i < n; i++)
+ faultHandlers[i] = this.VisitFaultHandler(faultHandlers[i], changes[i], deletions[i], insertions[i]);
+ FaultHandlerList result = new FaultHandlerList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Field VisitField(Field field, Field changes, Field deletions, Field insertions)
+ {
+ this.UpdateSourceContext(field, changes);
+ if (field == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ field.Attributes = this.VisitAttributeList(field.Attributes, changes.Attributes, deletions.Attributes, insertions.Attributes);
+ field.DefaultValue = this.VisitLiteral(field.DefaultValue, changes.DefaultValue, deletions.DefaultValue, insertions.DefaultValue);
+#if !NoXml
+ field.Documentation = changes.Documentation;
+#endif
+ field.Flags = changes.Flags;
+ field.HidesBaseClassMember = changes.HidesBaseClassMember;
+ field.ImplementedInterfaces = this.VisitInterfaceReferenceList(field.ImplementedInterfaces, changes.ImplementedInterfaces, deletions.ImplementedInterfaces, insertions.ImplementedInterfaces);
+ field.InitialData = changes.InitialData;
+ field.Initializer = changes.Initializer;
+ field.MarshallingInformation = changes.MarshallingInformation;
+ field.Name = changes.Name;
+ field.Offset = changes.Offset;
+ field.OverridesBaseClassMember = changes.OverridesBaseClassMember;
+ field.Section = changes.Section;
+ field.Type = this.VisitTypeReference(field.Type, changes.Type);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return field;
+ }
+ public virtual Block VisitFieldInitializerBlock(FieldInitializerBlock block, FieldInitializerBlock changes, FieldInitializerBlock deletions, FieldInitializerBlock insertions)
+ {
+ this.UpdateSourceContext(block, changes);
+ if (block == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ block.IsStatic = changes.IsStatic;
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return block;
+ }
+ public virtual FieldList VisitFieldList(FieldList fields, FieldList changes, FieldList deletions, FieldList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return fields;
+ int n = fields == null ? 0 : fields.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (fields != null)
+ for (int i = 0; i < n; i++)
+ fields[i] = this.VisitField(fields[i], changes[i], deletions[i], insertions[i]);
+ FieldList result = new FieldList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Statement VisitFilter(Filter filter, Filter changes, Filter deletions, Filter insertions)
+ {
+ this.UpdateSourceContext(filter, changes);
+ if (filter == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ filter.Block = this.VisitBlock(filter.Block, changes.Block, deletions.Block, insertions.Block);
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return filter;
+ }
+ public virtual FilterList VisitFilterList(FilterList filters, FilterList changes, FilterList deletions, FilterList insertions)
+ {
+ if (filters == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return filters;
+ }
+ public virtual Statement VisitFinally(Finally Finally, Finally changes, Finally deletions, Finally insertions)
+ {
+ this.UpdateSourceContext(Finally, changes);
+ if (Finally == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Finally;
+ }
+ public virtual Statement VisitFixed(Fixed Fixed, Fixed changes, Fixed deletions, Fixed insertions)
+ {
+ this.UpdateSourceContext(Fixed, changes);
+ if (Fixed == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Fixed;
+ }
+ public virtual Statement VisitFor(For For, For changes, For deletions, For insertions)
+ {
+ this.UpdateSourceContext(For, changes);
+ if (For == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return For;
+ }
+ public virtual Statement VisitForEach(ForEach forEach, ForEach changes, ForEach deletions, ForEach insertions)
+ {
+ this.UpdateSourceContext(forEach, changes);
+ if (forEach == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return forEach;
+ }
+ public virtual Statement VisitFunctionDeclaration(FunctionDeclaration functionDeclaration, FunctionDeclaration changes, FunctionDeclaration deletions, FunctionDeclaration insertions)
+ {
+ this.UpdateSourceContext(functionDeclaration, changes);
+ if (functionDeclaration == null) return changes;
+ return functionDeclaration;
+ }
+ public virtual Expression VisitTemplateInstance(TemplateInstance instance, TemplateInstance changes, TemplateInstance deletions, TemplateInstance insertions)
+ {
+ this.UpdateSourceContext(instance, changes);
+ if (instance == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return instance;
+ }
+ public virtual Expression VisitStackAlloc(StackAlloc alloc, StackAlloc changes, StackAlloc deletions, StackAlloc insertions)
+ {
+ this.UpdateSourceContext(alloc, changes);
+ if (alloc == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return alloc;
+ }
+ public virtual Statement VisitGoto(Goto Goto, Goto changes, Goto deletions, Goto insertions)
+ {
+ this.UpdateSourceContext(Goto, changes);
+ if (Goto == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Goto;
+ }
+ public virtual Statement VisitGotoCase(GotoCase gotoCase, GotoCase changes, GotoCase deletions, GotoCase insertions)
+ {
+ this.UpdateSourceContext(gotoCase, changes);
+ if (gotoCase == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return gotoCase;
+ }
+ public virtual Expression VisitIdentifier(Identifier identifier, Identifier changes, Identifier deletions, Identifier insertions)
+ {
+ this.UpdateSourceContext(identifier, changes);
+ if (identifier == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return identifier;
+ }
+ public virtual Statement VisitIf(If If, If changes, If deletions, If insertions)
+ {
+ this.UpdateSourceContext(If, changes);
+ if (If == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return If;
+ }
+ public virtual Expression VisitImplicitThis(ImplicitThis implicitThis, ImplicitThis changes, ImplicitThis deletions, ImplicitThis insertions)
+ {
+ this.UpdateSourceContext(implicitThis, changes);
+ if (implicitThis == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return implicitThis;
+ }
+ public virtual Expression VisitIndexer(Indexer indexer, Indexer changes, Indexer deletions, Indexer insertions)
+ {
+ this.UpdateSourceContext(indexer, changes);
+ if (indexer == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return indexer;
+ }
+ public virtual Interface VisitInterface(Interface Interface, Interface changes, Interface deletions, Interface insertions)
+ {
+ return (Interface)this.VisitTypeNode(Interface, changes, deletions, insertions);
+ }
+ public virtual InterfaceList VisitInterfaceReferenceList(InterfaceList interfaces, InterfaceList changes, InterfaceList deletions, InterfaceList insertions)
+ {
+ if (interfaces == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return interfaces;
+ }
+ public virtual Interface VisitInterfaceReference(Interface Interface, Interface changes)
+ {
+ return (Interface)this.VisitTypeReference(Interface, changes);
+ }
+ public virtual InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons, InstanceInitializer changes, InstanceInitializer deletions, InstanceInitializer insertions)
+ {
+ return (InstanceInitializer)this.VisitMethod(cons, changes, deletions, insertions);
+ }
+ public virtual Statement VisitLabeledStatement(LabeledStatement lStatement, LabeledStatement changes, LabeledStatement deletions, LabeledStatement insertions)
+ {
+ this.UpdateSourceContext(lStatement, changes);
+ if (lStatement == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return lStatement;
+ }
+ public virtual Literal VisitLiteral(Literal literal, Literal changes, Literal deletions, Literal insertions)
+ {
+ this.UpdateSourceContext(literal, changes);
+ if (literal == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return literal;
+ }
+ public virtual Expression VisitLocal(Local local, Local changes, Local deletions, Local insertions)
+ {
+ this.UpdateSourceContext(local, changes);
+ if (local == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return local;
+ }
+ public virtual LocalDeclaration VisitLocalDeclaration(LocalDeclaration localDeclaration, LocalDeclaration changes, LocalDeclaration deletions, LocalDeclaration insertions)
+ {
+ this.UpdateSourceContext(localDeclaration, changes);
+ if (localDeclaration == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return localDeclaration;
+ }
+ public virtual LocalDeclarationList VisitLocalDeclarationList(LocalDeclarationList localDeclarations, LocalDeclarationList changes, LocalDeclarationList deletions, LocalDeclarationList insertions)
+ {
+ if (localDeclarations == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return localDeclarations;
+ }
+ public virtual Statement VisitLocalDeclarationsStatement(LocalDeclarationsStatement localDeclarations, LocalDeclarationsStatement changes, LocalDeclarationsStatement deletions, LocalDeclarationsStatement insertions)
+ {
+ this.UpdateSourceContext(localDeclarations, changes);
+ if (localDeclarations == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return localDeclarations;
+ }
+ public virtual Statement VisitLock(Lock Lock, Lock changes, Lock deletions, Lock insertions)
+ {
+ this.UpdateSourceContext(Lock, changes);
+ if (Lock == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Lock;
+ }
+ public virtual Expression VisitLRExpression(LRExpression expr, LRExpression changes, LRExpression deletions, LRExpression insertions)
+ {
+ this.UpdateSourceContext(expr, changes);
+ if (expr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return expr;
+ }
+ public virtual Expression VisitMemberBinding(MemberBinding memberBinding, MemberBinding changes, MemberBinding deletions, MemberBinding insertions)
+ {
+ this.UpdateSourceContext(memberBinding, changes);
+ if (memberBinding == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return memberBinding;
+ }
+ public virtual MemberList VisitMemberList(MemberList members, MemberList changes, MemberList deletions, MemberList insertions)
+ {
+ if (members == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return members;
+ }
+ public virtual Method VisitMethod(Method method, Method changes, Method deletions, Method insertions)
+ {
+ this.UpdateSourceContext(method, changes);
+ if (method == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return method;
+ }
+ public virtual Expression VisitMethodCall(MethodCall call, MethodCall changes, MethodCall deletions, MethodCall insertions)
+ {
+ this.UpdateSourceContext(call, changes);
+ if (call == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return call;
+ }
+ public virtual Method VisitMethodReference(Method method, Method changes)
+ {
+ return method;
+ }
+ public virtual MethodList VisitMethodReferenceList(MethodList methodList, MethodList changesList)
+ {
+ return methodList;
+ }
+ public virtual Module VisitModule(Module module, Module changes, Module deletions, Module insertions)
+ {
+ this.UpdateSourceContext(module, changes);
+ if (module == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return module;
+ }
+ public virtual ModuleReference VisitModuleReference(ModuleReference moduleReference, ModuleReference changes, ModuleReference deletions, ModuleReference insertions)
+ {
+ this.UpdateSourceContext(moduleReference, changes);
+ if (moduleReference == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return moduleReference;
+ }
+ public virtual ModuleReferenceList VisitModuleReferenceList(ModuleReferenceList moduleReferences, ModuleReferenceList changes, ModuleReferenceList deletions, ModuleReferenceList insertions)
+ {
+ return moduleReferences;
+ }
+ public virtual Expression VisitNameBinding(NameBinding nameBinding, NameBinding changes, NameBinding deletions, NameBinding insertions)
+ {
+ this.UpdateSourceContext(nameBinding, changes);
+ if (nameBinding == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return nameBinding;
+ }
+ public virtual Expression VisitNamedArgument(NamedArgument namedArgument, NamedArgument changes, NamedArgument deletions, NamedArgument insertions)
+ {
+ this.UpdateSourceContext(namedArgument, changes);
+ if (namedArgument == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return namedArgument;
+ }
+ public virtual Namespace VisitNamespace(Namespace nspace, Namespace changes, Namespace deletions, Namespace insertions)
+ {
+ this.UpdateSourceContext(nspace, changes);
+ if (nspace == null) return changes;
+ return nspace;
+ }
+ public virtual NamespaceList VisitNamespaceList(NamespaceList namespaces, NamespaceList changes, NamespaceList deletions, NamespaceList insertions)
+ {
+ if (namespaces == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return namespaces;
+ }
+ public virtual NodeList VisitNodeList(NodeList nodeList, NodeList changes, NodeList deletions, NodeList insertions)
+ {
+ if (changes == null || deletions == null || insertions == null) return nodeList;
+ int n = nodeList == null ? 0 : nodeList.Count;
+ if (n > changes.Count) { Debug.Assert(false); n = changes.Count; }
+ if (n > deletions.Count) { Debug.Assert(false); n = deletions.Count; }
+ if (n > insertions.Count) { Debug.Assert(false); n = insertions.Count; }
+ if (nodeList != null)
+ for (int i = 0; i < n; i++)
+ nodeList[i] = this.Visit(nodeList[i], changes[i], deletions[i], insertions[i]);
+ NodeList result = new NodeList(insertions.Count - n);
+ for (int i = n, m = insertions.Count; i < m; i++)
+ result.Add(insertions[i]);
+ return result;
+ }
+ public virtual Expression VisitParameter(Parameter parameter, Parameter changes, Parameter deletions, Parameter insertions)
+ {
+ this.UpdateSourceContext(parameter, changes);
+ if (parameter == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return parameter;
+ }
+ public virtual ParameterList VisitParameterList(ParameterList parameterList, ParameterList changes, ParameterList deletions, ParameterList insertions)
+ {
+ if (parameterList == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return parameterList;
+ }
+ public virtual Expression VisitPrefixExpression(PrefixExpression pExpr, PrefixExpression changes, PrefixExpression deletions, PrefixExpression insertions)
+ {
+ this.UpdateSourceContext(pExpr, changes);
+ if (pExpr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return pExpr;
+ }
+ public virtual Expression VisitPostfixExpression(PostfixExpression pExpr, PostfixExpression changes, PostfixExpression deletions, PostfixExpression insertions)
+ {
+ this.UpdateSourceContext(pExpr, changes);
+ if (pExpr == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return pExpr;
+ }
+ public virtual Property VisitProperty(Property property, Property changes, Property deletions, Property insertions)
+ {
+ this.UpdateSourceContext(property, changes);
+ if (property == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return property;
+ }
+ public virtual Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier, QualifiedIdentifier changes, QualifiedIdentifier deletions, QualifiedIdentifier insertions)
+ {
+ this.UpdateSourceContext(qualifiedIdentifier, changes);
+ if (qualifiedIdentifier == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return qualifiedIdentifier;
+ }
+ public virtual Statement VisitRepeat(Repeat repeat, Repeat changes, Repeat deletions, Repeat insertions)
+ {
+ this.UpdateSourceContext(repeat, changes);
+ if (repeat == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return repeat;
+ }
+ public virtual Statement VisitResourceUse(ResourceUse resourceUse, ResourceUse changes, ResourceUse deletions, ResourceUse insertions)
+ {
+ this.UpdateSourceContext(resourceUse, changes);
+ if (resourceUse == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return resourceUse;
+ }
+ public virtual Statement VisitReturn(Return Return, Return changes, Return deletions, Return insertions)
+ {
+ this.UpdateSourceContext(Return, changes);
+ if (Return == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Return;
+ }
+ public virtual SecurityAttribute VisitSecurityAttribute(SecurityAttribute attribute, SecurityAttribute changes, SecurityAttribute deletions, SecurityAttribute insertions)
+ {
+ this.UpdateSourceContext(attribute, changes);
+ if (attribute == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return attribute;
+ }
+ public virtual SecurityAttributeList VisitSecurityAttributeList(SecurityAttributeList attributes, SecurityAttributeList changes, SecurityAttributeList deletions, SecurityAttributeList insertions)
+ {
+ if (attributes == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return attributes;
+ }
+ public virtual Expression VisitSetterValue(SetterValue value, SetterValue changes, SetterValue deletions, SetterValue insertions)
+ {
+ this.UpdateSourceContext(value, changes);
+ if (value == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return value;
+ }
+ public virtual StatementList VisitStatementList(StatementList statements, StatementList changes, StatementList deletions, StatementList insertions)
+ {
+ if (statements == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return statements;
+ }
+ public virtual StatementSnippet VisitStatementSnippet(StatementSnippet snippet, StatementSnippet changes, StatementSnippet deletions, StatementSnippet insertions)
+ {
+ this.UpdateSourceContext(snippet, changes);
+ if (snippet == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return snippet;
+ }
+ public virtual StaticInitializer VisitStaticInitializer(StaticInitializer cons, StaticInitializer changes, StaticInitializer deletions, StaticInitializer insertions)
+ {
+ return (StaticInitializer)this.VisitMethod(cons, changes, deletions, insertions);
+ }
+ public virtual Struct VisitStruct(Struct Struct, Struct changes, Struct deletions, Struct insertions)
+ {
+ return (Struct)this.VisitTypeNode(Struct, changes, deletions, insertions);
+ }
+ public virtual Statement VisitSwitch(Switch Switch, Switch changes, Switch deletions, Switch insertions)
+ {
+ this.UpdateSourceContext(Switch, changes);
+ if (Switch == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Switch;
+ }
+ public virtual SwitchCase VisitSwitchCase(SwitchCase switchCase, SwitchCase changes, SwitchCase deletions, SwitchCase insertions)
+ {
+ this.UpdateSourceContext(switchCase, changes);
+ if (switchCase == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return switchCase;
+ }
+ public virtual SwitchCaseList VisitSwitchCaseList(SwitchCaseList switchCases, SwitchCaseList changes, SwitchCaseList deletions, SwitchCaseList insertions)
+ {
+ if (switchCases == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return switchCases;
+ }
+ public virtual Statement VisitSwitchInstruction(SwitchInstruction switchInstruction, SwitchInstruction changes, SwitchInstruction deletions, SwitchInstruction insertions)
+ {
+ this.UpdateSourceContext(switchInstruction, changes);
+ if (switchInstruction == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return switchInstruction;
+ }
+ public virtual Statement VisitTypeswitch(Typeswitch Typeswitch, Typeswitch changes, Typeswitch deletions, Typeswitch insertions)
+ {
+ this.UpdateSourceContext(Typeswitch, changes);
+ if (Typeswitch == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Typeswitch;
+ }
+ public virtual TypeswitchCase VisitTypeswitchCase(TypeswitchCase typeswitchCase, TypeswitchCase changes, TypeswitchCase deletions, TypeswitchCase insertions)
+ {
+ this.UpdateSourceContext(typeswitchCase, changes);
+ if (typeswitchCase == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeswitchCase;
+ }
+ public virtual TypeswitchCaseList VisitTypeswitchCaseList(TypeswitchCaseList typeswitchCases, TypeswitchCaseList changes, TypeswitchCaseList deletions, TypeswitchCaseList insertions)
+ {
+ if (typeswitchCases == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeswitchCases;
+ }
+ public virtual Expression VisitTargetExpression(Expression expression, Expression changes, Expression deletions, Expression insertions)
+ {
+ return this.VisitExpression(expression, changes, deletions, insertions);
+ }
+ public virtual Expression VisitTernaryExpression(TernaryExpression expression, TernaryExpression changes, TernaryExpression deletions, TernaryExpression insertions)
+ {
+ this.UpdateSourceContext(expression, changes);
+ if (expression == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return expression;
+ }
+ public virtual Expression VisitThis(This This, This changes, This deletions, This insertions)
+ {
+ this.UpdateSourceContext(This, changes);
+ if (This == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return This;
+ }
+ public virtual Statement VisitThrow(Throw Throw, Throw changes, Throw deletions, Throw insertions)
+ {
+ this.UpdateSourceContext(Throw, changes);
+ if (Throw == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Throw;
+ }
+ public virtual Statement VisitTry(Try Try, Try changes, Try deletions, Try insertions)
+ {
+ this.UpdateSourceContext(Try, changes);
+ if (Try == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Try;
+ }
+#if ExtendedRuntime
+ public virtual TupleType VisitTupleType(TupleType tuple, TupleType changes, TupleType deletions, TupleType insertions){
+ return (TupleType)this.VisitTypeNode(tuple, changes, deletions, insertions);
+ }
+ public virtual TypeAlias VisitTypeAlias(TypeAlias tAlias, TypeAlias changes, TypeAlias deletions, TypeAlias insertions){
+ this.UpdateSourceContext(tAlias, changes);
+ if (tAlias == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return tAlias;
+ }
+ public virtual TypeIntersection VisitTypeIntersection(TypeIntersection typeIntersection, TypeIntersection changes, TypeIntersection deletions, TypeIntersection insertions){
+ return (TypeIntersection)this.VisitTypeNode(typeIntersection, changes, deletions, insertions);
+ }
+#endif
+ public virtual TypeMemberSnippet VisitTypeMemberSnippet(TypeMemberSnippet snippet, TypeMemberSnippet changes, TypeMemberSnippet deletions, TypeMemberSnippet insertions)
+ {
+ this.UpdateSourceContext(snippet, changes);
+ return snippet;
+ }
+ public virtual TypeModifier VisitTypeModifier(TypeModifier typeModifier, TypeModifier changes, TypeModifier deletions, TypeModifier insertions)
+ {
+ this.UpdateSourceContext(typeModifier, changes);
+ if (typeModifier == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeModifier;
+ }
+ public virtual TypeNode VisitTypeNode(TypeNode typeNode, TypeNode changes, TypeNode deletions, TypeNode insertions)
+ {
+ this.UpdateSourceContext(typeNode, changes);
+ if (typeNode == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeNode;
+ }
+ public virtual TypeNodeList VisitTypeNodeList(TypeNodeList types, TypeNodeList changes, TypeNodeList deletions, TypeNodeList insertions)
+ {
+ if (types == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return types;
+ }
+ public virtual TypeNode VisitTypeParameter(TypeNode typeParameter, TypeNode changes, TypeNode deletions, TypeNode insertions)
+ {
+ this.UpdateSourceContext(typeParameter, changes);
+ if (typeParameter == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeParameter;
+ }
+ public virtual TypeNodeList VisitTypeParameterList(TypeNodeList typeParameters, TypeNodeList changes, TypeNodeList deletions, TypeNodeList insertions)
+ {
+ if (typeParameters == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeParameters;
+ }
+ public virtual TypeNode VisitTypeReference(TypeNode type, TypeNode changes)
+ {
+ return type;
+ }
+ public virtual TypeReference VisitTypeReference(TypeReference type, TypeReference changes, TypeReference deletions, TypeReference insertions)
+ {
+ return type;
+ }
+ public virtual TypeNodeList VisitTypeReferenceList(TypeNodeList typeReferences, TypeNodeList changes, TypeNodeList deletions, TypeNodeList insertions)
+ {
+ if (typeReferences == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return typeReferences;
+ }
+#if ExtendedRuntime
+ public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion, TypeUnion changes, TypeUnion deletions, TypeUnion insertions){
+ return (TypeUnion)this.VisitTypeNode(typeUnion, changes, deletions, insertions);
+ }
+#endif
+ public virtual Expression VisitUnaryExpression(UnaryExpression unaryExpression, UnaryExpression changes, UnaryExpression deletions, UnaryExpression insertions)
+ {
+ this.UpdateSourceContext(unaryExpression, changes);
+ if (unaryExpression == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return unaryExpression;
+ }
+ public virtual Statement VisitVariableDeclaration(VariableDeclaration variableDeclaration, VariableDeclaration changes, VariableDeclaration deletions, VariableDeclaration insertions)
+ {
+ this.UpdateSourceContext(variableDeclaration, changes);
+ if (variableDeclaration == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return variableDeclaration;
+ }
+ public virtual UsedNamespace VisitUsedNamespace(UsedNamespace usedNamespace, UsedNamespace changes, UsedNamespace deletions, UsedNamespace insertions)
+ {
+ this.UpdateSourceContext(usedNamespace, changes);
+ if (usedNamespace == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return usedNamespace;
+ }
+ public virtual UsedNamespaceList VisitUsedNamespaceList(UsedNamespaceList usedNspaces, UsedNamespaceList changes, UsedNamespaceList deletions, UsedNamespaceList insertions)
+ {
+ if (usedNspaces == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return usedNspaces;
+ }
+ public virtual Statement VisitWhile(While While, While changes, While deletions, While insertions)
+ {
+ this.UpdateSourceContext(While, changes);
+ if (While == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return While;
+ }
+ public virtual Statement VisitYield(Yield Yield, Yield changes, Yield deletions, Yield insertions)
+ {
+ this.UpdateSourceContext(Yield, changes);
+ if (Yield == null) return changes;
+ if (changes != null)
+ {
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else
+ {
+ }
+ }
+ else if (deletions != null)
+ return null;
+ return Yield;
+ }
+#if ExtendedRuntime
+ // query nodes
+ public virtual Node VisitQueryAggregate(QueryAggregate qa, QueryAggregate changes, QueryAggregate deletions, QueryAggregate insertions){
+ this.UpdateSourceContext(qa, changes);
+ if (qa == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qa;
+ }
+ public virtual Node VisitQueryAlias(QueryAlias alias, QueryAlias changes, QueryAlias deletions, QueryAlias insertions){
+ this.UpdateSourceContext(alias, changes);
+ if (alias == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return alias;
+ }
+ public virtual Node VisitQueryAxis(QueryAxis axis, QueryAxis changes, QueryAxis deletions, QueryAxis insertions){
+ this.UpdateSourceContext(axis, changes);
+ if (axis == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return axis;
+ }
+ public virtual Node VisitQueryCommit(QueryCommit qc, QueryCommit changes, QueryCommit deletions, QueryCommit insertions){
+ this.UpdateSourceContext(qc, changes);
+ if (qc == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qc;
+ }
+ public virtual Node VisitQueryContext(QueryContext context, QueryContext changes, QueryContext deletions, QueryContext insertions){
+ this.UpdateSourceContext(context, changes);
+ if (context == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return context;
+ }
+ public virtual Node VisitQueryDelete(QueryDelete delete, QueryDelete changes, QueryDelete deletions, QueryDelete insertions){
+ this.UpdateSourceContext(delete, changes);
+ if (delete == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return delete;
+ }
+ public virtual Node VisitQueryDifference(QueryDifference diff, QueryDifference changes, QueryDifference deletions, QueryDifference insertions){
+ this.UpdateSourceContext(diff, changes);
+ if (diff == null) return changes;
+ return diff;
+ }
+ public virtual Node VisitQueryDistinct(QueryDistinct distinct, QueryDistinct changes, QueryDistinct deletions, QueryDistinct insertions){
+ this.UpdateSourceContext(distinct, changes);
+ if (distinct == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return distinct;
+ }
+ public virtual Node VisitQueryExists(QueryExists exists, QueryExists changes, QueryExists deletions, QueryExists insertions){
+ this.UpdateSourceContext(exists, changes);
+ if (exists == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return exists;
+ }
+ public virtual Node VisitQueryFilter(QueryFilter filter, QueryFilter changes, QueryFilter deletions, QueryFilter insertions){
+ this.UpdateSourceContext(filter, changes);
+ if (filter == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return filter;
+ }
+ public virtual Node VisitQueryGroupBy(QueryGroupBy groupby, QueryGroupBy changes, QueryGroupBy deletions, QueryGroupBy insertions){
+ this.UpdateSourceContext(groupby, changes);
+ if (groupby == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return groupby;
+ }
+ public virtual Statement VisitQueryGeneratedType(QueryGeneratedType qgt, QueryGeneratedType changes, QueryGeneratedType deletions, QueryGeneratedType insertions){
+ this.UpdateSourceContext(qgt, changes);
+ if (qgt == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qgt;
+ }
+ public virtual Node VisitQueryInsert(QueryInsert insert, QueryInsert changes, QueryInsert deletions, QueryInsert insertions){
+ this.UpdateSourceContext(insert, changes);
+ if (insert == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return insert;
+ }
+ public virtual Node VisitQueryIntersection(QueryIntersection intersection, QueryIntersection changes, QueryIntersection deletions, QueryIntersection insertions){
+ this.UpdateSourceContext(intersection, changes);
+ if (intersection == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return intersection;
+ }
+ public virtual Node VisitQueryIterator(QueryIterator xiterator, QueryIterator changes, QueryIterator deletions, QueryIterator insertions){
+ this.UpdateSourceContext(xiterator, changes);
+ if (xiterator == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return xiterator;
+ }
+ public virtual Node VisitQueryJoin(QueryJoin join, QueryJoin changes, QueryJoin deletions, QueryJoin insertions){
+ this.UpdateSourceContext(join, changes);
+ if (join == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return join;
+ }
+ public virtual Node VisitQueryLimit(QueryLimit limit, QueryLimit changes, QueryLimit deletions, QueryLimit insertions){
+ this.UpdateSourceContext(limit, changes);
+ if (limit == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return limit;
+ }
+ public virtual Node VisitQueryOrderBy(QueryOrderBy orderby, QueryOrderBy changes, QueryOrderBy deletions, QueryOrderBy insertions){
+ this.UpdateSourceContext(orderby, changes);
+ if (orderby == null) return changes;
+ return orderby;
+ }
+ public virtual Node VisitQueryOrderItem(QueryOrderItem item, QueryOrderItem changes, QueryOrderItem deletions, QueryOrderItem insertions){
+ this.UpdateSourceContext(item, changes);
+ if (item == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return item;
+ }
+ public virtual Node VisitQueryPosition(QueryPosition position, QueryPosition changes, QueryPosition deletions, QueryPosition insertions){
+ this.UpdateSourceContext(position, changes);
+ if (position == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return position;
+ }
+ public virtual Node VisitQueryProject(QueryProject project, QueryProject changes, QueryProject deletions, QueryProject insertions){
+ this.UpdateSourceContext(project, changes);
+ if (project == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return project;
+ }
+ public virtual Node VisitQueryRollback(QueryRollback qr, QueryRollback changes, QueryRollback deletions, QueryRollback insertions){
+ this.UpdateSourceContext(qr, changes);
+ if (qr == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qr;
+ }
+ public virtual Node VisitQueryQuantifier(QueryQuantifier qq, QueryQuantifier changes, QueryQuantifier deletions, QueryQuantifier insertions){
+ this.UpdateSourceContext(qq, changes);
+ if (qq == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qq;
+ }
+ public virtual Node VisitQueryQuantifiedExpression(QueryQuantifiedExpression qqe, QueryQuantifiedExpression changes, QueryQuantifiedExpression deletions, QueryQuantifiedExpression insertions){
+ this.UpdateSourceContext(qqe, changes);
+ if (qqe == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qqe;
+ }
+ public virtual Node VisitQuerySelect(QuerySelect select, QuerySelect changes, QuerySelect deletions, QuerySelect insertions){
+ this.UpdateSourceContext(select, changes);
+ if (select == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return select;
+ }
+ public virtual Node VisitQuerySingleton(QuerySingleton singleton, QuerySingleton changes, QuerySingleton deletions, QuerySingleton insertions){
+ this.UpdateSourceContext(singleton, changes);
+ if (singleton == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return singleton;
+ }
+ public virtual Node VisitQueryTransact(QueryTransact qt, QueryTransact changes, QueryTransact deletions, QueryTransact insertions){
+ this.UpdateSourceContext(qt, changes);
+ if (qt == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return qt;
+ }
+ public virtual Node VisitQueryTypeFilter(QueryTypeFilter filter, QueryTypeFilter changes, QueryTypeFilter deletions, QueryTypeFilter insertions){
+ this.UpdateSourceContext(filter, changes);
+ if (filter == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return filter;
+ }
+ public virtual Node VisitQueryUnion(QueryUnion union, QueryUnion changes, QueryUnion deletions, QueryUnion insertions){
+ this.UpdateSourceContext(union, changes);
+ if (union == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return union;
+ }
+ public virtual Node VisitQueryUpdate(QueryUpdate update, QueryUpdate changes, QueryUpdate deletions, QueryUpdate insertions){
+ this.UpdateSourceContext(update, changes);
+ if (update == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return update;
+ }
+ public virtual Node VisitQueryYielder(QueryYielder yielder, QueryYielder changes, QueryYielder deletions, QueryYielder insertions){
+ this.UpdateSourceContext(yielder, changes);
+ if (yielder == null) return changes;
+ if (changes != null){
+ if (deletions == null || insertions == null)
+ Debug.Assert(false);
+ else{
+ }
+ }else if (deletions != null)
+ return null;
+ return yielder;
+ }
+#endif
+ }
+}
+#endif \ No newline at end of file
diff --git a/tools/Sandcastle/Source/CCI/Writer.cs b/tools/Sandcastle/Source/CCI/Writer.cs
new file mode 100644
index 0000000..28a3668
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/Writer.cs
@@ -0,0 +1,6397 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+#if !NoWriter
+using System;
+using System.Collections;
+#if CCINamespace
+using Microsoft.Cci.Metadata;
+#else
+using System.Compiler.Metadata;
+#endif
+using System.Diagnostics;
+using System.IO;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Security;
+#if !ROTOR
+using System.Security.Cryptography;
+#endif
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !ROTOR
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006"), SuppressUnmanagedCodeSecurity]
+ interface ISymUnmanagedDocumentWriter
+ {
+ void SetSource(uint sourceSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] source);
+ void SetCheckSum(ref Guid algorithmId, uint checkSumSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] checkSum);
+ };
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2DE91396-3844-3B1D-8E91-41C24FD672EA"), SuppressUnmanagedCodeSecurity]
+ interface ISymUnmanagedWriter
+ {
+ ISymUnmanagedDocumentWriter DefineDocument(string url, ref Guid language, ref Guid languageVendor, ref Guid documentType);
+ void SetUserEntryPoint(uint entryMethod);
+ void OpenMethod(uint method);
+ void CloseMethod();
+ uint OpenScope(uint startOffset);
+ void CloseScope(uint endOffset);
+ void SetScopeRange(uint scopeID, uint startOffset, uint endOffset);
+ void DefineLocalVariable(string name, uint attributes, uint cSig, IntPtr signature, uint addrKind, uint addr1, uint addr2, uint startOffset, uint endOffset);
+ void DefineParameter(string name, uint attributes, uint sequence, uint addrKind, uint addr1, uint addr2, uint addr3);
+ void DefineField(uint parent, string name, uint attributes, uint cSig, IntPtr signature, uint addrKind, uint addr1, uint addr2, uint addr3);
+ void DefineGlobalVariable(string name, uint attributes, uint cSig, IntPtr signature, uint addrKind, uint addr1, uint addr2, uint addr3);
+ void Close();
+ void SetSymAttribute(uint parent, string name, uint cData, IntPtr signature);
+ void OpenNamespace(string name);
+ void CloseNamespace();
+ void UsingNamespace(string fullName);
+ void SetMethodSourceRange(ISymUnmanagedDocumentWriter startDoc, uint startLine, uint startColumn, object endDoc, uint endLine, uint endColumn);
+ void Initialize([MarshalAs(UnmanagedType.IUnknown)]object emitter, string filename, [MarshalAs(UnmanagedType.IUnknown)]object pIStream, bool fFullBuild);
+ void GetDebugInfo(ref ImageDebugDirectory pIDD, uint cData, out uint pcData, IntPtr data);
+ void DefineSequencePoints(ISymUnmanagedDocumentWriter document, uint spCount,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] offsets,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] lines,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] columns,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] endLines,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint[] endColumns);
+ void RemapToken(uint oldToken, uint newToken);
+ void Initialize2([MarshalAs(UnmanagedType.IUnknown)]object emitter, string tempfilename, [MarshalAs(UnmanagedType.IUnknown)]object pIStream, bool fFullBuild, string finalfilename);
+ void DefineConstant(string name, object value, uint cSig, IntPtr signature);
+ }
+ struct ImageDebugDirectory
+ {
+ internal int Characteristics;
+ internal int TimeDateStamp;
+ internal short MajorVersion;
+ internal short MinorVersion;
+ internal int Type;
+ internal int SizeOfData;
+ internal int AddressOfRawData;
+ internal int PointerToRawData;
+ public ImageDebugDirectory(bool zeroFill)
+ {
+ this.Characteristics = 0;
+ this.TimeDateStamp = 0;
+ this.MajorVersion = 0;
+ this.MinorVersion = 0;
+ this.Type = 0;
+ this.SizeOfData = 0;
+ this.AddressOfRawData = 0;
+ this.PointerToRawData = 0;
+ }
+ }
+
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")]
+ unsafe public interface IMetaDataEmit
+ {
+ void SetModuleProps(string szName);
+ void Save(string szFile, uint dwSaveFlags);
+ void SaveToStream(void* pIStream, uint dwSaveFlags);
+ uint GetSaveSize(uint fSave);
+ uint DefineTypeDef(char* szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements);
+ uint DefineNestedType(char* szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements, uint tdEncloser);
+ void SetHandler([MarshalAs(UnmanagedType.IUnknown), In]object pUnk);
+ uint DefineMethod(uint td, char* zName, uint dwMethodFlags, byte* pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags);
+ void DefineMethodImpl(uint td, uint tkBody, uint tkDecl);
+ uint DefineTypeRefByName(uint tkResolutionScope, char* szName);
+ uint DefineImportType(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue, IMetaDataImport pImport,
+ uint tdImport, IntPtr pAssemEmit);
+ uint DefineMemberRef(uint tkImport, string szName, byte* pvSigBlob, uint cbSigBlob);
+ uint DefineImportMember(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue,
+ IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent);
+ uint DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint* rmdOtherMethods);
+ void SetClassLayout(uint td, uint dwPackSize, COR_FIELD_OFFSET* rFieldOffsets, uint ulClassSize);
+ void DeleteClassLayout(uint td);
+ void SetFieldMarshal(uint tk, byte* pvNativeType, uint cbNativeType);
+ void DeleteFieldMarshal(uint tk);
+ uint DefinePermissionSet(uint tk, uint dwAction, void* pvPermission, uint cbPermission);
+ void SetRVA(uint md, uint ulRVA);
+ uint GetTokenFromSig(byte* pvSig, uint cbSig);
+ uint DefineModuleRef(string szName);
+ void SetParent(uint mr, uint tk);
+ uint GetTokenFromTypeSpec(byte* pvSig, uint cbSig);
+ void SaveToMemory(void* pbData, uint cbData);
+ uint DefineUserString(string szString, uint cchString);
+ void DeleteToken(uint tkObj);
+ void SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags);
+ void SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements);
+ void SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint* rmdOtherMethods);
+ uint SetPermissionSetProps(uint tk, uint dwAction, void* pvPermission, uint cbPermission);
+ void DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);
+ void SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL);
+ void DeletePinvokeMap(uint tk);
+ uint DefineCustomAttribute(uint tkObj, uint tkType, void* pCustomAttribute, uint cbCustomAttribute);
+ void SetCustomAttributeValue(uint pcv, void* pCustomAttribute, uint cbCustomAttribute);
+ uint DefineField(uint td, string szName, uint dwFieldFlags, byte* pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, void* pValue, uint cchValue);
+ uint DefineProperty(uint td, string szProperty, uint dwPropFlags, byte* pvSig, uint cbSig, uint dwCPlusTypeFlag,
+ void* pValue, uint cchValue, uint mdSetter, uint mdGetter, uint* rmdOtherMethods);
+ uint DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue);
+ void SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue);
+ void SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue, uint mdSetter, uint mdGetter, uint* rmdOtherMethods);
+ void SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue);
+ uint DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs);
+ void ApplyEditAndContinue([MarshalAs(UnmanagedType.IUnknown)]object pImport);
+ uint TranslateSigWithScope(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue,
+ IMetaDataImport import, byte* pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, byte* pvTranslatedSig, uint cbTranslatedSigMax);
+ void SetMethodImplFlags(uint md, uint dwImplFlags);
+ void SetFieldRVA(uint fd, uint ulRVA);
+ void Merge(IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs(UnmanagedType.IUnknown)]object pHandler);
+ void MergeEnd();
+ }
+ public struct COR_FIELD_OFFSET
+ {
+ public uint ridOfField;
+ public uint ulOffset;
+ }
+ [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
+ unsafe public interface IMetaDataImport
+ {
+ [PreserveSig]
+ void CloseEnum(uint hEnum);
+ uint CountEnum(uint hEnum);
+ void ResetEnum(uint hEnum, uint ulPos);
+ uint EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax);
+ uint EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax);
+ uint EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax);
+ uint FindTypeDefByName(string szTypeDef, uint tkEnclosingClass);
+ Guid GetScopeProps(StringBuilder szName, uint cchName, out uint pchName);
+ uint GetModuleFromScope();
+ uint GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags);
+ uint GetInterfaceImplProps(uint iiImpl, out uint pClass);
+ uint GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName);
+ uint ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope);
+ uint EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax);
+ uint EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax);
+ uint EnumMethods(ref uint phEnum, uint cl, uint* rMethods, uint cMax);
+ uint EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax);
+ uint EnumFields(ref uint phEnum, uint cl, uint* rFields, uint cMax);
+ uint EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax);
+ uint EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax);
+ uint EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax);
+ uint EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax);
+ uint EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission,
+ uint cMax);
+ uint FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
+ uint FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
+ uint FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
+ uint FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob);
+ uint GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr,
+ IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA);
+ unsafe uint GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob);
+ uint EnumProperties(ref uint phEnum, uint td, uint* rProperties, uint cMax);
+ uint EnumEvents(ref uint phEnum, uint td, uint* rEvents, uint cMax);
+ uint GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags,
+ out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax);
+ uint EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax);
+ uint GetMethodSemantics(uint mb, uint tkEventProp);
+ uint GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] COR_FIELD_OFFSET[] rFieldOffset, uint cMax, out uint pcFieldOffset);
+ unsafe uint GetFieldMarshal(uint tk, out byte* ppvNativeType);
+ uint GetRVA(uint tk, out uint pulCodeRVA);
+ unsafe uint GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission);
+ unsafe uint GetSigFromToken(uint mdSig, out byte* ppvSig);
+ uint GetModuleRefProps(uint mur, StringBuilder szName, uint cchName);
+ uint EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax);
+ unsafe uint GetTypeSpecFromToken(uint typespec, out byte* ppvSig);
+ uint GetNameFromToken(uint tk);
+ uint EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax);
+ uint GetUserString(uint stk, StringBuilder szString, uint cchString);
+ uint GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName);
+ uint EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax);
+ uint EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax);
+ uint EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax);
+ [PreserveSig]
+ int GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam);
+ uint EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax);
+ uint GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob);
+ uint FindTypeRef(uint tkResolutionScope, string szName);
+ uint GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr,
+ out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue);
+ uint GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr,
+ out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue);
+ uint GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags,
+ out byte* ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter,
+ out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)] uint[] rmdOtherMethod, uint cMax);
+ uint GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName,
+ out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue);
+ uint GetCustomAttributeByName(uint tkObj, string szName, out void* ppData);
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ bool IsValidToken(uint tk);
+ uint GetNestedClassProps(uint tdNestedClass);
+ uint GetNativeCallConvFromSig(void* pvSig, uint cbSig);
+ int IsGlobal(uint pd);
+ }
+ [SuppressUnmanagedCodeSecurity]
+ internal sealed class Ir2md : IMetaDataEmit, IMetaDataImport
+ {
+#else
+ internal sealed class Ir2md{
+#endif
+ private AssemblyNode assembly;
+ private Module/*!*/ module;
+ private MetadataWriter/*!*/ writer;
+ private bool UseGenerics = false;
+ private bool StripOptionalModifiersFromLocals
+ {
+ get { return this.module.StripOptionalModifiersFromLocals; }
+ }
+ private BinaryWriter/*!*/ blobHeap = new BinaryWriter(new MemoryStream(), System.Text.Encoding.Unicode);
+#if WHIDBEYwithGenerics || WHIDBEYwithGenericsAndIEqualityComparer
+ private Hashtable/*!*/ blobHeapIndex = new Hashtable(new ByteArrayKeyComparer());
+#else
+ private Hashtable/*!*/ blobHeapIndex = new Hashtable(new ByteArrayHasher(), new ByteArrayComparer());
+#endif
+ private Hashtable/*!*/ blobHeapStringIndex = new Hashtable();
+ private NodeList/*!*/ nodesWithCustomAttributes = new NodeList();
+ private int customAttributeCount = 0;
+ private NodeList/*!*/ nodesWithSecurityAttributes = new NodeList();
+ private int securityAttributeCount = 0;
+ private NodeList/*!*/ constantTableEntries = new NodeList();
+ private TrivialHashtable/*!*/ assemblyRefIndex = new TrivialHashtable();
+ private AssemblyReferenceList/*!*/ assemblyRefEntries = new AssemblyReferenceList();
+ private TypeNodeList/*!*/ classLayoutEntries = new TypeNodeList();
+ private TrivialHashtable/*!*/ documentMap = new TrivialHashtable();
+ private TrivialHashtable/*!*/ eventIndex = new TrivialHashtable();
+ private EventList/*!*/ eventEntries = new EventList();
+ private TrivialHashtable/*!*/ eventMapIndex = new TrivialHashtable();
+ private EventList/*!*/ eventMapEntries = new EventList();
+ private TrivialHashtable/*!*/ exceptionBlock = new TrivialHashtable();
+ private TrivialHashtable/*!*/ fieldIndex = new TrivialHashtable();
+ private FieldList/*!*/ fieldEntries = new FieldList();
+ private FieldList/*!*/ fieldLayoutEntries = new FieldList();
+ private FieldList/*!*/ fieldRvaEntries = new FieldList();
+ private Hashtable/*!*/ fileTableIndex = new Hashtable();
+ private ModuleList/*!*/ fileTableEntries = new ModuleList();
+ private Hashtable/*!*/ genericParamIndex = new Hashtable();
+ private MemberList/*!*/ genericParamEntries = new MemberList();
+ private TypeNodeList/*!*/ genericParameters = new TypeNodeList();
+ private TypeNodeList/*!*/ genericParamConstraintEntries = new TypeNodeList();
+ private ArrayList/*!*/ guidEntries = new ArrayList();
+ private Hashtable/*!*/ guidIndex = new Hashtable();
+ private MethodList/*!*/ implMapEntries = new MethodList();
+ private TypeNodeList/*!*/ interfaceEntries = new TypeNodeList();
+ private NodeList/*!*/ marshalEntries = new NodeList();
+ private TrivialHashtable/*!*/ memberRefIndex = new TrivialHashtable();
+ private MemberList/*!*/ memberRefEntries = new MemberList();
+ private TrivialHashtable/*!*/ methodBodiesHeapIndex = new TrivialHashtable();
+ private BinaryWriter/*!*/ methodBodiesHeap = new BinaryWriter(new MemoryStream());
+ private BinaryWriter/*!*/ methodBodyHeap;
+ private MethodList/*!*/ methodEntries = new MethodList();
+ private TrivialHashtable/*!*/ methodIndex = new TrivialHashtable();
+ private MethodList/*!*/ methodImplEntries = new MethodList();
+ private MethodInfo/*!*/ methodInfo;
+ private Method currentMethod;
+ private MemberList/*!*/ methodSemanticsEntries = new MemberList();
+ private MethodList/*!*/ methodSpecEntries = new MethodList();
+ private Hashtable/*!*/ methodSpecIndex = new Hashtable();
+ private ModuleReferenceList/*!*/ moduleRefEntries = new ModuleReferenceList();
+ private Hashtable/*!*/ moduleRefIndex = new Hashtable();
+ private TypeNodeList/*!*/ nestedClassEntries = new TypeNodeList();
+ private TrivialHashtable/*!*/ paramIndex = new TrivialHashtable();
+ private ParameterList/*!*/ paramEntries = new ParameterList();
+ private TrivialHashtable/*!*/ propertyIndex = new TrivialHashtable();
+ private PropertyList/*!*/ propertyEntries = new PropertyList();
+ private TrivialHashtable/*!*/ propertyMapIndex = new TrivialHashtable();
+ private PropertyList/*!*/ propertyMapEntries = new PropertyList();
+ private BinaryWriter/*!*/ resourceDataHeap = new BinaryWriter(new MemoryStream());
+ private BinaryWriter/*!*/ sdataHeap = new BinaryWriter(new MemoryStream());
+#if !ROTOR
+ private ISymUnmanagedWriter symWriter = null;
+#endif
+ private int stackHeight;
+ private int stackHeightMax;
+ private int stackHeightExitTotal;
+ private ArrayList/*!*/ standAloneSignatureEntries = new ArrayList();
+ private BinaryWriter/*!*/ stringHeap = new BinaryWriter(new MemoryStream());
+ private Hashtable/*!*/ stringHeapIndex = new Hashtable();
+ private BinaryWriter/*!*/ tlsHeap = new BinaryWriter(new MemoryStream());
+ private TrivialHashtable/*!*/ typeDefIndex = new TrivialHashtable();
+ private TypeNodeList/*!*/ typeDefEntries = new TypeNodeList();
+ private TrivialHashtable/*!*/ typeRefIndex = new TrivialHashtable();
+ private TypeNodeList/*!*/ typeRefEntries = new TypeNodeList();
+ private TrivialHashtable/*!*/ typeSpecIndex = new TrivialHashtable();
+ private TypeNodeList/*!*/ typeSpecEntries = new TypeNodeList();
+ private TrivialHashtable/*!*/ typeParameterNumber = new TrivialHashtable();
+ private BinaryWriter/*!*/ userStringHeap = new BinaryWriter(new MemoryStream(), System.Text.Encoding.Unicode);
+ private Hashtable/*!*/ userStringHeapIndex = new Hashtable();
+ private byte[] PublicKey;
+
+ internal Ir2md(Module/*!*/ module)
+ {
+ this.assembly = module as AssemblyNode;
+ this.module = module;
+ //^ base();
+ this.blobHeap.Write((byte)0);
+ this.stringHeap.Write((byte)0);
+ this.userStringHeap.Write((byte)0);
+ if (this.assembly != null)
+ this.PublicKey = this.assembly.PublicKeyOrToken;
+ }
+ internal static void WritePE(Module/*!*/ module, string debugSymbolsLocation, BinaryWriter/*!*/ writer)
+ {
+ Ir2md ir2md = new Ir2md(module);
+ try
+ {
+ ir2md.SetupMetadataWriter(debugSymbolsLocation);
+ MetadataWriter mdWriter = ir2md.writer;
+ mdWriter.WritePE(writer);
+ }
+ finally
+ {
+#if !ROTOR
+ if (ir2md.symWriter != null)
+ ir2md.symWriter.Close();
+#endif
+ ir2md.assembly = null;
+ ir2md.assemblyRefEntries = null;
+ ir2md.assemblyRefIndex = null;
+ ir2md.blobHeap = null;
+ ir2md.blobHeapIndex = null;
+ ir2md.blobHeapStringIndex = null;
+ ir2md.classLayoutEntries = null;
+ ir2md.constantTableEntries = null;
+ ir2md.documentMap = null;
+ ir2md.eventEntries = null;
+ ir2md.eventIndex = null;
+ ir2md.eventMapEntries = null;
+ ir2md.eventMapIndex = null;
+ ir2md.exceptionBlock = null;
+ ir2md.fieldEntries = null;
+ ir2md.fieldIndex = null;
+ ir2md.fieldLayoutEntries = null;
+ ir2md.fieldRvaEntries = null;
+ ir2md.fileTableEntries = null;
+ ir2md.fileTableIndex = null;
+ ir2md.genericParamConstraintEntries = null;
+ ir2md.genericParamEntries = null;
+ ir2md.genericParameters = null;
+ ir2md.genericParamIndex = null;
+ ir2md.guidEntries = null;
+ ir2md.guidIndex = null;
+ ir2md.implMapEntries = null;
+ ir2md.interfaceEntries = null;
+ ir2md.marshalEntries = null;
+ ir2md.memberRefEntries = null;
+ ir2md.memberRefIndex = null;
+ ir2md.methodBodiesHeap = null;
+ ir2md.methodBodiesHeapIndex = null;
+ ir2md.methodBodyHeap = null;
+ ir2md.methodEntries = null;
+ ir2md.methodImplEntries = null;
+ ir2md.methodIndex = null;
+ ir2md.methodInfo = null;
+ ir2md.currentMethod = null;
+ ir2md.methodSemanticsEntries = null;
+ ir2md.methodSpecEntries = null;
+ ir2md.methodSpecIndex = null;
+ ir2md.module = null;
+ ir2md.moduleRefEntries = null;
+ ir2md.moduleRefIndex = null;
+ ir2md.nestedClassEntries = null;
+ ir2md.nodesWithCustomAttributes = null;
+ ir2md.nodesWithSecurityAttributes = null;
+ ir2md.paramEntries = null;
+ ir2md.paramIndex = null;
+ ir2md.propertyEntries = null;
+ ir2md.propertyIndex = null;
+ ir2md.propertyMapEntries = null;
+ ir2md.propertyMapIndex = null;
+ ir2md.PublicKey = null;
+ ir2md.resourceDataHeap = null;
+ ir2md.sdataHeap = null;
+ ir2md.standAloneSignatureEntries = null;
+ ir2md.stringHeap = null;
+ ir2md.stringHeapIndex = null;
+#if !ROTOR
+ ir2md.symWriter = null;
+#endif
+ ir2md.tlsHeap = null;
+ ir2md.typeDefEntries = null;
+ ir2md.typeDefIndex = null;
+ ir2md.typeParameterNumber = null;
+ ir2md.typeRefEntries = null;
+ ir2md.typeRefIndex = null;
+ ir2md.typeSpecEntries = null;
+ ir2md.typeSpecIndex = null;
+ ir2md.unspecializedFieldFor = null;
+ ir2md.unspecializedMethodFor = null;
+ ir2md.userStringHeap = null;
+ ir2md.userStringHeapIndex = null;
+ ir2md.writer = null;
+ ir2md = null;
+ }
+ }
+
+ private static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
+ private static Guid IID_IClassFactory = new Guid("00000001-0000-0000-C000-000000000046");
+
+ [ComImport(), Guid("00000001-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+ interface IClassFactory
+ {
+ int CreateInstance(
+ [In, MarshalAs(UnmanagedType.Interface)] object unused,
+ [In] ref Guid refiid,
+ [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
+ int LockServer(
+ int fLock);
+ }
+
+ delegate int GetClassObjectDelegate([In] ref Guid refclsid,
+ [In] ref Guid refiid,
+ [MarshalAs(UnmanagedType.Interface)] out IClassFactory ppUnk);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
+ private static extern int LoadLibrary(string lpFileName);
+ [DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
+ private static extern GetClassObjectDelegate GetProcAddress(int hModule, string lpProcName);
+
+ private object CrossCompileActivate(string server, Guid guid)
+ {
+ // Poor man's version of Activator.CreateInstance or CoCreate
+ object o = null;
+ int hmod = LoadLibrary(server);
+ if (hmod != 0)
+ {
+ GetClassObjectDelegate del = GetProcAddress(hmod, "DllGetClassObject");
+ if (del != null)
+ {
+ IClassFactory icf;
+ int hr = del(ref guid, ref IID_IClassFactory, out icf);
+ if (hr == 0 && icf != null)
+ {
+ object temp = null;
+ hr = icf.CreateInstance(null, ref IID_IUnknown, out temp);
+ if (hr == 0) o = temp;
+ }
+ }
+ }
+ return o;
+ }
+ private void SetupMetadataWriter(string debugSymbolsLocation)
+ {
+ Version v = TargetPlatform.TargetVersion;
+ this.UseGenerics = TargetPlatform.UseGenerics;
+#if !ROTOR
+ if (debugSymbolsLocation != null)
+ {
+ // If targeting RTM (Version.Major = 1 and Version.Minor = 0)
+ // then use Symwriter.pdb as ProgID else use CorSymWriter_SxS
+ // (Note that RTM version 1.0.3705 has Assembly version 1.0.3300,
+ // hence the <= 3705 expression. This also leaves room for RTM SP releases
+ // with slightly different build numbers).
+ Type t = null;
+ if (v.Major == 1 && v.Minor == 0 && v.Build <= 3705)
+ {
+ try
+ {
+ t = Type.GetTypeFromProgID("Symwriter.pdb", false);
+ this.symWriter = (ISymUnmanagedWriter)Activator.CreateInstance(t);
+ if (this.symWriter != null)
+ this.symWriter.Initialize(this, debugSymbolsLocation, null, true);
+ }
+ catch (Exception)
+ {
+ t = null;
+ this.symWriter = null;
+ }
+ }
+ if (t == null)
+ {
+ Debug.Assert(this.symWriter == null);
+ t = Type.GetTypeFromProgID("CorSymWriter_SxS", false);
+ if (t != null)
+ {
+ Guid guid = t.GUID;
+
+ // If the compiler was built with Whidbey, then mscoree will pick a matching
+ // diasymreader.dll out of the Whidbey directory. But if we are cross-
+ // compiling, this is *NOT* what we want. Instead, we want to override
+ // the shim's logic and explicitly pick a diasymreader.dll from the place
+ // that matches the version of the output file we are emitting. This is
+ // strictly illegal by the CLR's rules. However, the CLR does not yet
+ // support cross-compilation, so we have little choice.
+ if (!UseGenerics)
+ {
+ Version vcompiler = typeof(object).Assembly.GetName().Version;
+ if (vcompiler.Major >= 2)
+ {
+ // This is the only cross-compilation case we currently support.
+ string server = Path.Combine(Path.GetDirectoryName(typeof(object).Assembly.Location),
+ "..\\v1.1.4322\\diasymreader.dll");
+ object o = CrossCompileActivate(server, guid);
+ this.symWriter = (ISymUnmanagedWriter)o;
+ }
+ }
+ if (this.symWriter == null)
+ {
+ this.symWriter = (ISymUnmanagedWriter)Activator.CreateInstance(t);
+ }
+ if (this.symWriter != null)
+ this.symWriter.Initialize(this, debugSymbolsLocation, null, true);
+ }
+ else
+ {
+ throw new DebugSymbolsCouldNotBeWrittenException();
+ }
+ }
+ }
+#endif
+ //Visit the module, building lists etc.
+ this.VisitModule(this.module);
+ //Use the lists to populate the tables in the metadata writer
+#if !ROTOR
+ MetadataWriter writer = this.writer = new MetadataWriter(this.symWriter);
+#else
+ MetadataWriter writer = this.writer = new MetadataWriter();
+#endif
+ writer.UseGenerics = this.UseGenerics;
+ if (module.EntryPoint != null)
+ {
+ writer.entryPointToken = this.GetMethodToken(module.EntryPoint);
+#if !ROTOR
+ if (this.symWriter != null) this.symWriter.SetUserEntryPoint((uint)writer.entryPointToken);
+#endif
+ }
+ writer.moduleKind = module.Kind;
+ writer.peKind = module.PEKind;
+ writer.TrackDebugData = module.TrackDebugData;
+ writer.fileAlignment = module.FileAlignment;
+ if (writer.fileAlignment < 512) writer.fileAlignment = 512;
+ writer.PublicKey = this.PublicKey;
+ if (this.assembly != null) this.PopulateAssemblyTable();
+ this.PopulateClassLayoutTable();
+ this.PopulateConstantTable();
+ this.PopulateGenericParamTable(); //Needs to happen before PopulateCustomAttributeTable since it the latter refers to indices in the sorted table
+ this.PopulateCustomAttributeTable();
+ this.PopulateDeclSecurityTable();
+ this.PopulateEventMapTable();
+ this.PopulateEventTable();
+ this.PopulateExportedTypeTable();
+ this.PopulateFieldTable();
+ this.PopulateFieldLayoutTable();
+ this.PopulateFieldRVATable();
+ this.PopulateManifestResourceTable(); //This needs to happen before PopulateFileTable because resources are not visited separately
+ this.PopulateFileTable();
+ this.PopulateGenericParamConstraintTable();
+ this.PopulateImplMapTable();
+ this.PopulateInterfaceImplTable();
+ this.PopulateMarshalTable();
+ this.PopulateMethodTable();
+ this.PopulateMethodImplTable();
+ this.PopulateMemberRefTable();
+ this.PopulateMethodSemanticsTable();
+ this.PopulateMethodSpecTable();
+ this.PopulateModuleTable();
+ this.PopulateModuleRefTable();
+ this.PopulateNestedClassTable();
+ this.PopulateParamTable();
+ this.PopulatePropertyTable();
+ this.PopulatePropertyMapTable();
+ this.PopulateStandAloneSigTable();
+ this.PopulateTypeDefTable();
+ this.PopulateTypeRefTable();
+ this.PopulateTypeSpecTable();
+ this.PopulateGuidTable();
+ this.PopulateAssemblyRefTable();
+ this.writer.BlobHeap = (MemoryStream)this.blobHeap.BaseStream; //this.blobHeap = null;
+ this.writer.SdataHeap = (MemoryStream)this.sdataHeap.BaseStream; //this.sdataHeap = null;
+ this.writer.TlsHeap = (MemoryStream)this.tlsHeap.BaseStream; //this.tlsHeap = null;
+ this.writer.StringHeap = (MemoryStream)this.stringHeap.BaseStream; //this.stringHeap = null;
+ this.writer.UserstringHeap = (MemoryStream)this.userStringHeap.BaseStream; //this.userStringHeap = null;
+ this.writer.MethodBodiesHeap = (MemoryStream)this.methodBodiesHeap.BaseStream; //this.methodBodiesHeap = null;
+ this.writer.ResourceDataHeap = (MemoryStream)this.resourceDataHeap.BaseStream; //this.resourceDataHeap = null;
+ this.writer.Win32Resources = this.module.Win32Resources;
+ }
+ int GetAssemblyRefIndex(AssemblyNode/*!*/ assembly)
+ {
+ if (assembly.Location == "unknown:location")
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.UnresolvedAssemblyReferenceNotAllowed, assembly.Name));
+ Object index = this.assemblyRefIndex[assembly.UniqueKey];
+ if (index == null)
+ {
+ index = this.assemblyRefEntries.Count + 1;
+ AssemblyReference aref = new AssemblyReference(assembly);
+ if (this.module.UsePublicKeyTokensForAssemblyReferences)
+ {
+ aref.PublicKeyOrToken = aref.PublicKeyToken;
+ aref.HashValue = null;
+ aref.Flags = aref.Flags & ~AssemblyFlags.PublicKey;
+ }
+ this.assemblyRefEntries.Add(aref);
+ this.assemblyRefIndex[assembly.UniqueKey] = index;
+ }
+ return (int)index;
+ }
+ int GetBlobIndex(ExpressionList expressions, ParameterList parameters)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ this.WriteCustomAttributeSignature(expressions, parameters, false, signature);
+ byte[] sigBytes = sig.ToArray();
+ int length = sigBytes.Length;
+ int index = (int)this.blobHeap.BaseStream.Position;
+ Ir2md.WriteCompressedInt(this.blobHeap, length);
+ this.blobHeap.BaseStream.Write(sigBytes, 0, length);
+ return index;
+ }
+ void WriteCustomAttributeSignature(ExpressionList expressions, ParameterList parameters, bool onlyWriteNamedArguments, BinaryWriter signature)
+ {
+ int n = parameters == null ? 0 : parameters.Count;
+ int m = expressions == null ? 0 : expressions.Count;
+ Debug.Assert(m >= n);
+ int numNamed = m > n ? m - n : 0;
+ if (onlyWriteNamedArguments)
+ {
+ Ir2md.WriteCompressedInt(signature, numNamed);
+ }
+ else
+ {
+ signature.Write((short)1);
+ if (parameters != null && expressions != null)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = parameters[i];
+ Expression e = expressions[i];
+ if (p == null || e == null) continue;
+ Literal l = e as Literal;
+ if (l == null) { Debug.Assert(false); continue; }
+ this.WriteCustomAttributeLiteral(signature, l, p.Type == CoreSystemTypes.Object);
+ }
+ }
+ signature.Write((short)numNamed);
+ }
+ if (expressions != null)
+ {
+ for (int i = n; i < m; i++)
+ {
+ Expression e = expressions[i];
+ NamedArgument narg = e as NamedArgument;
+ if (narg == null) { Debug.Assert(false); continue; }
+ signature.Write((byte)(narg.IsCustomAttributeProperty ? 0x54 : 0x53));
+ if (narg.ValueIsBoxed)
+ signature.Write((byte)ElementType.BoxedEnum);
+ else if (narg.Value.Type is EnumNode)
+ {
+ signature.Write((byte)ElementType.Enum);
+ this.WriteSerializedTypeName(signature, narg.Value.Type);
+ }
+ else if (narg.Value.Type == CoreSystemTypes.Type)
+ signature.Write((byte)ElementType.Type);
+ else if (narg.Value.Type is ArrayType)
+ {
+ ArrayType arrT = (ArrayType)narg.Value.Type;
+ if (arrT.ElementType == CoreSystemTypes.Type)
+ {
+ signature.Write((byte)ElementType.SzArray);
+ signature.Write((byte)ElementType.Type);
+ }
+ else
+ this.WriteTypeSignature(signature, narg.Value.Type);
+ }
+ else
+ this.WriteTypeSignature(signature, narg.Value.Type);
+ signature.Write(narg.Name.Name, false);
+ this.WriteCustomAttributeLiteral(signature, (Literal)narg.Value, narg.ValueIsBoxed);
+ }
+ }
+ }
+ int GetBlobIndex(byte[]/*!*/ blob)
+ {
+ object indexOb = this.blobHeapIndex[blob];
+ if (indexOb != null) return (int)indexOb;
+ int index = (int)this.blobHeap.BaseStream.Position;
+ int length = blob.Length;
+ Ir2md.WriteCompressedInt(this.blobHeap, length);
+ this.blobHeap.BaseStream.Write(blob, 0, length);
+ this.blobHeapIndex[blob] = index;
+ return index;
+ }
+ int GetBlobIndex(string/*!*/ str)
+ {
+ object indexOb = this.blobHeapStringIndex[str];
+ if (indexOb != null) return (int)indexOb;
+ int index = (int)this.blobHeap.BaseStream.Position;
+ this.blobHeap.Write((string)str);
+ this.blobHeapStringIndex[str] = index;
+ return index;
+ }
+ int GetBlobIndex(Field/*!*/ field)
+ {
+ if (field != null && field.DeclaringType != null && field.DeclaringType.Template != null && field.DeclaringType.Template.IsGeneric)
+ field = this.GetUnspecializedField(field);
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ signature.Write((byte)0x6);
+ TypeNode fieldType = field.Type;
+#if ExtendedRuntime
+ if (field.HasOutOfBandContract) fieldType = TypeNode.DeepStripModifiers(fieldType, null, SystemTypes.NonNullType);
+#endif
+ if (fieldType == null) { Debug.Fail(""); fieldType = SystemTypes.Object; }
+ this.WriteTypeSignature(signature, fieldType, true);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetBlobIndex(MarshallingInformation/*!*/ marshallingInformation)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ signature.Write((byte)marshallingInformation.NativeType);
+ switch (marshallingInformation.NativeType)
+ {
+ case NativeType.SafeArray:
+ signature.Write((byte)marshallingInformation.ElementType);
+ if (marshallingInformation.Class != null && marshallingInformation.Class.Length > 0)
+ signature.Write(marshallingInformation.Class, false);
+ break;
+ case NativeType.LPArray:
+ signature.Write((byte)marshallingInformation.ElementType);
+ if (marshallingInformation.ParamIndex >= 0 || marshallingInformation.ElementSize > 0)
+ {
+ if (marshallingInformation.ParamIndex < 0)
+ {
+ Debug.Fail("MarshallingInformation.ElementSize > 0 should imply that ParamIndex >= 0");
+ marshallingInformation.ParamIndex = 0;
+ }
+ Ir2md.WriteCompressedInt(signature, marshallingInformation.ParamIndex);
+ }
+ if (marshallingInformation.ElementSize > 0)
+ {
+ Ir2md.WriteCompressedInt(signature, marshallingInformation.ElementSize);
+ if (marshallingInformation.NumberOfElements > 0)
+ Ir2md.WriteCompressedInt(signature, marshallingInformation.NumberOfElements);
+ }
+ break;
+ case NativeType.ByValArray:
+ Ir2md.WriteCompressedInt(signature, marshallingInformation.Size);
+ if (marshallingInformation.ElementType != NativeType.NotSpecified)
+ signature.Write((byte)marshallingInformation.ElementType);
+ break;
+ case NativeType.ByValTStr:
+ Ir2md.WriteCompressedInt(signature, marshallingInformation.Size);
+ break;
+ case NativeType.CustomMarshaler:
+ signature.Write((short)0);
+ signature.Write(marshallingInformation.Class);
+ signature.Write(marshallingInformation.Cookie);
+ break;
+ }
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetBlobIndex(Literal/*!*/ literal)
+ {
+ int index = (int)this.blobHeap.BaseStream.Position;
+ TypeNode lType = literal.Type;
+ EnumNode eType = lType as EnumNode;
+ if (eType != null) lType = eType.UnderlyingType;
+ IConvertible ic = literal.Value as IConvertible;
+ if (ic == null) ic = "";
+ switch (lType.typeCode)
+ {
+ case ElementType.Boolean: this.blobHeap.Write((byte)1); this.blobHeap.Write(ic.ToBoolean(null)); break;
+ case ElementType.Char: this.blobHeap.Write((byte)2); this.blobHeap.Write(ic.ToChar(null)); break;
+ case ElementType.Int8: this.blobHeap.Write((byte)1); this.blobHeap.Write(ic.ToSByte(null)); break;
+ case ElementType.UInt8: this.blobHeap.Write((byte)1); this.blobHeap.Write(ic.ToByte(null)); break;
+ case ElementType.Int16: this.blobHeap.Write((byte)2); this.blobHeap.Write(ic.ToInt16(null)); break;
+ case ElementType.UInt16: this.blobHeap.Write((byte)2); this.blobHeap.Write(ic.ToUInt16(null)); break;
+ case ElementType.Int32: this.blobHeap.Write((byte)4); this.blobHeap.Write(ic.ToInt32(null)); break;
+ case ElementType.UInt32: this.blobHeap.Write((byte)4); this.blobHeap.Write(ic.ToUInt32(null)); break;
+ case ElementType.Int64: this.blobHeap.Write((byte)8); this.blobHeap.Write(ic.ToInt64(null)); break;
+ case ElementType.UInt64: this.blobHeap.Write((byte)8); this.blobHeap.Write(ic.ToUInt64(null)); break;
+ case ElementType.Single: this.blobHeap.Write((byte)4); this.blobHeap.Write(ic.ToSingle(null)); break;
+ case ElementType.Double: this.blobHeap.Write((byte)8); this.blobHeap.Write(ic.ToDouble(null)); break;
+ case ElementType.String: this.blobHeap.Write((string)literal.Value, false); break;
+ case ElementType.Array:
+ case ElementType.Class:
+ case ElementType.Object:
+ case ElementType.Reference:
+ case ElementType.SzArray: this.blobHeap.Write((byte)4); this.blobHeap.Write((int)0); break; //REVIEW: standard implies this should be 0, peverify thinks otherwise.
+ default: Debug.Assert(false, "Unexpected Literal type"); return 0;
+ }
+ return index;
+ }
+ int GetBlobIndex(FunctionPointer/*!*/ fp)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ this.WriteMethodSignature(signature, fp);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetBlobIndex(Method/*!*/ method, bool methodSpecSignature)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ if (methodSpecSignature)
+ this.WriteMethodSpecSignature(signature, method);
+ else
+ this.WriteMethodSignature(signature, method);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetBlobIndex(AttributeList/*!*/ securityAttributes)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ signature.Write((byte)'.');
+ Ir2md.WriteCompressedInt(signature, securityAttributes.Count);
+ foreach (AttributeNode attr in securityAttributes)
+ this.WriteSecurityAttribute(signature, attr);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ private void WriteSecurityAttribute(BinaryWriter signature, AttributeNode attr)
+ {
+ this.WriteSerializedTypeName(signature, attr.Type);
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter casig = new BinaryWriter(sig);
+ MemberBinding mb = attr.Constructor as MemberBinding;
+ if (mb == null) return;
+ InstanceInitializer constructor = mb.BoundMember as InstanceInitializer;
+ if (constructor == null) return;
+ this.WriteCustomAttributeSignature(attr.Expressions, constructor.Parameters, true, casig);
+ byte[] sigBytes = sig.ToArray();
+ int length = sigBytes.Length;
+ Ir2md.WriteCompressedInt(signature, length);
+ signature.BaseStream.Write(sigBytes, 0, length);
+ }
+ int GetBlobIndex(Property/*!*/ prop)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ this.WritePropertySignature(signature, prop);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetBlobIndex(TypeNode/*!*/ type)
+ {
+ MemoryStream sig = new MemoryStream();
+ BinaryWriter signature = new BinaryWriter(sig);
+ this.WriteTypeSignature(signature, type, true);
+ return this.GetBlobIndex(sig.ToArray());
+ }
+ int GetCustomAttributeParentCodedIndex(Node/*!*/ node)
+ {
+ switch (node.NodeType)
+ {
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ case NodeType.Method: return this.GetMethodIndex((Method)node) << 5;
+ case NodeType.Field: return (this.GetFieldIndex((Field)node) << 5) | 1;
+ case NodeType.Parameter: return (this.GetParamIndex((Parameter)node) << 5) | 4;
+ case NodeType.Class:
+ case NodeType.DelegateNode:
+ case NodeType.EnumNode:
+ case NodeType.Interface:
+ case NodeType.Struct:
+#if !MinimalReader
+ case NodeType.TupleType:
+ case NodeType.TypeAlias:
+ case NodeType.TypeIntersection:
+ case NodeType.TypeUnion:
+#endif
+ TypeNode t = (TypeNode)node;
+ if (this.IsStructural(t) && (!t.IsGeneric || (t.Template != null && t.ConsolidatedTemplateArguments != null && t.ConsolidatedTemplateArguments.Count > 0)))
+ return (this.GetTypeSpecIndex(t) << 5) | 13;
+ else
+ return (this.GetTypeDefIndex(t) << 5) | 3;
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ if (!this.UseGenerics) goto case NodeType.Class;
+ return (this.GetGenericParamIndex((TypeNode)node) << 5) | 19;
+ case NodeType.Property: return (this.GetPropertyIndex((Property)node) << 5) | 9;
+ case NodeType.Event: return (this.GetEventIndex((Event)node) << 5) | 10;
+ case NodeType.Module: return (1 << 5) | 7;
+ case NodeType.Assembly: return (1 << 5) | 14;
+ default: Debug.Assert(false, "Unexpect custom attribute parent"); return 0;
+ }
+ }
+#if !ROTOR
+ ISymUnmanagedDocumentWriter GetDocumentWriter(Document/*!*/ doc)
+ //^ requires this.symWriter != null;
+ {
+ int key = Identifier.For(doc.Name).UniqueIdKey;
+ object writer = this.documentMap[key];
+ if (writer == null)
+ {
+ writer = this.symWriter.DefineDocument(doc.Name, ref doc.Language, ref doc.LanguageVendor, ref doc.DocumentType);
+ this.documentMap[key] = writer;
+ }
+ return (ISymUnmanagedDocumentWriter)writer;
+ }
+#endif
+ int GetEventIndex(Event/*!*/ e)
+ {
+ return (int)this.eventIndex[e.UniqueKey];
+ }
+ int GetFieldIndex(Field/*!*/ f)
+ {
+ Object index = this.fieldIndex[f.UniqueKey];
+ if (index == null)
+ {
+ if (this.fieldEntries == null) return 1;
+ index = this.fieldEntries.Count + 1;
+ this.fieldEntries.Add(f);
+ this.fieldIndex[f.UniqueKey] = index;
+ if (f.DefaultValue != null && !(f.DefaultValue.Value is Parameter))
+ this.constantTableEntries.Add(f);
+ if (!f.IsStatic && f.DeclaringType != null && (f.DeclaringType.Flags & TypeFlags.ExplicitLayout) != 0)
+ this.fieldLayoutEntries.Add(f);
+ if ((f.Flags & FieldFlags.HasFieldRVA) != 0)
+ this.fieldRvaEntries.Add(f);
+ if (f.MarshallingInformation != null)
+ this.marshalEntries.Add(f);
+ }
+ return (int)index;
+ }
+ int GetGenericParamIndex(TypeNode/*!*/ gp)
+ {
+ return (int)this.genericParamIndex[gp.UniqueKey];
+ }
+ int GetFieldToken(Field/*!*/ f)
+ {
+ if (f.DeclaringType == null || (f.DeclaringType.DeclaringModule == this.module && !this.IsStructural(f.DeclaringType)))
+ return 0x04000000 | this.GetFieldIndex(f);
+ else
+ return 0x0a000000 | this.GetMemberRefIndex(f);
+ }
+ bool IsStructural(TypeNode type)
+ {
+ if (type == null) return false;
+ if (this.UseGenerics && (type.IsGeneric || type.Template != null && type.Template.IsGeneric)) return true;
+ switch (type.NodeType)
+ {
+ case NodeType.ArrayType:
+ case NodeType.Pointer:
+ case NodeType.Reference:
+ case NodeType.OptionalModifier:
+ case NodeType.RequiredModifier:
+ return true;
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ return this.UseGenerics;
+ }
+ return false;
+ }
+ int GetFileTableIndex(Module/*!*/ module)
+ {
+ Object index = this.fileTableIndex[module];
+ if (index == null)
+ {
+ index = this.fileTableEntries.Count + 1;
+ this.fileTableEntries.Add(module);
+ this.fileTableIndex[module] = index;
+ }
+ return (int)index;
+ }
+ int GetGuidIndex(Guid guid)
+ {
+ Object index = this.guidIndex[guid];
+ if (index == null)
+ {
+ index = this.guidEntries.Count + 1;
+ this.guidEntries.Add(guid);
+ this.guidIndex[guid] = index;
+ }
+ return (int)index;
+ }
+ internal int GetLocalVarIndex(Local/*!*/ loc)
+ {
+#if !MinimalReader
+ LocalBinding lb = loc as LocalBinding;
+ if (lb != null) loc = lb.BoundLocal;
+#endif
+ if (this.StripOptionalModifiersFromLocals)
+ loc.Type = TypeNode.StripModifiers(loc.Type);
+ MethodInfo methInfo = this.methodInfo;
+
+ if (methInfo.localVarSignature == null)
+ {
+ methInfo.localVarSignature = new BinaryWriter(new MemoryStream());
+ methInfo.localVarSignature.Write((short)0);
+ methInfo.localVarIndex = new TrivialHashtable();
+ methInfo.localVarSigTok = 0x11000000 | this.GetStandAloneSignatureIndex(methInfo.localVarSignature);
+ }
+ object index = methInfo.localVarIndex[loc.UniqueKey];
+ if (index == null)
+ {
+ methInfo.localVarIndex[loc.UniqueKey] = index = methInfo.localVarIndex.Count;
+#if !ROTOR
+ int startPosition = 0;
+ if (this.symWriter != null && loc.Name != null && loc.Name.UniqueIdKey != Identifier.Empty.UniqueIdKey)
+ {
+ methInfo.debugLocals.Add(loc);
+ methInfo.signatureOffsets.Add(startPosition = methInfo.localVarSignature.BaseStream.Position);
+ if (loc.Pinned) methInfo.localVarSignature.Write((byte)ElementType.Pinned);
+ this.WriteTypeSignature(methInfo.localVarSignature, loc.Type, true);
+ methInfo.signatureLengths.Add(methInfo.localVarSignature.BaseStream.Position - startPosition);
+ }
+ else
+ {
+#endif
+ if (loc.Pinned) methInfo.localVarSignature.Write((byte)ElementType.Pinned);
+ this.WriteTypeSignature(methInfo.localVarSignature, loc.Type, true);
+#if !ROTOR
+ }
+#endif
+ }
+ return (int)index;
+ }
+ int GetMemberRefParentEncoded(TypeNode type)
+ {
+ if (type == null) return 0;
+ if (this.IsStructural(type)) return (this.GetTypeSpecIndex(type) << 3) | 4;
+ if (type.DeclaringModule == this.module) return this.GetTypeDefIndex(type) << 3;
+ if (type.DeclaringModule != null) return (this.GetTypeRefIndex(type) << 3) | 1;
+ if (type.typeCode == ElementType.Class || type.typeCode == ElementType.ValueType)
+ return this.GetTypeDefIndex(type) << 3; //REVIEW: when does this happen?
+ Debug.Assert(false);
+ return 0;
+ }
+ int GetMemberRefIndex(Member/*!*/ m)
+ {
+ Object index = this.memberRefIndex[m.UniqueKey];
+ if (index == null)
+ {
+ index = this.memberRefEntries.Count + 1;
+ this.memberRefEntries.Add(m);
+ this.memberRefIndex[m.UniqueKey] = index;
+ TypeNode type = m.DeclaringType;
+ this.VisitReferencedType(type);
+ }
+ return (int)index;
+ }
+ class VarargMethodCallSignature : FunctionPointer
+ {
+ internal Method method;
+ internal VarargMethodCallSignature(Method/*!*/ method, TypeNodeList/*!*/ parameterTypes)
+ : base(parameterTypes, method.ReturnType, method.Name)
+ {
+ this.method = method;
+ this.DeclaringType = method.DeclaringType;
+ }
+ }
+ int GetMemberRefToken(Method/*!*/ m, ExpressionList arguments)
+ {
+ int numArgs = arguments == null ? 0 : arguments.Count;
+ TypeNodeList parTypes = new TypeNodeList(numArgs);
+ int varArgStart = m.Parameters.Count;
+ for (int i = 0; i < varArgStart; i++)
+ parTypes.Add(m.Parameters[i].Type);
+ for (int i = varArgStart; i < numArgs; i++)
+ {
+ //^ assert arguments != null;
+ parTypes.Add(arguments[i].Type);
+ }
+ VarargMethodCallSignature sig = new VarargMethodCallSignature(m, parTypes);
+ sig.VarArgStart = varArgStart;
+ sig.CallingConvention = m.CallingConvention;
+ return 0x0a000000 | this.GetMemberRefIndex(sig);
+ }
+ int GetMethodDefOrRefEncoded(Method/*!*/ m)
+ {
+ if (m.DeclaringType.DeclaringModule == this.module && !this.IsStructural(m.DeclaringType))
+ return this.GetMethodIndex(m) << 1;
+ else
+ return (this.GetMemberRefIndex(m) << 1) | 0x1;
+ }
+ int GetMethodIndex(Method/*!*/ m)
+ {
+ Object index = this.methodIndex[m.UniqueKey];
+ if (index == null)
+ {
+ if (this.methodEntries == null) return 1;
+ index = this.methodEntries.Count + 1;
+ this.methodEntries.Add(m);
+ this.methodIndex[m.UniqueKey] = index;
+ if (m.ReturnTypeMarshallingInformation != null || (m.ReturnAttributes != null && m.ReturnAttributes.Count > 0))
+ {
+ Parameter p = new Parameter();
+ p.ParameterListIndex = -1;
+ p.Attributes = m.ReturnAttributes;
+ if (m.ReturnTypeMarshallingInformation != null)
+ {
+ p.MarshallingInformation = m.ReturnTypeMarshallingInformation;
+ p.Flags = ParameterFlags.HasFieldMarshal;
+ this.marshalEntries.Add(p);
+ }
+ this.paramEntries.Add(p);
+ this.paramIndex[m.UniqueKey] = this.paramEntries.Count;
+ this.paramIndex[p.UniqueKey] = this.paramEntries.Count;
+ this.VisitAttributeList(p.Attributes, p);
+ }
+ int offset = m.IsStatic ? 0 : 1;
+ if (m.Parameters != null)
+ {
+ for (int i = 0, n = m.Parameters.Count; i < n; i++)
+ {
+ Parameter p = m.Parameters[i];
+ if (p == null) continue;
+ if (p == null) continue;
+ if (p.DeclaringMethod == null) p.DeclaringMethod = m;
+ p.ParameterListIndex = i;
+ p.ArgumentListIndex = i + offset;
+ int j = this.paramEntries.Count + 1;
+ this.paramEntries.Add(p); //TODO: provide a way to suppress the param table entries unless param has custom attributes or flags
+ this.paramIndex[p.UniqueKey] = j;
+ if (p.DefaultValue != null)
+ this.constantTableEntries.Add(p);
+ if (p.MarshallingInformation != null)
+ this.marshalEntries.Add(p);
+ }
+ }
+ if (m.IsGeneric)
+ this.VisitGenericParameterList(m, m.TemplateParameters);
+ }
+ return (int)index;
+ }
+ int GetMethodSpecIndex(Method/*!*/ m)
+ {
+ int structuralKey = m.UniqueKey;
+ int blobIndex = this.GetBlobIndex(m, true);
+ if (m.Template != null)
+ structuralKey = (m.Template.UniqueKey << 8) + blobIndex;
+ else
+ Debug.Assert(false);
+ Object index = this.methodSpecIndex[m.UniqueKey];
+ if (index == null)
+ {
+ index = this.methodSpecIndex[structuralKey];
+ if (index is int)
+ {
+ Method otherMethod = this.methodSpecEntries[((int)index) - 1];
+ if (otherMethod != null && otherMethod.Template == m.Template && blobIndex == this.GetBlobIndex(otherMethod, true))
+ return (int)index;
+ }
+ index = this.methodSpecEntries.Count + 1;
+ this.methodSpecEntries.Add(m);
+ this.methodSpecIndex[m.UniqueKey] = index;
+ this.methodSpecIndex[structuralKey] = index;
+ this.GetMemberRefIndex(m.Template);
+ Method templ = m.Template;
+ if (templ != null)
+ {
+ while (templ.Template != null) templ = templ.Template;
+ TypeNodeList templParams = templ.TemplateParameters;
+ if (templParams != null)
+ {
+ for (int i = 0, n = templParams.Count; i < n; i++)
+ {
+ TypeNode templParam = templParams[i];
+ if (templParam == null) continue;
+ this.typeParameterNumber[templParam.UniqueKey] = -(i + 1);
+ }
+ }
+ }
+ }
+ return (int)index;
+ }
+ int GetMethodToken(Method/*!*/ m)
+ {
+ if (this.UseGenerics && m.Template != null && m.Template.IsGeneric)
+ return 0x2b000000 | this.GetMethodSpecIndex(m);
+ else if (m.DeclaringType.DeclaringModule == this.module && !this.IsStructural(m.DeclaringType))
+ return 0x06000000 | this.GetMethodIndex(m);
+ else
+ return 0x0a000000 | this.GetMemberRefIndex(m);
+ }
+ int GetMethodDefToken(Method/*!*/ m)
+ {
+ if (m.DeclaringType.DeclaringModule == this.module)
+ return 0x06000000 | this.GetMethodIndex(m);
+ else
+ return 0x0a000000 | this.GetMemberRefIndex(m);
+ }
+ int GetMethodBodiesHeapIndex(Method/*!*/ m)
+ {
+ return (int)this.methodBodiesHeapIndex[m.UniqueKey];
+ }
+ int GetModuleRefIndex(Module/*!*/ module)
+ {
+ if (module.Location == "unknown:location") throw new InvalidOperationException(ExceptionStrings.UnresolvedModuleReferenceNotAllowed);
+ Object index = this.moduleRefIndex[module.Name];
+ if (index == null)
+ {
+ index = this.moduleRefEntries.Count + 1;
+ this.moduleRefEntries.Add(new ModuleReference(module.Name, module));
+ this.moduleRefIndex[module.Name] = index;
+ if (module.HashValue != null && module.HashValue.Length > 0)
+ this.GetFileTableIndex(module);
+ }
+ return (int)index;
+ }
+ int GetOffset(Block target, int addressOfNextInstruction)
+ {
+ if (target == null) return 0;
+ int fixupLocation = (int)(this.methodBodyHeap.BaseStream.Position);
+ Object ob = this.methodInfo.fixupIndex[target.UniqueKey];
+ if (ob is int) return ((int)ob) - addressOfNextInstruction;
+ Fixup fixup = new Fixup();
+ fixup.addressOfNextInstruction = addressOfNextInstruction;
+ fixup.fixupLocation = fixupLocation;
+ fixup.shortOffset = false;
+ fixup.nextFixUp = (Fixup)ob;
+ this.methodInfo.fixupIndex[target.UniqueKey] = fixup;
+ return 0;
+ }
+ int GetOffset(Block target, ref bool shortOffset)
+ {
+ if (target == null) return 0;
+ int fixupLocation = (int)(this.methodBodyHeap.BaseStream.Position + 1);
+ Object ob = this.methodInfo.fixupIndex[target.UniqueKey];
+ if (ob is int)
+ {
+ int targetAddress = (int)ob;
+ int offset = targetAddress - (fixupLocation + 1);
+ if (-128 > offset || offset > 127)
+ {
+ offset = targetAddress - (fixupLocation + 4);
+ Debug.Assert(offset < -128, "Forward short branch out of range");
+ shortOffset = false;
+ }
+ else
+ shortOffset = true;
+ return offset;
+ }
+ Fixup fixup = new Fixup();
+ fixup.fixupLocation = fixup.addressOfNextInstruction = fixupLocation;
+ if (shortOffset) fixup.addressOfNextInstruction += 1; else fixup.addressOfNextInstruction += 4;
+ fixup.shortOffset = shortOffset;
+ fixup.nextFixUp = (Fixup)ob;
+ this.methodInfo.fixupIndex[target.UniqueKey] = fixup;
+ return 0;
+ }
+ int GetParamIndex(Parameter p)
+ {
+ if (p == null) return 0;
+#if !MinimalReader
+ ParameterBinding pb = p as ParameterBinding;
+ if (pb != null) p = pb.BoundParameter;
+#endif
+ return (int)this.paramIndex[p.UniqueKey];
+ }
+ int GetPropertyIndex(Property/*!*/ p)
+ {
+ return (int)this.propertyIndex[p.UniqueKey];
+ }
+ int GetSecurityAttributeParentCodedIndex(Node/*!*/ node)
+ {
+ switch (node.NodeType)
+ {
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ case NodeType.Method: return (this.GetMethodIndex((Method)node) << 2) | 1;
+ case NodeType.Class:
+ case NodeType.Interface:
+ case NodeType.DelegateNode:
+ case NodeType.EnumNode:
+ case NodeType.Struct: return (this.GetTypeDefIndex((TypeNode)node) << 2) | 0;
+ case NodeType.Assembly: return (1 << 2) | 2;
+ default: Debug.Assert(false, "Unexpected security attribute parent"); return 0;
+ }
+ }
+ int GetStandAloneSignatureIndex(BinaryWriter signatureWriter)
+ {
+ this.standAloneSignatureEntries.Add(signatureWriter);
+ return this.standAloneSignatureEntries.Count;
+ }
+ int GetStaticDataIndex(byte[] data, PESection targetSection)
+ {
+ int result = 0;
+ switch (targetSection)
+ {
+ case PESection.SData:
+ result = (int)this.sdataHeap.BaseStream.Position;
+ this.sdataHeap.Write(data);
+ break;
+ case PESection.Text:
+ result = (int)this.methodBodiesHeap.BaseStream.Position;
+ this.methodBodiesHeap.Write(data);
+ break;
+ case PESection.TLS:
+ result = (int)this.tlsHeap.BaseStream.Position;
+ this.tlsHeap.Write(data);
+ break;
+ }
+ return result;
+ }
+ int GetResourceDataIndex(byte[]/*!*/ data)
+ {
+ int index = (int)this.resourceDataHeap.BaseStream.Position;
+ this.resourceDataHeap.Write((int)data.Length);
+ this.resourceDataHeap.Write(data);
+ return index;
+ }
+ int GetStringIndex(string str)
+ {
+ if (str == null || str.Length == 0) return 0;
+ Object index = this.stringHeapIndex[str];
+ if (index == null)
+ {
+ index = (int)this.stringHeap.BaseStream.Position;
+ this.stringHeap.Write(str, true);
+ this.stringHeapIndex[str] = index;
+ }
+ return (int)index;
+ }
+ int GetUserStringIndex(string/*!*/ str)
+ {
+ Object index = this.userStringHeapIndex[str];
+ if (index == null)
+ {
+ index = (int)this.userStringHeap.BaseStream.Position;
+ Ir2md.WriteCompressedInt(this.userStringHeap, str.Length * 2 + 1);
+ this.userStringHeap.Write(str.ToCharArray());
+ this.userStringHeapIndex[str] = index;
+ //Write out a trailing byte indicating if the string is really quite simple
+ ulong stringKind = 0; //no funny business
+ foreach (char ch in str)
+ {
+ if (ch >= 0x7F) stringKind += 1;
+ else
+ switch ((int)ch)
+ {
+ case 0x1:
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0x7:
+ case 0x8:
+ case 0xE:
+ case 0xF:
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1A:
+ case 0x1B:
+ case 0x1C:
+ case 0x1D:
+ case 0x1E:
+ case 0x1F:
+ case 0x27:
+ case 0x2D:
+ stringKind += 1;
+ break;
+ default:
+ break;
+ }
+ }
+ if (stringKind > 0) stringKind = 1;
+ this.userStringHeap.Write((byte)stringKind);
+ }
+ return (int)index;
+ }
+ int GetTypeDefIndex(TypeNode/*!*/ type)
+ {
+ Object index = this.typeDefIndex[type.UniqueKey];
+ if (index == null)
+ {
+ if (this.typeDefEntries == null) return 0;
+ index = this.typeDefEntries.Count + 1;
+ this.typeDefEntries.Add(type);
+ this.typeDefIndex[type.UniqueKey] = index;
+ if (type.IsGeneric && type.Template == null)
+ this.VisitGenericParameterList(type, type.ConsolidatedTemplateParameters);
+ }
+ return (int)index;
+ }
+ int GetTypeDefOrRefOrSpecEncoded(TypeNode type)
+ {
+ if (type == null) return 0;
+ if (!this.UseGenerics)
+ {
+ ClassParameter cp = type as ClassParameter;
+ if (cp != null) { Debug.Assert(!cp.IsGeneric); return this.GetTypeDefOrRefOrSpecEncoded(cp.BaseClass); } //REVIEW: why???
+ }
+ if (this.IsStructural(type)) return (this.GetTypeSpecIndex(type) << 2) | 2;
+ if (type.DeclaringModule == this.module) return this.GetTypeDefIndex(type) << 2;
+ return (this.GetTypeRefIndex(type) << 2) | 1;
+ }
+ int GetTypeToken(TypeNode/*!*/ type)
+ {
+ if (this.IsStructural(type) && (!type.IsGeneric || (type.ConsolidatedTemplateArguments != null && type.ConsolidatedTemplateArguments.Count > 0)))
+ return 0x1b000000 | this.GetTypeSpecIndex(type);
+ if (type.IsGeneric)
+ {
+ TypeNode foundType = type.GetTemplateInstance(type, type.TemplateParameters);
+ Debug.Assert(foundType != type);
+ return this.GetTypeToken(foundType);
+ }
+ if (type.DeclaringModule == this.module)
+ return 0x02000000 | this.GetTypeDefIndex(type);
+ else if (type.DeclaringModule != null)
+ return 0x01000000 | this.GetTypeRefIndex(type);
+ else if (type.typeCode == ElementType.ValueType || type.typeCode == ElementType.Class)
+ {
+ type.DeclaringModule = this.module;
+ return 0x02000000 | this.GetTypeDefIndex(type);
+ }
+ Debug.Assert(false);
+ return 0;
+ }
+ int GetTypeDefToken(TypeNode/*!*/ type)
+ {
+ if (this.IsStructural(type) && (!type.IsGeneric || (type.Template != null && type.ConsolidatedTemplateArguments != null && type.ConsolidatedTemplateArguments.Count > 0)))
+ return 0x1b000000 | this.GetTypeSpecIndex(type);
+ if (type.DeclaringModule == this.module)
+ return 0x02000000 | this.GetTypeDefIndex(type);
+ else if (type.DeclaringModule != null)
+ return 0x01000000 | this.GetTypeRefIndex(type);
+ else if (type.typeCode == ElementType.ValueType || type.typeCode == ElementType.Class)
+ {
+ type.DeclaringModule = this.module;
+ return 0x02000000 | this.GetTypeDefIndex(type);
+ }
+ Debug.Assert(false);
+ return 0;
+ }
+ int GetTypeRefIndex(TypeNode/*!*/ type)
+ {
+ Object index = this.typeRefIndex[type.UniqueKey];
+ if (index == null)
+ {
+ index = this.typeRefEntries.Count + 1;
+ this.typeRefEntries.Add(type);
+ this.typeRefIndex[type.UniqueKey] = index;
+ Module module = type.DeclaringModule;
+ AssemblyNode assembly = module as AssemblyNode;
+ if (assembly != null)
+ this.GetAssemblyRefIndex(assembly);
+ else
+ this.GetModuleRefIndex(module);
+ if (type.DeclaringType != null)
+ this.GetTypeRefIndex(type.DeclaringType);
+ }
+ return (int)index;
+ }
+ int GetTypeSpecIndex(TypeNode/*!*/ type)
+ {
+ int structuralKey = type.UniqueKey;
+ int blobIndex = 0;
+ if (type.Template != null)
+ {
+ blobIndex = this.GetBlobIndex(type);
+ structuralKey = ((type.Template.UniqueKey << 8) & int.MaxValue) + blobIndex;
+ }
+ Object index = this.typeSpecIndex[type.UniqueKey];
+ if (index == null)
+ {
+ if (type.Template != null)
+ {
+ index = this.typeSpecIndex[structuralKey];
+ if (index is int)
+ {
+ TypeNode otherType = this.typeSpecEntries[((int)index) - 1];
+ if (otherType != null && otherType.Template == type.Template && blobIndex == this.GetBlobIndex(otherType))
+ return (int)index;
+ }
+ }
+ index = this.typeSpecEntries.Count + 1;
+ this.typeSpecEntries.Add(type);
+ this.typeSpecIndex[type.UniqueKey] = index;
+ if (type.Template != null)
+ this.typeSpecIndex[structuralKey] = index;
+ if (type.Template != null)
+ {
+ if (type.Template.DeclaringModule != this.module)
+ this.GetTypeRefIndex(type.Template);
+ TypeNodeList templArgs = type.ConsolidatedTemplateArguments;
+ for (int i = 0, n = templArgs == null ? 0 : templArgs.Count; i < n; i++)
+ {
+ this.VisitReferencedType(templArgs[i]);
+ }
+ }
+ else
+ {
+ TypeNodeList telems = type.StructuralElementTypes;
+ for (int i = 0, n = telems == null ? 0 : telems.Count; i < n; i++)
+ this.VisitReferencedType(telems[i]);
+ }
+ }
+ return (int)index;
+ }
+ TrivialHashtable/*!*/ unspecializedFieldFor = new TrivialHashtable();
+ Field/*!*/ GetUnspecializedField(Field/*!*/ field)
+ {
+ if (field == null || field.DeclaringType == null || !field.DeclaringType.IsGeneric) { Debug.Fail(""); return field; }
+ Field unspecializedField = (Field)this.unspecializedFieldFor[field.UniqueKey];
+ if (unspecializedField != null) return unspecializedField;
+ TypeNode template = field.DeclaringType;
+ if (template == null) { Debug.Assert(false); return field; }
+ while (template.Template != null) template = template.Template;
+ MemberList specializedMembers = field.DeclaringType.Members;
+ MemberList unspecializedMembers = template.Members;
+ for (int i = 0, n = specializedMembers.Count; i < n; i++)
+ {
+ if (specializedMembers[i] != field) continue;
+ unspecializedField = (Field)unspecializedMembers[i];
+ if (unspecializedField == null) { Debug.Fail(""); unspecializedField = field; }
+ this.unspecializedFieldFor[field.UniqueKey] = unspecializedField;
+ this.VisitReferencedType(unspecializedField.DeclaringType);
+ return unspecializedField;
+ }
+ Debug.Fail("");
+ return field;
+ }
+ TrivialHashtable/*!*/ unspecializedMethodFor = new TrivialHashtable();
+ Method/*!*/ GetUnspecializedMethod(Method/*!*/ method)
+ {
+ Debug.Assert(method != null && method.DeclaringType != null && method.DeclaringType.IsGeneric);
+ Method unspecializedMethod = (Method)this.unspecializedMethodFor[method.UniqueKey];
+ if (unspecializedMethod != null) return unspecializedMethod;
+ TypeNode template = method.DeclaringType;
+ if (template == null) { Debug.Assert(false); return method; }
+ while (template.Template != null) template = template.Template;
+ MemberList specializedMembers = method.DeclaringType.Members;
+ MemberList unspecializedMembers = template.Members;
+ for (int i = 0, n = specializedMembers.Count; i < n; i++)
+ {
+ if (specializedMembers[i] != method) continue;
+ unspecializedMethod = unspecializedMembers[i] as Method;
+ if (unspecializedMethod == null) break;
+ this.unspecializedMethodFor[method.UniqueKey] = unspecializedMethod;
+ template = unspecializedMethod.DeclaringType;
+ while (template.Template != null) template = template.Template;
+ this.VisitReferencedType(template);
+ for (int j = 0, m = unspecializedMethod.TemplateParameters == null ? 0 : unspecializedMethod.TemplateParameters.Count; j < m; j++)
+ {
+ TypeNode p = unspecializedMethod.TemplateParameters[j];
+ if (p == null) continue;
+ this.typeParameterNumber[p.UniqueKey] = -(j + 1);
+ }
+ return unspecializedMethod;
+ }
+ Debug.Assert(false);
+ return method;
+ }
+ internal void IncrementStackHeight()
+ {
+ this.stackHeight++;
+ if (this.stackHeight > this.stackHeightMax) this.stackHeightMax = this.stackHeight;
+ }
+ void PopulateAssemblyTable()
+ //^ requires this.assembly != null;
+ {
+ AssemblyNode assembly = this.assembly;
+ AssemblyRow[] assemblyTable = this.writer.assemblyTable = new AssemblyRow[1];
+ assemblyTable[0].HashAlgId = (int)AssemblyHashAlgorithm.SHA1;
+ assemblyTable[0].Flags = (int)assembly.Flags;
+ if (assembly.Version == null) assembly.Version = new Version(1, 0, 0, 0);
+ assemblyTable[0].MajorVersion = assembly.Version.Major;
+ assemblyTable[0].MinorVersion = assembly.Version.Minor;
+ assemblyTable[0].RevisionNumber = assembly.Version.Revision;
+ assemblyTable[0].BuildNumber = assembly.Version.Build;
+ if (assembly.PublicKeyOrToken != null && 0 < assembly.PublicKeyOrToken.Length)
+ assemblyTable[0].PublicKey = this.GetBlobIndex(assembly.PublicKeyOrToken);
+ if (assembly.Name != null)
+ assemblyTable[0].Name = this.GetStringIndex(assembly.Name);
+ else
+ Debug.Assert(false, "Assembly must have a name");
+ if (assembly.Culture != null && assembly.Culture.Length > 0)
+ assemblyTable[0].Culture = this.GetStringIndex(assembly.Culture);
+ this.writer.assemblyTable = assemblyTable;
+ }
+ void PopulateAssemblyRefTable()
+ {
+ AssemblyReferenceList arList = this.module.AssemblyReferences = this.assemblyRefEntries;
+ if (arList == null) return;
+ int n = arList.Count;
+ AssemblyRefRow[] arRows = this.writer.assemblyRefTable = new AssemblyRefRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ AssemblyReference ar = arList[i];
+ if (ar.Version == null)
+ Debug.Assert(false, "assembly reference without a version");
+ else
+ {
+ arRows[i].MajorVersion = ar.Version.Major;
+ arRows[i].MinorVersion = ar.Version.Minor;
+ arRows[i].RevisionNumber = ar.Version.Revision;
+ arRows[i].BuildNumber = ar.Version.Build;
+ arRows[i].Flags = (int)ar.Flags;
+ }
+ if (ar.PublicKeyOrToken != null && 0 < ar.PublicKeyOrToken.Length)
+ arRows[i].PublicKeyOrToken = this.GetBlobIndex(ar.PublicKeyOrToken);
+ if (ar.Name == null)
+ Debug.Assert(false, "assembly reference without a name");
+ else
+ arRows[i].Name = this.GetStringIndex(ar.Name);
+ if (ar.Culture != null && ar.Culture.Length > 0)
+ arRows[i].Culture = this.GetStringIndex(ar.Culture);
+ if (ar.HashValue != null)
+ arRows[i].HashValue = this.GetBlobIndex(ar.HashValue);
+ }
+ //this.assemblyRefEntries = null;
+ }
+ void PopulateClassLayoutTable()
+ {
+ int n = this.classLayoutEntries.Count;
+ if (n == 0) return;
+ ClassLayoutRow[] clr = this.writer.classLayoutTable = new ClassLayoutRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.classLayoutEntries[i];
+ clr[i].ClassSize = t.ClassSize;
+ clr[i].PackingSize = t.PackingSize;
+ clr[i].Parent = this.GetTypeDefIndex(t);
+ }
+ //this.classLayoutEntries = null;
+ }
+ void PopulateConstantTable()
+ {
+ int n = this.constantTableEntries.Count;
+ if (n == 0) return;
+ ConstantRow[] cr = this.writer.constantTable = new ConstantRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = this.constantTableEntries[i] as Parameter;
+ if (p != null)
+ {
+ cr[i].Parent = (this.GetParamIndex(p) << 2) | 1;
+ cr[i].Value = this.GetBlobIndex((Literal)p.DefaultValue);
+ TypeNode t = p.DefaultValue.Type;
+ if (t.NodeType == NodeType.EnumNode) t = ((EnumNode)t).UnderlyingType;
+ cr[i].Type = (int)t.typeCode;
+ if (t is Reference || (t != p.Type && Literal.IsNullLiteral(p.DefaultValue)))
+ cr[i].Type = (int)ElementType.Class;
+ }
+ else
+ {
+ Field f = (Field)this.constantTableEntries[i];
+ cr[i].Parent = (this.GetFieldIndex(f) << 2);
+ cr[i].Value = this.GetBlobIndex(f.DefaultValue);
+ TypeNode t = f.DefaultValue.Type;
+ if (t.NodeType == NodeType.EnumNode) t = ((EnumNode)t).UnderlyingType;
+ cr[i].Type = (int)t.typeCode;
+ if (t is Reference || (t != f.Type && Literal.IsNullLiteral(f.DefaultValue)))
+ cr[i].Type = (int)ElementType.Class;
+ }
+ ConstantRow temp = cr[i];
+ int parent = temp.Parent;
+ for (int j = i - 1; j >= 0; j--)
+ {
+ if (cr[j].Parent > parent)
+ {
+ cr[j + 1] = cr[j];
+ if (j == 0)
+ {
+ cr[0] = temp;
+ break;
+ }
+ }
+ else
+ {
+ if (j < i - 1) cr[j + 1] = temp;
+ break;
+ }
+ }
+ }
+ //TODO: more efficient sort
+ //this.constantTableEntries = null;
+ }
+ void PopulateCustomAttributeTable()
+ {
+ if (this.customAttributeCount == 0) return;
+ CustomAttributeRow[] table = this.writer.customAttributeTable = new CustomAttributeRow[this.customAttributeCount];
+ int k = 0;
+ int prevCodedIndex = 0;
+ for (int i = 0, n = this.nodesWithCustomAttributes.Count; i < n; i++)
+ {
+ AttributeList attrs = null;
+ Node node = this.nodesWithCustomAttributes[i];
+ int codedIndex = 0;
+ switch (node.NodeType)
+ {
+ case NodeType.Method:
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ Method m = (Method)node;
+ codedIndex = this.GetMethodIndex(m) << 5;
+ attrs = m.Attributes;
+ break;
+ case NodeType.Field:
+ Field f = (Field)node;
+ codedIndex = (this.GetFieldIndex(f) << 5) | 1;
+ attrs = f.Attributes;
+ break;
+ case NodeType.Parameter:
+ Parameter par = (Parameter)node;
+ codedIndex = (this.GetParamIndex(par) << 5) | 4;
+ attrs = par.Attributes;
+ break;
+ case NodeType.Class:
+ case NodeType.DelegateNode:
+ case NodeType.EnumNode:
+ case NodeType.Interface:
+ case NodeType.Struct:
+#if !MinimalReader
+ case NodeType.TupleType:
+ case NodeType.TypeAlias:
+ case NodeType.TypeIntersection:
+ case NodeType.TypeUnion:
+#endif
+ TypeNode t = (TypeNode)node;
+ if (this.IsStructural(t) && (!t.IsGeneric || (t.Template != null && t.ConsolidatedTemplateArguments != null && t.ConsolidatedTemplateArguments.Count > 0)))
+ codedIndex = (this.GetTypeSpecIndex(t) << 5) | 13;
+ else
+ codedIndex = (this.GetTypeDefIndex(t) << 5) | 3;
+ attrs = t.Attributes;
+ break;
+ case NodeType.ClassParameter:
+ case NodeType.TypeParameter:
+ if (!this.UseGenerics) goto case NodeType.Class;
+ t = (TypeNode)node;
+ codedIndex = (this.GetGenericParamIndex(t) << 5) | 19;
+ attrs = t.Attributes;
+ break;
+ case NodeType.Property:
+ Property p = (Property)node;
+ codedIndex = (this.GetPropertyIndex(p) << 5) | 9;
+ attrs = p.Attributes;
+ break;
+ case NodeType.Event:
+ Event e = (Event)node;
+ codedIndex = (this.GetEventIndex(e) << 5) | 10;
+ attrs = e.Attributes;
+ break;
+ case NodeType.Module:
+ case NodeType.Assembly:
+ codedIndex = (1 << 5) | (node.NodeType == NodeType.Module ? 7 : 14);
+ attrs = ((Module)node).Attributes;
+ break;
+ default:
+ Debug.Assert(false);
+ break;
+ }
+ if (attrs == null) continue;
+ if (UseGenerics)
+ {
+ Debug.Assert(codedIndex > prevCodedIndex);
+ }
+ prevCodedIndex = codedIndex;
+ for (int j = 0, m = attrs.Count; j < m; j++)
+ {
+ AttributeNode a = attrs[j];
+ if (a == null) continue;
+ table[k].Parent = codedIndex;
+ Debug.Assert(a.Constructor is MemberBinding);
+ Method cons = (Method)((MemberBinding)a.Constructor).BoundMember;
+ if (cons.DeclaringType.DeclaringModule == this.module && !this.IsStructural(cons.DeclaringType))
+ table[k].Constructor = (this.GetMethodIndex(cons) << 3) | 2;
+ else
+ table[k].Constructor = (this.GetMemberRefIndex(cons) << 3) | 3;
+ table[k].Value = this.GetBlobIndex(a.Expressions, cons.Parameters);
+ k++;
+ }
+ }
+ }
+ void PopulateDeclSecurityTable()
+ {
+ if (this.securityAttributeCount == 0) return;
+ DeclSecurityRow[] table = this.writer.declSecurityTable = new DeclSecurityRow[this.securityAttributeCount];
+ int k = 0;
+ int prevCodedIndex = 0;
+ for (int i = 0, n = this.nodesWithSecurityAttributes.Count; i < n; i++)
+ {
+ SecurityAttributeList attrs = null;
+ Node node = this.nodesWithSecurityAttributes[i];
+ int codedIndex = 0;
+ switch (node.NodeType)
+ {
+ case NodeType.Method:
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ Method m = (Method)node;
+ codedIndex = (this.GetMethodIndex(m) << 2) | 1;
+ attrs = m.SecurityAttributes;
+ break;
+ case NodeType.Class:
+ case NodeType.Interface:
+ case NodeType.DelegateNode:
+ case NodeType.EnumNode:
+ case NodeType.Struct:
+ TypeNode t = (TypeNode)node;
+ codedIndex = (this.GetTypeDefIndex(t) << 2) | 0;
+ attrs = t.SecurityAttributes;
+ break;
+ case NodeType.Assembly:
+ codedIndex = (1 << 2) | 2;
+ attrs = ((AssemblyNode)node).SecurityAttributes;
+ break;
+ default:
+ Debug.Assert(false);
+ break;
+ }
+ if (attrs == null) continue;
+ Debug.Assert(codedIndex > prevCodedIndex);
+ prevCodedIndex = codedIndex;
+ for (int j = 0, m = attrs.Count; j < m; j++)
+ {
+ SecurityAttribute a = attrs[j];
+ if (a == null) continue;
+ this.VisitReferencedType(CoreSystemTypes.SecurityAction);
+ table[k].Action = (int)a.Action;
+ table[k].Parent = codedIndex;
+ if (CoreSystemTypes.SystemAssembly.MetadataFormatMajorVersion == 1 && CoreSystemTypes.SystemAssembly.MetadataFormatMinorVersion < 1)
+ table[k].PermissionSet = this.GetBlobIndex(a.SerializedPermissions);
+ else
+ {
+ if (a.PermissionAttributes != null)
+ {
+ table[k].PermissionSet = this.GetBlobIndex(a.PermissionAttributes);
+ }
+ else
+ {
+ // Came across some assemblies that had a metadata version > 1.0, but still used
+ // serialized security attributes. So might as well try to see if this is the case
+ // if the PermissionAttributes are null.
+ table[k].PermissionSet = this.GetBlobIndex(a.SerializedPermissions);
+ }
+ }
+ k++;
+ }
+ }
+ }
+ void PopulateEventMapTable()
+ {
+ int n = this.eventMapEntries.Count;
+ if (n == 0) return;
+ EventMapRow[] emr = this.writer.eventMapTable = new EventMapRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Event e = this.eventMapEntries[i];
+ emr[i].Parent = this.GetTypeDefIndex(e.DeclaringType);
+ emr[i].EventList = this.GetEventIndex(e);
+ }
+ //this.eventMapEntries = null;
+ }
+ void PopulateEventTable()
+ {
+ int n = this.eventEntries.Count;
+ if (n == 0) return;
+ EventRow[] er = this.writer.eventTable = new EventRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Event e = this.eventEntries[i];
+ if (e == null || e.Name == null) continue;
+ er[i].Flags = (int)e.Flags;
+ er[i].Name = this.GetStringIndex(e.Name.ToString());
+ er[i].EventType = this.GetTypeDefOrRefOrSpecEncoded(e.HandlerType);
+ }
+ //this.eventEntries = null;
+ }
+ void PopulateExportedTypeTable()
+ {
+ if (this.assembly == null) return;
+ TypeNodeList exportedTypes = this.assembly.ExportedTypes;
+ int n = exportedTypes == null ? 0 : exportedTypes.Count;
+ if (n == 0) return;
+ ExportedTypeRow[] ett = this.writer.exportedTypeTable = new ExportedTypeRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode et = exportedTypes[i];
+ if (et == null || et.Namespace == null || et.Name == null) continue;
+ ett[i].TypeDefId = 0;
+ ett[i].TypeNamespace = this.GetStringIndex(et.Namespace.ToString());
+ ett[i].TypeName = this.GetStringIndex(et.Name.ToString());
+ ett[i].Flags = (int)(et.Flags & TypeFlags.VisibilityMask);
+ if (et.DeclaringType != null)
+ {
+ for (int j = 0; j < i; j++)
+ {
+ if (exportedTypes[j] == et.DeclaringType)
+ {
+ ett[i].Implementation = (j << 2) | 2;
+ break;
+ }
+ }
+ }
+ else if (et.DeclaringModule != this.module && et.DeclaringModule is AssemblyNode)
+ {
+ ett[i].Implementation = (this.GetAssemblyRefIndex((AssemblyNode)et.DeclaringModule) << 2) | 1;
+ ett[i].Flags = (int)TypeFlags.Forwarder;
+ }
+ else
+ ett[i].Implementation = (this.GetFileTableIndex(et.DeclaringModule) << 2) | 0;
+ }
+ }
+ void PopulateFieldTable()
+ {
+ int n = this.fieldEntries.Count;
+ if (n == 0) return;
+ FieldRow[] fr = this.writer.fieldTable = new FieldRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Field f = this.fieldEntries[i];
+ fr[i].Flags = (int)f.Flags;
+ fr[i].Name = this.GetStringIndex(f.Name.Name); // we don't store prefixes in field names.
+ fr[i].Signature = this.GetBlobIndex(f);
+ }
+ //this.fieldEntries = null;
+ }
+ void PopulateFieldLayoutTable()
+ {
+ int n = this.fieldLayoutEntries.Count;
+ if (n == 0) return;
+ FieldLayoutRow[] flr = this.writer.fieldLayoutTable = new FieldLayoutRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Field f = this.fieldLayoutEntries[i];
+ flr[i].Field = this.GetFieldIndex(f);
+ flr[i].Offset = f.Offset;
+ }
+ //this.fieldLayoutEntries = null;
+ }
+ void PopulateFieldRVATable()
+ {
+ int n = this.fieldRvaEntries.Count;
+ if (n == 0) return;
+ FieldRvaRow[] frr = this.writer.fieldRvaTable = new FieldRvaRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Field f = this.fieldRvaEntries[i];
+ frr[i].Field = this.GetFieldIndex(f);
+ if (f.InitialData != null)
+ frr[i].RVA = this.GetStaticDataIndex(f.InitialData, f.Section); //Fixed up to be an RVA inside MetadataWriter.
+ else
+ frr[i].RVA = f.Offset;
+ frr[i].TargetSection = f.Section;
+ }
+ //this.fieldRvaEntries = null;
+ }
+ void PopulateFileTable()
+ {
+ int n = this.fileTableEntries.Count;
+ if (n == 0) return;
+ bool readContents = false;
+ FileRow[] ftr = this.writer.fileTable = new FileRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Module module = this.fileTableEntries[i];
+ switch (module.Kind)
+ {
+ case ModuleKindFlags.ConsoleApplication:
+ case ModuleKindFlags.DynamicallyLinkedLibrary:
+ case ModuleKindFlags.WindowsApplication:
+ ftr[i].Flags = (int)FileFlags.ContainsMetaData;
+ break;
+ case ModuleKindFlags.ManifestResourceFile:
+ readContents = true;
+ ftr[i].Flags = (int)FileFlags.ContainsNoMetaData;
+ break;
+ case ModuleKindFlags.UnmanagedDynamicallyLinkedLibrary:
+ ftr[i].Flags = (int)FileFlags.ContainsNoMetaData;
+ break;
+ }
+ if (module.HashValue != null)
+ ftr[i].HashValue = this.GetBlobIndex(module.HashValue);
+ else
+ ftr[i].HashValue = 0;
+ ftr[i].Name = this.GetStringIndex(module.Name);
+ if (readContents)
+ {
+ try
+ {
+ FileStream fs = File.OpenRead(module.Location);
+ long size = fs.Length;
+ byte[] buffer = new byte[size];
+ fs.Read(buffer, 0, (int)size);
+ System.Security.Cryptography.SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
+ byte[] hash = sha1.ComputeHash(buffer);
+ ftr[i].HashValue = this.GetBlobIndex(hash);
+ }
+ catch { }
+ }
+ }
+ //this.fileTableEntries = null;
+ }
+ void PopulateGuidTable()
+ {
+ int n = this.guidEntries.Count;
+ Guid[] guids = this.writer.GuidHeap = new Guid[n];
+ for (int i = 0; i < n; i++)
+ guids[i] = (Guid)this.guidEntries[i];
+ //this.guidEntries = null;
+ }
+ void PopulateGenericParamTable()
+ {
+ int n = this.genericParamEntries.Count;
+ if (n == 0) return;
+ GenericParamRow[] gpr = this.writer.genericParamTable = new GenericParamRow[n];
+ Member lastMember = null;
+ int number = 0;
+ for (int i = 0; i < n; i++)
+ {
+ Member m = this.genericParamEntries[i];
+ TypeNode paramType = this.genericParameters[i];
+ if (paramType == null || paramType.Name == null) continue;
+ Method meth = m as Method;
+ TypeNode type = m as TypeNode;
+ if (m != lastMember) number = 0;
+ gpr[i].GenericParameter = paramType;
+ gpr[i].Number = number++;
+ if (type != null)
+ {
+ gpr[i].Name = this.GetStringIndex(paramType.Name.ToString());
+ gpr[i].Owner = (this.GetTypeDefIndex(type) << 1) | 0;
+ }
+ else
+ {
+ //^ assert meth != null;
+ gpr[i].Name = this.GetStringIndex(paramType.Name.ToString());
+ gpr[i].Owner = (this.GetMethodIndex(meth) << 1) | 1;
+ }
+ ITypeParameter tp = paramType as ITypeParameter;
+ if (tp != null)
+ gpr[i].Flags = (int)tp.TypeParameterFlags;
+ else
+ {
+ Debug.Assert(false);
+ gpr[i].Flags = 0;
+ }
+ lastMember = m;
+ GenericParamRow temp = gpr[i];
+ int owner = temp.Owner;
+ for (int j = i - 1; j >= 0; j--)
+ {
+ if (gpr[j].Owner > owner)
+ {
+ gpr[j + 1] = gpr[j];
+ if (j == 0)
+ {
+ gpr[0] = temp;
+ break;
+ }
+ }
+ else
+ {
+ if (j < i - 1) gpr[j + 1] = temp;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < n; i++)
+ {
+ Member genPar = gpr[i].GenericParameter;
+ if (genPar == null) continue;
+ this.genericParamIndex[genPar.UniqueKey] = i + 1;
+ }
+ for (int i = 0; i < n; i++)
+ {
+ Member genPar = gpr[i].GenericParameter;
+ if (genPar == null) continue;
+ this.VisitAttributeList(genPar.Attributes, genPar);
+ }
+ //this.genericParamEntries = null;
+ //this.genericParameters = null;
+ }
+ void PopulateGenericParamConstraintTable()
+ {
+ int n = this.genericParamConstraintEntries.Count;
+ if (n == 0) return;
+ GenericParamConstraintRow[] gpcr = this.writer.genericParamConstraintTable = new GenericParamConstraintRow[n];
+ TypeNode lastParameter = null;
+ int paramIndex = 0;
+ int constraintIndex = 0;
+ int indexOffset = 0;
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.genericParamConstraintEntries[i];
+ if (t != lastParameter)
+ {
+ paramIndex = this.GetGenericParamIndex(t);
+ constraintIndex = 0;
+ indexOffset = 0;
+ }
+ gpcr[i].Param = paramIndex;
+ TypeNode constraint;
+ if (constraintIndex == 0 && t.BaseType != null && t.BaseType != CoreSystemTypes.Object)
+ {
+ constraint = t.BaseType; indexOffset = 1;
+ }
+ else
+ constraint = t.Interfaces[constraintIndex - indexOffset];
+ gpcr[i].Constraint = this.GetTypeDefOrRefOrSpecEncoded(constraint);
+ lastParameter = t;
+ constraintIndex++;
+ GenericParamConstraintRow temp = gpcr[i];
+ int param = temp.Param;
+ for (int j = i - 1; j >= 0; j--)
+ {
+ if (gpcr[j].Param > param)
+ {
+ gpcr[j + 1] = gpcr[j];
+ if (j == 0)
+ {
+ gpcr[0] = temp;
+ break;
+ }
+ }
+ else
+ {
+ if (j < i - 1) gpcr[j + 1] = temp;
+ break;
+ }
+ }
+ }
+ //this.genericParamConstraintEntries = null;
+ }
+ void PopulateImplMapTable()
+ {
+ int n = this.implMapEntries.Count;
+ if (n == 0) return;
+ ImplMapRow[] imr = this.writer.implMapTable = new ImplMapRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Method m = this.implMapEntries[i];
+ imr[i].ImportName = this.GetStringIndex(m.PInvokeImportName);
+ imr[i].ImportScope = this.GetModuleRefIndex(m.PInvokeModule);
+ imr[i].MappingFlags = (int)m.PInvokeFlags;
+ imr[i].MemberForwarded = (this.GetMethodIndex(m) << 1) | 1;
+ }
+ //this.implMapEntries = null;
+ }
+ void PopulateInterfaceImplTable()
+ {
+ int n = this.interfaceEntries.Count;
+ if (n == 0) return;
+ InterfaceImplRow[] iir = this.writer.interfaceImplTable = new InterfaceImplRow[n];
+ TypeNode prevT = null;
+ for (int i = 0, j = 0; i < n; i++)
+ {
+ TypeNode t = this.interfaceEntries[i];
+ if (t == prevT)
+ j++;
+ else
+ {
+ j = 0;
+ prevT = t;
+ }
+ int ti = iir[i].Class = this.GetTypeDefIndex(t);
+ Interface iface = null;
+#if ExtendedRuntime
+ if (t is ITypeParameter){
+ int numIfaces = t.Interfaces == null ? 0 : t.Interfaces.Count;
+ if (j == numIfaces)
+ iface = SystemTypes.ITemplateParameter;
+ else
+ iface = t.Interfaces[j];
+ }else
+#endif
+ iface = t.Interfaces[j];
+ if (iface == null) { i--; continue; }
+ int ii = iir[i].Interface = this.GetTypeDefOrRefOrSpecEncoded(iface);
+ for (int k = 0; k < i; k++)
+ { //REVIEW: is a more efficient sort worthwhile?
+ if (iir[k].Class > ti)
+ {
+ for (int kk = i; kk > k; kk--)
+ {
+ iir[kk].Class = iir[kk - 1].Class;
+ iir[kk].Interface = iir[kk - 1].Interface;
+ }
+ iir[k].Class = ti;
+ iir[k].Interface = ii;
+ break;
+ }
+ }
+ }
+ //this.interfaceEntries = null;
+ }
+ void PopulateManifestResourceTable()
+ {
+ ResourceList resources = this.module.Resources;
+ int n = resources == null ? 0 : resources.Count;
+ if (n == 0) return;
+ ManifestResourceRow[] mresources = this.writer.manifestResourceTable = new ManifestResourceRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Resource r = resources[i];
+ mresources[i].Flags = r.IsPublic ? 1 : 2;
+ mresources[i].Name = this.GetStringIndex(r.Name);
+ if (r.Data != null)
+ mresources[i].Offset = this.GetResourceDataIndex(r.Data);
+ else if (r.DefiningModule is AssemblyNode)
+ mresources[i].Implementation = (this.GetAssemblyRefIndex((AssemblyNode)r.DefiningModule) << 2) | 1;
+ else
+ mresources[i].Implementation = (this.GetFileTableIndex(r.DefiningModule) << 2) | 0;
+ }
+ }
+ void PopulateMarshalTable()
+ {
+ int n = this.marshalEntries.Count;
+ if (n == 0) return;
+ FieldMarshalRow[] fmr = this.writer.fieldMarshalTable = new FieldMarshalRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ MarshallingInformation mi;
+ Field f = this.marshalEntries[i] as Field;
+ if (f != null)
+ {
+ fmr[i].Parent = (this.GetFieldIndex(f) << 1) | 0;
+ mi = f.MarshallingInformation;
+ }
+ else
+ {
+ Parameter p = (Parameter)this.marshalEntries[i];
+ fmr[i].Parent = (this.GetParamIndex(p) << 1) | 1;
+ mi = p.MarshallingInformation;
+ }
+ int nt = fmr[i].NativeType = this.GetBlobIndex(mi);
+ int pi = fmr[i].Parent;
+ for (int k = 0; k < i; k++)
+ { //REVIEW: is a more efficient sort worthwhile?
+ if (fmr[k].Parent > pi)
+ {
+ for (int kk = i; kk > k; kk--)
+ {
+ fmr[kk].Parent = fmr[kk - 1].Parent;
+ fmr[kk].NativeType = fmr[kk - 1].NativeType;
+ }
+ fmr[k].Parent = pi;
+ fmr[k].NativeType = nt;
+ break;
+ }
+ }
+ }
+ //this.marshalEntries = null;
+ }
+ void PopulateMemberRefTable()
+ {
+ int n = this.memberRefEntries.Count;
+ if (n == 0) return;
+ MemberRefRow[] mr = this.writer.memberRefTable = new MemberRefRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Member member = this.memberRefEntries[i];
+ if (member == null || member.Name == null) continue;
+ mr[i].Name = this.GetStringIndex(member.Name.ToString());
+ Field f = member as Field;
+ if (f != null)
+ mr[i].Signature = this.GetBlobIndex(f);
+ else
+ {
+ FunctionPointer fp = member as FunctionPointer;
+ if (fp != null)
+ {
+ mr[i].Signature = this.GetBlobIndex(fp);
+ if (fp is VarargMethodCallSignature)
+ {
+ Method m = ((VarargMethodCallSignature)member).method;
+ if (m != null && m.DeclaringType.DeclaringModule == this.module && !this.IsStructural(m.DeclaringType))
+ {
+ mr[i].Class = (this.GetMethodIndex(m) << 3) | 3;
+ continue;
+ }
+ }
+ }
+ else
+ {
+ Method m = (Method)member;
+ if (m.IsGeneric && m.Template != null) m = this.GetUnspecializedMethod(m);
+ mr[i].Signature = this.GetBlobIndex(m, false);
+ if (m.DeclaringType.DeclaringModule == this.module && !this.IsStructural(m.DeclaringType) && !m.IsGeneric)
+ {
+ mr[i].Class = (this.GetMethodIndex(m) << 3) | 3;
+ continue;
+ }
+ //TODO: if the declaring type is the special global members type of another module, set class to a module ref
+ }
+ }
+ int j = mr[i].Class = this.GetMemberRefParentEncoded(member.DeclaringType);
+ if ((j & 0x3) == 2) mr[i].Class = (j & ~0x3) | 4;
+ }
+ //this.memberRefEntries = null;
+ }
+ void PopulateMethodTable()
+ {
+ int n = this.methodEntries.Count;
+ if (n == 0) return;
+ MethodRow[] mr = this.writer.methodTable = new MethodRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Method m = this.methodEntries[i];
+ if (m == null || m.Name == null) continue;
+ if (m.IsAbstract || m.Body == null || m.Body.Statements == null || m.Body.Statements.Count == 0)
+ mr[i].RVA = -1;
+ else
+ mr[i].RVA = this.GetMethodBodiesHeapIndex(m); //Fixed up to be an RVA inside MetadataWriter.
+ mr[i].Flags = (int)m.Flags;
+ mr[i].ImplFlags = (int)m.ImplFlags;
+ mr[i].Name = this.GetStringIndex(m.Name.ToString());
+ mr[i].Signature = this.GetBlobIndex(m, false);
+ if (m.ReturnTypeMarshallingInformation != null || (m.ReturnAttributes != null && m.ReturnAttributes.Count > 0))
+ mr[i].ParamList = (int)this.paramIndex[m.UniqueKey];
+ else
+ {
+ ParameterList pars = m.Parameters;
+ if (pars != null && pars.Count > 0)
+ {
+ Debug.Assert(pars[0] != null && pars[0].DeclaringMethod == m);
+ mr[i].ParamList = this.GetParamIndex(pars[0]);
+ }
+ else
+ mr[i].ParamList = 0;
+ }
+ }
+ //this.methodEntries = null;
+ }
+ void PopulateMethodImplTable()
+ {
+ int n = this.methodImplEntries.Count;
+ if (n == 0) return;
+ MethodImplRow[] mir = this.writer.methodImplTable = new MethodImplRow[n];
+ int j = 0;
+ Method lastMethod = null;
+ for (int i = 0; i < n; i++)
+ {
+ Method m = this.methodImplEntries[i];
+ if (lastMethod != m) j = 0;
+ mir[i].Class = this.GetTypeDefIndex(m.DeclaringType);
+ if (m.DeclaringType.DeclaringModule == this.module)
+ mir[i].MethodBody = this.GetMethodIndex(m) << 1;
+ else
+ mir[i].MethodBody = (this.GetMemberRefIndex(m) << 1) | 0x1;
+ Method im = m.ImplementedInterfaceMethods[j++];
+ while (im == null) im = m.ImplementedInterfaceMethods[j++];
+ mir[i].MethodDeclaration = this.GetMethodDefOrRefEncoded(im);
+ lastMethod = m;
+ }
+ //this.methodImplEntries = null;
+ }
+ void PopulateMethodSpecTable()
+ {
+ int n = this.methodSpecEntries.Count;
+ if (n == 0) return;
+ MethodSpecRow[] msr = this.writer.methodSpecTable = new MethodSpecRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Method m = this.methodSpecEntries[i];
+ msr[i].Method = this.GetMethodDefOrRefEncoded(m.Template);
+ msr[i].Instantiation = this.GetBlobIndex(m, true);
+ //TODO: sort this and eliminate duplicates.
+ //Duplicates can arise when methods are instantiated with method parameters from different methods.
+ //TODO: perhaps this duplication should be prevented by Method.GetTemplateInstance?
+ }
+ //this.methodEntries = null;
+ }
+ void PopulateMethodSemanticsTable()
+ {
+ int n = this.methodSemanticsEntries.Count;
+ if (n == 0) return;
+ MethodSemanticsRow[] msr = this.writer.methodSemanticsTable = new MethodSemanticsRow[n];
+ Member previousOwner = null;
+ int index = -1;
+ for (int i = 0; i < n; i++)
+ {
+ Member owner = this.methodSemanticsEntries[i];
+ Property ownerProperty = owner as Property;
+ if (ownerProperty != null)
+ {
+ msr[i].Association = (this.GetPropertyIndex(ownerProperty) << 1) | 1;
+ if (owner != previousOwner)
+ {
+ previousOwner = owner;
+ index = -1;
+ if (ownerProperty.Getter != null)
+ {
+ msr[i].Method = this.GetMethodIndex(ownerProperty.Getter);
+ msr[i].Semantics = 0x0002;
+ continue;
+ }
+ }
+ if (index == -1)
+ {
+ index = 0;
+ if (ownerProperty.Setter != null)
+ {
+ msr[i].Method = this.GetMethodIndex(ownerProperty.Setter);
+ msr[i].Semantics = 0x0001;
+ continue;
+ }
+ }
+ msr[i].Method = this.GetMethodIndex(ownerProperty.OtherMethods[index]);
+ msr[i].Semantics = 0x0004;
+ index++;
+ continue;
+ }
+ Event ownerEvent = owner as Event;
+ if (ownerEvent == null) { Debug.Fail(""); continue; }
+ msr[i].Association = this.GetEventIndex(ownerEvent) << 1;
+ if (owner != previousOwner)
+ {
+ previousOwner = owner;
+ index = -2;
+ if (ownerEvent.HandlerAdder != null)
+ {
+ msr[i].Method = this.GetMethodIndex(ownerEvent.HandlerAdder);
+ msr[i].Semantics = 0x0008;
+ continue;
+ }
+ }
+ if (index == -2)
+ {
+ index = -1;
+ if (ownerEvent.HandlerRemover != null)
+ {
+ msr[i].Method = this.GetMethodIndex(ownerEvent.HandlerRemover);
+ msr[i].Semantics = 0x0010;
+ continue;
+ }
+ }
+ if (index == -1)
+ {
+ index = 0;
+ if (ownerEvent.HandlerCaller != null)
+ {
+ msr[i].Method = this.GetMethodIndex(ownerEvent.HandlerCaller);
+ msr[i].Semantics = 0x0020;
+ continue;
+ }
+ }
+ msr[i].Method = this.GetMethodIndex(ownerEvent.OtherMethods[i]);
+ msr[i].Semantics = 0x0004;
+ index++;
+ continue;
+ }
+ System.Array.Sort(msr, new MethodSemanticsRowComparer());
+ //this.methodSemanticsEntries = null;
+ }
+ class MethodSemanticsRowComparer : IComparer
+ {
+ int IComparer.Compare(object x, object y)
+ {
+ MethodSemanticsRow xr = (MethodSemanticsRow)x;
+ MethodSemanticsRow yr = (MethodSemanticsRow)y;
+ int result = xr.Association - yr.Association;
+ if (result == 0) result = xr.Method - yr.Method;
+ return result;
+ }
+ }
+ void PopulateModuleTable()
+ {
+ ModuleRow[] mr = this.writer.moduleTable = new ModuleRow[1];
+ string name = this.module.Name;
+ if (this.assembly != null)
+ {
+ if (this.assembly.ModuleName != null)
+ name = this.assembly.ModuleName;
+ else
+ {
+ string extension = ".exe";
+ if (this.module.Kind == ModuleKindFlags.DynamicallyLinkedLibrary) extension = ".dll";
+ name = name + extension;
+ }
+ }
+ mr[0].Name = this.GetStringIndex(name);
+ mr[0].Mvid = this.GetGuidIndex(Guid.NewGuid());
+ }
+ void PopulateModuleRefTable()
+ {
+ int n = this.moduleRefEntries.Count;
+ if (n == 0) return;
+ ModuleRefRow[] mrr = this.writer.moduleRefTable = new ModuleRefRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ ModuleReference moduleRef = this.moduleRefEntries[i];
+ mrr[i].Name = this.GetStringIndex(moduleRef.Name);
+ }
+ //this.moduleRefEntries = null;
+ }
+ void PopulateNestedClassTable()
+ {
+ int n = this.nestedClassEntries.Count;
+ if (n == 0) return;
+ NestedClassRow[] ncr = this.writer.nestedClassTable = new NestedClassRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode nt = this.nestedClassEntries[i];
+ ncr[i].NestedClass = this.GetTypeDefIndex(nt);
+ ncr[i].EnclosingClass = this.GetTypeDefIndex(nt.DeclaringType);
+ }
+ //this.nestedClassEntries = null;
+ }
+ void PopulateParamTable()
+ {
+ int n = this.paramEntries.Count;
+ if (n == 0) return;
+ ParamRow[] pr = this.writer.paramTable = new ParamRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = this.paramEntries[i];
+ if (p == null) continue;
+ pr[i].Flags = (int)p.Flags;
+ pr[i].Sequence = p.ParameterListIndex + 1;
+ pr[i].Name = p.Name == null ? 0 : this.GetStringIndex(p.Name.ToString());
+ }
+ //this.paramEntries = null;
+ }
+ void PopulatePropertyTable()
+ {
+ int n = this.propertyEntries.Count;
+ if (n == 0) return;
+ PropertyRow[] pr = this.writer.propertyTable = new PropertyRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Property p = this.propertyEntries[i];
+ if (p == null || p.Name == null) continue;
+ pr[i].Flags = (int)p.Flags;
+ pr[i].Name = this.GetStringIndex(p.Name.ToString());
+ pr[i].Signature = this.GetBlobIndex(p);
+ }
+ //this.propertyEntries = null;
+ }
+ void PopulatePropertyMapTable()
+ {
+ int n = this.propertyMapEntries.Count;
+ if (n == 0) return;
+ PropertyMapRow[] pmr = this.writer.propertyMapTable = new PropertyMapRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ Property p = this.propertyMapEntries[i];
+ pmr[i].Parent = this.GetTypeDefIndex(p.DeclaringType);
+ pmr[i].PropertyList = this.GetPropertyIndex(p);
+ }
+ //this.propertyMapEntries = null;
+ }
+ void PopulateStandAloneSigTable()
+ {
+ int n = this.standAloneSignatureEntries.Count;
+ if (n == 0) return;
+ StandAloneSigRow[] sasr = this.writer.standAloneSigTable = new StandAloneSigRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ BinaryWriter sigWriter = (BinaryWriter)this.standAloneSignatureEntries[i];
+ sasr[i].Signature = this.GetBlobIndex(((MemoryStream)sigWriter.BaseStream).ToArray());
+ }
+ }
+ void PopulateTypeDefTable()
+ {
+ int n = this.typeDefEntries.Count;
+ if (n == 0) return;
+ TypeDefRow[] tdr = this.writer.typeDefTable = new TypeDefRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.typeDefEntries[i];
+ if (t == null) continue;
+ tdr[i].Flags = (int)t.Flags;
+ tdr[i].Name = this.GetStringIndex(t.Name == null ? "" : t.Name.ToString());
+ tdr[i].Namespace = t.Namespace == null ? 0 : this.GetStringIndex(t.Namespace == null ? "" : t.Namespace.ToString());
+ tdr[i].Extends = this.GetTypeDefOrRefOrSpecEncoded(t.BaseType);
+ MemberList members = t.Members;
+ int m = members.Count;
+ for (int j = 0; j < m; j++)
+ {
+ Member mem = members[j];
+ if (mem == null) continue;
+ if (mem.NodeType == NodeType.Field)
+ {
+ tdr[i].FieldList = this.GetFieldIndex((Field)mem);
+ break;
+ }
+ }
+ for (int j = 0; j < m; j++)
+ {
+ Member mem = members[j];
+ if (mem == null) continue;
+ switch (mem.NodeType)
+ {
+ case NodeType.Method:
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ tdr[i].MethodList = this.GetMethodIndex((Method)mem);
+ goto done;
+ }
+ }
+ done: continue;
+ }
+ //this.typeDefEntries = null;
+ }
+ void PopulateTypeRefTable()
+ {
+ int n = this.typeRefEntries.Count;
+ if (n == 0) return;
+ TypeRefRow[] trr = this.writer.typeRefTable = new TypeRefRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.typeRefEntries[i];
+ if (t == null || t.Name == null || t.Namespace == null) continue;
+ trr[i].Name = this.GetStringIndex(t.Name.ToString());
+ trr[i].Namespace = this.GetStringIndex(t.Namespace.ToString());
+ if (t.DeclaringType == null)
+ if (t.DeclaringModule is AssemblyNode)
+ trr[i].ResolutionScope = (this.GetAssemblyRefIndex((AssemblyNode)t.DeclaringModule) << 2) | 2;
+ else
+ trr[i].ResolutionScope = (this.GetModuleRefIndex(t.DeclaringModule) << 2) | 1;
+ else
+ trr[i].ResolutionScope = (this.GetTypeRefIndex(t.DeclaringType) << 2) | 3;
+ }
+ //this.typeRefEntries = null;
+ }
+ void PopulateTypeSpecTable()
+ {
+ int n = this.typeSpecEntries.Count;
+ if (n == 0) return;
+ TypeSpecRow[] tsr = this.writer.typeSpecTable = new TypeSpecRow[n];
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode t = this.typeSpecEntries[i];
+ tsr[i].Signature = this.GetBlobIndex(t);
+ //TODO: eliminate duplicates
+ }
+ //this.typeSpecEntries = null;
+ }
+ void Visit(Node node)
+ {
+ if (node == null) return;
+ switch (node.NodeType)
+ {
+ case NodeType.AddressDereference:
+ this.VisitAddressDereference((AddressDereference)node); return;
+ case NodeType.Arglist:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.AssignmentStatement:
+ this.VisitAssignmentStatement((AssignmentStatement)node); return;
+#if !MinimalReader
+ case NodeType.Base:
+ this.VisitBase((Base)node); return;
+#endif
+ case NodeType.Block:
+ this.VisitBlock((Block)node); return;
+#if !MinimalReader
+ case NodeType.BlockExpression:
+ this.VisitBlockExpression((BlockExpression)node); return;
+#endif
+ case NodeType.Branch:
+ this.VisitBranch((Branch)node); return;
+ case NodeType.DebugBreak:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.Call:
+ case NodeType.Calli:
+ case NodeType.Callvirt:
+ case NodeType.Jmp:
+#if !MinimalReader
+ case NodeType.MethodCall:
+#endif
+ this.VisitMethodCall((MethodCall)node); return;
+ case NodeType.Class:
+ case NodeType.ClassParameter:
+ this.VisitClass((Class)node); return;
+ case NodeType.Construct:
+ this.VisitConstruct((Construct)node); return;
+ case NodeType.ConstructArray:
+ this.VisitConstructArray((ConstructArray)node); return;
+ case NodeType.DelegateNode:
+ this.VisitDelegateNode((DelegateNode)node); return;
+ case NodeType.Dup:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.EndFilter:
+ this.VisitEndFilter((EndFilter)node); return;
+ case NodeType.EndFinally:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.EnumNode:
+ this.VisitEnumNode((EnumNode)node); return;
+ case NodeType.Event:
+ this.VisitEvent((Event)node); return;
+ case NodeType.ExpressionStatement:
+ this.VisitExpressionStatement((ExpressionStatement)node); return;
+ case NodeType.Field:
+ this.VisitField((Field)node); return;
+ case NodeType.Indexer:
+ this.VisitIndexer((Indexer)node); return;
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ case NodeType.Method:
+ this.VisitMethod((Method)node); return;
+ case NodeType.TypeParameter:
+ case NodeType.Interface:
+ this.VisitInterface((Interface)node); return;
+ case NodeType.Literal:
+ this.VisitLiteral((Literal)node); return;
+ case NodeType.Local:
+ this.VisitLocal((Local)node); return;
+#if !MinimalReader
+ case NodeType.LocalDeclarationsStatement:
+ this.VisitLocalDeclarationsStatement((LocalDeclarationsStatement)node); return;
+#endif
+ case NodeType.MemberBinding:
+ this.VisitMemberBinding((MemberBinding)node); return;
+ case NodeType.Nop:
+ this.VisitStatement((Statement)node); return;
+ case NodeType.Parameter:
+ this.VisitParameter((Parameter)node); return;
+ case NodeType.Pop:
+ this.VisitExpression((Expression)node); return;
+ case NodeType.Property:
+ this.VisitProperty((Property)node); return;
+ case NodeType.Rethrow:
+ case NodeType.Throw:
+ this.VisitThrow((Throw)node); return;
+ case NodeType.Return:
+ this.VisitReturn((Return)node); return;
+ case NodeType.Struct:
+#if !MinimalReader
+ case NodeType.TypeAlias:
+ case NodeType.TypeIntersection:
+ case NodeType.TypeUnion:
+ case NodeType.TupleType:
+#endif
+ this.VisitStruct((Struct)node); return;
+#if !MinimalReader
+ case NodeType.SwitchCaseBottom:
+ return;
+#endif
+ case NodeType.SwitchInstruction:
+ this.VisitSwitchInstruction((SwitchInstruction)node); return;
+ case NodeType.This:
+ this.VisitThis((This)node); return;
+
+ case NodeType.Cpblk:
+ case NodeType.Initblk:
+ this.VisitTernaryExpression((TernaryExpression)node); return;
+
+ case NodeType.Add:
+ case NodeType.Add_Ovf:
+ case NodeType.Add_Ovf_Un:
+ case NodeType.And:
+ case NodeType.Box:
+ case NodeType.Castclass:
+ case NodeType.Ceq:
+ case NodeType.Cgt:
+ case NodeType.Cgt_Un:
+ case NodeType.Clt:
+ case NodeType.Clt_Un:
+ case NodeType.Div:
+ case NodeType.Div_Un:
+ case NodeType.Eq:
+ case NodeType.Ge:
+ case NodeType.Gt:
+#if !MinimalReader
+ case NodeType.Is:
+#endif
+ case NodeType.Isinst:
+ case NodeType.Ldvirtftn:
+ case NodeType.Le:
+ case NodeType.Lt:
+ case NodeType.Mkrefany:
+ case NodeType.Mul:
+ case NodeType.Mul_Ovf:
+ case NodeType.Mul_Ovf_Un:
+ case NodeType.Ne:
+ case NodeType.Or:
+ case NodeType.Refanyval:
+ case NodeType.Rem:
+ case NodeType.Rem_Un:
+ case NodeType.Shl:
+ case NodeType.Shr:
+ case NodeType.Shr_Un:
+ case NodeType.Sub:
+ case NodeType.Sub_Ovf:
+ case NodeType.Sub_Ovf_Un:
+ case NodeType.Unbox:
+ case NodeType.UnboxAny:
+ case NodeType.Xor:
+ this.VisitBinaryExpression((BinaryExpression)node); return;
+
+
+ case NodeType.AddressOf:
+#if !MinimalReader
+ case NodeType.OutAddress:
+ case NodeType.RefAddress:
+#endif
+ case NodeType.ReadOnlyAddressOf:
+ this.VisitAddressOf((UnaryExpression)node); return;
+ case NodeType.Ckfinite:
+ case NodeType.Conv_I:
+ case NodeType.Conv_I1:
+ case NodeType.Conv_I2:
+ case NodeType.Conv_I4:
+ case NodeType.Conv_I8:
+ case NodeType.Conv_Ovf_I:
+ case NodeType.Conv_Ovf_I1:
+ case NodeType.Conv_Ovf_I1_Un:
+ case NodeType.Conv_Ovf_I2:
+ case NodeType.Conv_Ovf_I2_Un:
+ case NodeType.Conv_Ovf_I4:
+ case NodeType.Conv_Ovf_I4_Un:
+ case NodeType.Conv_Ovf_I8:
+ case NodeType.Conv_Ovf_I8_Un:
+ case NodeType.Conv_Ovf_I_Un:
+ case NodeType.Conv_Ovf_U:
+ case NodeType.Conv_Ovf_U1:
+ case NodeType.Conv_Ovf_U1_Un:
+ case NodeType.Conv_Ovf_U2:
+ case NodeType.Conv_Ovf_U2_Un:
+ case NodeType.Conv_Ovf_U4:
+ case NodeType.Conv_Ovf_U4_Un:
+ case NodeType.Conv_Ovf_U8:
+ case NodeType.Conv_Ovf_U8_Un:
+ case NodeType.Conv_Ovf_U_Un:
+ case NodeType.Conv_R4:
+ case NodeType.Conv_R8:
+ case NodeType.Conv_R_Un:
+ case NodeType.Conv_U:
+ case NodeType.Conv_U1:
+ case NodeType.Conv_U2:
+ case NodeType.Conv_U4:
+ case NodeType.Conv_U8:
+ case NodeType.Ldftn:
+ case NodeType.Ldlen:
+ case NodeType.Ldtoken:
+ case NodeType.Localloc:
+ case NodeType.Neg:
+ case NodeType.Not:
+ case NodeType.Refanytype:
+ case NodeType.Sizeof:
+ this.VisitUnaryExpression((UnaryExpression)node); return;
+
+ default:
+ // handle type extensions with new NodeType's, that are emitted as ordinary structs and classes
+ Class cl = node as Class;
+ if (cl != null)
+ {
+ this.VisitClass(cl); return;
+ }
+ Struct st = node as Struct;
+ if (st != null)
+ {
+ this.VisitStruct(st); return;
+ }
+ Debug.Assert(false, "invalid node: " + node.NodeType.ToString());
+ return;
+ }
+ }
+ void VisitAddressDereference(AddressDereference/*!*/ adr)
+ {
+ this.Visit(adr.Address);
+ if (adr.Alignment > 0)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x12);
+ this.methodBodyHeap.Write((byte)adr.Alignment);
+ }
+ if (adr.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ switch (adr.Type.typeCode)
+ {
+ case ElementType.Int8: this.methodBodyHeap.Write((byte)0x46); return;
+ case ElementType.UInt8: this.methodBodyHeap.Write((byte)0x47); return;
+ case ElementType.Int16: this.methodBodyHeap.Write((byte)0x48); return;
+ case ElementType.Char:
+ case ElementType.UInt16: this.methodBodyHeap.Write((byte)0x49); return;
+ case ElementType.Int32: this.methodBodyHeap.Write((byte)0x4a); return;
+ case ElementType.UInt32: this.methodBodyHeap.Write((byte)0x4b); return;
+ case ElementType.Int64:
+ case ElementType.UInt64: this.methodBodyHeap.Write((byte)0x4c); return;
+ //case ElementType.UIntPtr:
+ //case ElementType.IntPtr: this.methodBodyHeap.Write((byte)0x4d); return;
+ case ElementType.Single: this.methodBodyHeap.Write((byte)0x4e); return;
+ case ElementType.Double: this.methodBodyHeap.Write((byte)0x4f); return;
+ default:
+ if (adr.Type.IsValueType || (adr.Type is ITypeParameter && this.UseGenerics))
+ {
+ this.methodBodyHeap.Write((byte)0x71);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(adr.Type));
+ return;
+ }
+ else if (TypeNode.StripModifiers(adr.Type) is Pointer)
+ {
+ this.methodBodyHeap.Write((byte)0x4d); return;
+ }
+ this.methodBodyHeap.Write((byte)0x50);
+ return;
+ }
+ }
+ void VisitAttributeList(AttributeList attrs, Node/*!*/ node)
+ {
+ if (attrs == null) return;
+ int n = attrs.Count;
+ if (n == 0) return;
+ int m = n;
+ for (int j = 0; j < n; j++)
+ {
+ AttributeNode a = attrs[j];
+ if (a == null) m--;
+ }
+ if (m == 0) return;
+ n = m;
+ int codedIndex = this.GetCustomAttributeParentCodedIndex(node);
+ this.customAttributeCount += n;
+ m = this.nodesWithCustomAttributes.Count;
+ this.nodesWithCustomAttributes.Add(node);
+ int i = 0; //after the for loop i will be position where the new node should be in sorted list
+ NodeList nodes = this.nodesWithCustomAttributes;
+ for (i = m; i > 0; i--)
+ {
+ Node other = nodes[i - 1];
+ int oci = this.GetCustomAttributeParentCodedIndex(other);
+ if (oci < codedIndex) break;
+ if (UseGenerics)
+ {
+ if (oci == codedIndex) Debug.Assert(false);
+ }
+ }
+ if (i == m) return; //node is already where it should be
+ for (int j = m; j > i; j--) nodes[j] = nodes[j - 1]; //Make space at postion i
+ nodes[i] = node;
+ }
+ void VisitAddressOf(UnaryExpression/*!*/ expr)
+ {
+ Expression operand = expr.Operand;
+ if (operand == null) return;
+ switch (operand.NodeType)
+ {
+ case NodeType.Indexer:
+ Indexer indexer = (Indexer)operand;
+ this.Visit(indexer.Object);
+ if (indexer.Operands == null || indexer.Operands.Count < 1) return;
+ this.Visit(indexer.Operands[0]);
+ if (expr.NodeType == NodeType.ReadOnlyAddressOf)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x1e);
+ }
+ this.methodBodyHeap.Write((byte)0x8f);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(indexer.ElementType));
+ this.stackHeight--;
+ return;
+ case NodeType.Local:
+ int li = this.GetLocalVarIndex((Local)operand);
+ if (li < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x12);
+ this.methodBodyHeap.Write((byte)li);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x0d);
+ this.methodBodyHeap.Write((ushort)li);
+ }
+ this.IncrementStackHeight();
+ return;
+ case NodeType.MemberBinding:
+ MemberBinding mb = (MemberBinding)operand;
+ if (mb.TargetObject != null)
+ {
+ this.Visit(mb.TargetObject);
+ this.methodBodyHeap.Write((byte)0x7c);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0x7f);
+ this.IncrementStackHeight();
+ }
+ this.methodBodyHeap.Write((int)this.GetFieldToken((Field)mb.BoundMember));
+ return;
+ case NodeType.Parameter:
+#if !MinimalReader
+ ParameterBinding pb = operand as ParameterBinding;
+ if (pb != null) operand = pb.BoundParameter;
+#endif
+ int pi = ((Parameter)operand).ArgumentListIndex;
+ if (pi < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x0f);
+ this.methodBodyHeap.Write((byte)pi);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x0a);
+ this.methodBodyHeap.Write((ushort)pi);
+ }
+ this.IncrementStackHeight();
+ return;
+ }
+ }
+ void VisitAssignmentStatement(AssignmentStatement/*!*/ assignment)
+ {
+ this.DefineSequencePoint(assignment);
+ Expression target = assignment.Target;
+ switch (assignment.Target.NodeType)
+ {
+ case NodeType.Local:
+ Local loc = (Local)target;
+ this.Visit(assignment.Source);
+ this.stackHeight--;
+ int li = this.GetLocalVarIndex(loc);
+ switch (li)
+ {
+ case 0: this.methodBodyHeap.Write((byte)0x0a); return;
+ case 1: this.methodBodyHeap.Write((byte)0x0b); return;
+ case 2: this.methodBodyHeap.Write((byte)0x0c); return;
+ case 3: this.methodBodyHeap.Write((byte)0x0d); return;
+ default:
+ if (li < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x13);
+ this.methodBodyHeap.Write((byte)li);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x0e);
+ this.methodBodyHeap.Write((ushort)li);
+ }
+ return;
+ }
+ case NodeType.MemberBinding:
+ MemberBinding mb = (MemberBinding)target;
+ if (mb.TargetObject != null) this.Visit(mb.TargetObject);
+ this.Visit(assignment.Source);
+ if (mb.TargetObject != null)
+ {
+ if (mb.Alignment != -1)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x12);
+ this.methodBodyHeap.Write((byte)mb.Alignment);
+ }
+ if (mb.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ this.methodBodyHeap.Write((byte)0x7d);
+ }
+ else
+ {
+ if (mb.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ this.methodBodyHeap.Write((byte)0x80);
+ }
+ this.methodBodyHeap.Write((int)this.GetFieldToken((Field)mb.BoundMember));
+ if (mb.TargetObject != null)
+ this.stackHeight -= 2;
+ else
+ this.stackHeight--;
+ return;
+ case NodeType.Parameter:
+#if !MinimalReader
+ ParameterBinding pb = target as ParameterBinding;
+ if (pb != null) target = pb.BoundParameter;
+#endif
+ Parameter par = (Parameter)target;
+ this.Visit(assignment.Source);
+ int pi = par.ArgumentListIndex;
+ if (pi < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x10);
+ this.methodBodyHeap.Write((byte)pi);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x0b);
+ this.methodBodyHeap.Write((ushort)pi);
+ }
+ this.stackHeight--;
+ return;
+ case NodeType.Indexer:
+ Indexer indexer = (Indexer)target;
+ this.Visit(indexer.Object);
+ if (indexer.Operands == null || indexer.Operands.Count < 1) return;
+ this.Visit(indexer.Operands[0]);
+ this.Visit(assignment.Source);
+ byte opCode;
+ switch (indexer.ElementType.typeCode)
+ {
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: opCode = 0x9b; break;
+ case ElementType.Boolean:
+ case ElementType.Int8:
+ case ElementType.UInt8: opCode = 0x9c; break;
+ case ElementType.Char:
+ case ElementType.Int16:
+ case ElementType.UInt16: opCode = 0x9d; break;
+ case ElementType.Int32:
+ case ElementType.UInt32: opCode = 0x9e; break;
+ case ElementType.Int64:
+ case ElementType.UInt64: opCode = 0x9f; break;
+ case ElementType.Single: opCode = 0xa0; break;
+ case ElementType.Double: opCode = 0xa1; break;
+ default:
+ if (this.UseGenerics && (indexer.ElementType is ITypeParameter))
+ opCode = 0xa4;
+ else if (TypeNode.StripModifiers(indexer.ElementType) is Pointer)
+ opCode = 0x9b;
+ else
+ opCode = 0xa2;
+ break;
+ }
+ this.methodBodyHeap.Write((byte)opCode);
+ if (opCode == 0xa4) this.methodBodyHeap.Write((int)this.GetTypeToken(indexer.ElementType));
+ this.stackHeight -= 3;
+ return;
+ case NodeType.AddressDereference:
+ AddressDereference adr = (AddressDereference)target;
+ this.Visit(adr.Address);
+ if (adr.Type.IsValueType || adr.Type is ITypeParameter)
+ {
+ Literal lit = assignment.Source as Literal;
+ if (lit != null && lit.Value == null)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x15);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(adr.Type));
+ this.stackHeight--;
+ return;
+ }
+ }
+ this.Visit(assignment.Source);
+ this.stackHeight -= 2;
+ if (adr.Alignment > 0)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x12);
+ this.methodBodyHeap.Write((byte)adr.Alignment);
+ }
+ if (adr.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ TypeNode adrType = TypeNode.StripModifiers(adr.Type);
+ if (adrType == null) return;
+ switch (adrType.typeCode)
+ {
+ case ElementType.Int8:
+ case ElementType.UInt8: this.methodBodyHeap.Write((byte)0x52); return;
+ case ElementType.Int16:
+ case ElementType.UInt16: this.methodBodyHeap.Write((byte)0x53); return;
+ case ElementType.Int32:
+ case ElementType.UInt32: this.methodBodyHeap.Write((byte)0x54); return;
+ case ElementType.Int64:
+ case ElementType.UInt64: this.methodBodyHeap.Write((byte)0x55); return;
+ case ElementType.Single: this.methodBodyHeap.Write((byte)0x56); return;
+ case ElementType.Double: this.methodBodyHeap.Write((byte)0x57); return;
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: this.methodBodyHeap.Write((byte)0xdf); return;
+ default:
+ if (adrType != null && (adrType.IsValueType ||
+ this.UseGenerics && (adrType is ITypeParameter)))
+ {
+ this.methodBodyHeap.Write((byte)0x81);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(adrType));
+ return;
+ }
+ if (adrType.NodeType == NodeType.Pointer)
+ {
+ this.methodBodyHeap.Write((byte)0xdf); return;
+ }
+ this.methodBodyHeap.Write((byte)0x51);
+ return;
+ }
+ default:
+ Debug.Assert(false, "unexpected assignment target");
+ return;
+ }
+ }
+#if !MinimalReader
+ void VisitBase(Base/*!*/ Base)
+ {
+ this.IncrementStackHeight();
+ this.methodBodyHeap.Write((byte)0x02);
+ }
+#endif
+ void VisitBinaryExpression(BinaryExpression/*!*/ binaryExpression)
+ {
+ byte opCode = 0;
+ this.Visit(binaryExpression.Operand1);
+ switch (binaryExpression.NodeType)
+ {
+ case NodeType.Castclass: opCode = 0x74; goto writeOpCodeAndToken;
+ case NodeType.Isinst: opCode = 0x75; goto writeOpCodeAndToken;
+ case NodeType.Unbox: opCode = 0x79; goto writeOpCodeAndToken;
+ case NodeType.UnboxAny: opCode = 0xa5; goto writeOpCodeAndToken;
+ case NodeType.Box: opCode = 0x8c; goto writeOpCodeAndToken;
+ case NodeType.Refanyval: opCode = 0xc2; goto writeOpCodeAndToken;
+ case NodeType.Mkrefany: opCode = 0xc6; goto writeOpCodeAndToken;
+ writeOpCodeAndToken:
+ this.methodBodyHeap.Write((byte)opCode);
+ Literal lit = binaryExpression.Operand2 as Literal;
+ if (lit != null)
+ this.methodBodyHeap.Write((int)this.GetTypeToken((TypeNode)lit.Value));
+ else
+ {
+ // TODO: Normalized IR should never use a MemberBinding to represent a type
+ this.methodBodyHeap.Write((int)this.GetTypeToken((TypeNode)((MemberBinding)binaryExpression.Operand2).BoundMember));
+ }
+ return;
+ case NodeType.Ldvirtftn: opCode = 0x07; this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)opCode);
+ this.methodBodyHeap.Write((int)this.GetMethodToken((Method)((MemberBinding)binaryExpression.Operand2).BoundMember));
+ return;
+ }
+ this.Visit(binaryExpression.Operand2);
+ switch (binaryExpression.NodeType)
+ {
+ case NodeType.Add: opCode = 0x58; break;
+ case NodeType.Sub: opCode = 0x59; break;
+ case NodeType.Mul: opCode = 0x5a; break;
+ case NodeType.Div: opCode = 0x5b; break;
+ case NodeType.Div_Un: opCode = 0x5c; break;
+ case NodeType.Rem: opCode = 0x5d; break;
+ case NodeType.Rem_Un: opCode = 0x5e; break;
+ case NodeType.And: opCode = 0x5f; break;
+ case NodeType.Or: opCode = 0x60; break;
+ case NodeType.Xor: opCode = 0x61; break;
+ case NodeType.Shl: opCode = 0x62; break;
+ case NodeType.Shr: opCode = 0x63; break;
+ case NodeType.Shr_Un: opCode = 0x64; break;
+ case NodeType.Add_Ovf: opCode = 0xd6; break;
+ case NodeType.Add_Ovf_Un: opCode = 0xd7; break;
+ case NodeType.Mul_Ovf: opCode = 0xd8; break;
+ case NodeType.Mul_Ovf_Un: opCode = 0xd9; break;
+ case NodeType.Sub_Ovf: opCode = 0xda; break;
+ case NodeType.Sub_Ovf_Un: opCode = 0xdb; break;
+ case NodeType.Ceq: opCode = 0x01; this.methodBodyHeap.Write((byte)0xfe); break;
+ case NodeType.Cgt: opCode = 0x02; this.methodBodyHeap.Write((byte)0xfe); break;
+ case NodeType.Cgt_Un: opCode = 0x03; this.methodBodyHeap.Write((byte)0xfe); break;
+ case NodeType.Clt: opCode = 0x04; this.methodBodyHeap.Write((byte)0xfe); break;
+ case NodeType.Clt_Un: opCode = 0x05; this.methodBodyHeap.Write((byte)0xfe); break;
+ }
+ this.methodBodyHeap.Write((byte)opCode);
+ this.stackHeight--;
+ }
+ void VisitBlock(Block/*!*/ block)
+ {
+ MethodInfo mInfo = this.methodInfo;
+ int currentAddress = (int)this.methodBodyHeap.BaseStream.Position;
+ this.VisitFixupList((Fixup)this.methodInfo.fixupIndex[block.UniqueKey], currentAddress);
+ mInfo.fixupIndex[block.UniqueKey] = currentAddress;
+ this.methodBodyHeap.BaseStream.Position = currentAddress;
+ int savedStackHeight = this.stackHeight;
+ if (this.exceptionBlock[block.UniqueKey] != null) this.stackHeight = 1;
+ StatementList statements = block.Statements;
+ if (statements == null) return;
+#if !ROTOR
+ if (this.symWriter != null && block.HasLocals)
+ {
+ LocalList savedDebugLocals = mInfo.debugLocals;
+ Int32List savedSignatureLengths = mInfo.signatureLengths;
+ Int32List savedSignatureOffsets = mInfo.signatureOffsets;
+ mInfo.debugLocals = new LocalList();
+ mInfo.signatureLengths = new Int32List();
+ mInfo.signatureOffsets = new Int32List();
+ this.symWriter.OpenScope((uint)currentAddress);
+ for (int i = 0, n = statements.Count; i < n; i++)
+ this.Visit(statements[i]);
+ if (this.stackHeight > 0) this.stackHeightExitTotal += this.stackHeight;
+ this.DefineLocalVariables(currentAddress, mInfo.debugLocals);
+ mInfo.debugLocals = savedDebugLocals;
+ mInfo.signatureLengths = savedSignatureLengths;
+ mInfo.signatureOffsets = savedSignatureOffsets;
+ }
+ else
+ {
+#endif
+ for (int i = 0, n = statements.Count; i < n; i++)
+ this.Visit(statements[i]);
+ if (this.stackHeight > savedStackHeight) this.stackHeightExitTotal += (this.stackHeight - savedStackHeight);
+#if !ROTOR
+ }
+#endif
+ this.stackHeight = savedStackHeight;
+ }
+#if !MinimalReader
+ void VisitBlockExpression(BlockExpression/*!*/ blockExpression)
+ {
+ if (blockExpression.Block == null) return;
+ this.VisitBlock(blockExpression.Block);
+ }
+#endif
+ void VisitBranch(Branch/*!*/ branch)
+ {
+ this.DefineSequencePoint(branch);
+ BinaryExpression bex = branch.Condition as BinaryExpression;
+ UnaryExpression uex = null;
+ NodeType typeOfCondition = NodeType.Nop;
+ if (bex != null)
+ {
+ switch (bex.NodeType)
+ {
+ case NodeType.Eq:
+ case NodeType.Ge:
+ case NodeType.Gt:
+ case NodeType.Le:
+ case NodeType.Lt:
+ case NodeType.Ne:
+ this.Visit(bex.Operand1);
+ this.Visit(bex.Operand2);
+ typeOfCondition = bex.NodeType;
+ this.stackHeight -= 2;
+ break;
+ case NodeType.And:
+ case NodeType.Or:
+ case NodeType.Xor:
+ case NodeType.Isinst:
+ case NodeType.Castclass:
+ typeOfCondition = bex.NodeType;
+ goto default;
+ default:
+ this.Visit(branch.Condition);
+ this.stackHeight--;
+ break;
+ }
+ }
+ else
+ {
+ uex = branch.Condition as UnaryExpression;
+ if (uex != null && uex.NodeType == NodeType.LogicalNot)
+ {
+ this.Visit(uex.Operand);
+ typeOfCondition = NodeType.LogicalNot;
+ this.stackHeight--;
+ }
+ else if (branch.Condition != null)
+ {
+ // Undefined is used here simply as a sentinel value
+ typeOfCondition = NodeType.Undefined;
+ this.Visit(branch.Condition);
+ this.stackHeight--;
+ }
+ }
+ int target = this.GetOffset(branch.Target, ref branch.shortOffset);
+ if (branch.ShortOffset)
+ {
+ switch (typeOfCondition)
+ {
+ case NodeType.Nop:
+ if (branch.Condition == null)
+ {
+ if (branch.LeavesExceptionBlock)
+ this.methodBodyHeap.Write((byte)0xde);
+ else
+ this.methodBodyHeap.Write((byte)0x2b);
+ break;
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0x2d); break;
+ }
+ case NodeType.And:
+ case NodeType.Or:
+ case NodeType.Xor:
+ case NodeType.Isinst:
+ case NodeType.Castclass:
+ case NodeType.Undefined:
+ this.methodBodyHeap.Write((byte)0x2d); break;
+ case NodeType.LogicalNot:
+ this.methodBodyHeap.Write((byte)0x2c); break;
+ case NodeType.Eq:
+ this.methodBodyHeap.Write((byte)0x2e); break;
+ case NodeType.Ge:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x34);
+ else
+ this.methodBodyHeap.Write((byte)0x2f);
+ break;
+ case NodeType.Gt:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x35);
+ else
+ this.methodBodyHeap.Write((byte)0x30);
+ break;
+ case NodeType.Le:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x36);
+ else
+ this.methodBodyHeap.Write((byte)0x31);
+ break;
+ case NodeType.Lt:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x37);
+ else
+ this.methodBodyHeap.Write((byte)0x32);
+ break;
+ case NodeType.Ne:
+ this.methodBodyHeap.Write((byte)0x33);
+ break;
+ }
+ this.methodBodyHeap.Write((sbyte)target);
+ }
+ else
+ {
+ switch (typeOfCondition)
+ {
+ case NodeType.Nop:
+ if (branch.Condition == null)
+ {
+ if (branch.LeavesExceptionBlock)
+ this.methodBodyHeap.Write((byte)0xdd);
+ else
+ this.methodBodyHeap.Write((byte)0x38);
+ break;
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0x3a); break;
+ }
+ case NodeType.And:
+ case NodeType.Or:
+ case NodeType.Xor:
+ case NodeType.Isinst:
+ case NodeType.Castclass:
+ case NodeType.Undefined:
+ this.methodBodyHeap.Write((byte)0x3a); break;
+ case NodeType.LogicalNot:
+ this.methodBodyHeap.Write((byte)0x39); break;
+ case NodeType.Eq:
+ this.methodBodyHeap.Write((byte)0x3b); break;
+ case NodeType.Ge:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x41);
+ else
+ this.methodBodyHeap.Write((byte)0x3c);
+ break;
+ case NodeType.Gt:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x42);
+ else
+ this.methodBodyHeap.Write((byte)0x3d);
+ break;
+ case NodeType.Le:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x43);
+ else
+ this.methodBodyHeap.Write((byte)0x3e);
+ break;
+ case NodeType.Lt:
+ if (branch.BranchIfUnordered)
+ this.methodBodyHeap.Write((byte)0x44);
+ else
+ this.methodBodyHeap.Write((byte)0x3f);
+ break;
+ case NodeType.Ne:
+ this.methodBodyHeap.Write((byte)0x40); break;
+ }
+ this.methodBodyHeap.Write((int)target);
+ }
+ }
+ void VisitMethodCall(MethodCall/*!*/ call)
+ {
+ MemberBinding mb = (MemberBinding)call.Callee;
+ TypeNode constraint = call.Constraint;
+ this.Visit(mb.TargetObject);
+ ExpressionList arguments = call.Operands;
+ int pops = 0;
+ if (arguments != null)
+ {
+ this.VisitExpressionList(arguments);
+ pops = arguments.Count;
+ }
+ if (call.Type != CoreSystemTypes.Void) { this.VisitReferencedType(call.Type); pops--; }
+ if (pops >= 0)
+ this.stackHeight -= pops;
+ else
+ this.IncrementStackHeight(); //make sure the high water mark moves up if necessary
+ if (call.IsTailCall)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x14);
+ }
+ else if (constraint != null)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x16);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(constraint));
+ }
+ switch (call.NodeType)
+ {
+ case NodeType.Calli:
+ this.methodBodyHeap.Write((byte)0x29);
+ BinaryWriter sig = new BinaryWriter(new MemoryStream());
+ this.WriteMethodSignature(sig, (FunctionPointer)mb.BoundMember);
+ this.methodBodyHeap.Write((int)(0x11000000 | this.GetStandAloneSignatureIndex(sig)));
+ return;
+ case NodeType.Callvirt: this.methodBodyHeap.Write((byte)0x6f); break;
+ case NodeType.Jmp: this.methodBodyHeap.Write((byte)0x27); break;
+ default: this.methodBodyHeap.Write((byte)0x28); break;
+ }
+ Method method = (Method)mb.BoundMember;
+ if ((method.CallingConvention & (CallingConventionFlags)7) == CallingConventionFlags.VarArg ||
+ (method.CallingConvention & (CallingConventionFlags)7) == CallingConventionFlags.C)
+ {
+ this.methodBodyHeap.Write((int)this.GetMemberRefToken(method, arguments));
+ }
+ else
+ this.methodBodyHeap.Write((int)this.GetMethodToken(method));
+ }
+ void VisitClass(Class/*!*/ Class)
+ {
+ if (this.UseGenerics && Class.Template != null && Class.Template.IsGeneric) return;
+ this.VisitAttributeList(Class.Attributes, Class);
+ this.VisitSecurityAttributeList(Class.SecurityAttributes, Class);
+ if (Class.BaseClass != null) this.VisitReferencedType(Class.BaseClass);
+ for (int i = 0, n = Class.Interfaces == null ? 0 : Class.Interfaces.Count; i < n; i++)
+ {
+ this.GetTypeDefOrRefOrSpecEncoded(Class.Interfaces[i]);
+ if (Class.Interfaces[i] != null) this.interfaceEntries.Add(Class);
+ }
+ if (Class.NodeType == NodeType.ClassParameter && !(Class is MethodClassParameter))
+ this.interfaceEntries.Add(Class);
+ for (int i = 0, n = Class.Members.Count; i < n; i++)
+ {
+ Member mem = Class.Members[i];
+ if (mem == null || mem is TypeNode) continue;
+ this.Visit(mem);
+ }
+ if ((Class.Flags & (TypeFlags.ExplicitLayout | TypeFlags.SequentialLayout)) != 0 && (Class.PackingSize != 0 || Class.ClassSize != 0))
+ this.classLayoutEntries.Add(Class);
+ }
+ void VisitConstruct(Construct/*!*/ cons)
+ {
+ int pops = -1;
+ ExpressionList operands = cons.Operands;
+ if (operands != null)
+ {
+ this.VisitExpressionList(cons.Operands);
+ pops = operands.Count - 1;
+ }
+ if (pops >= 0)
+ this.stackHeight -= pops;
+ else
+ this.IncrementStackHeight();
+ this.methodBodyHeap.Write((byte)0x73);
+ Method method = ((MemberBinding)cons.Constructor).BoundMember as Method;
+ if (method == null) return;
+ this.methodBodyHeap.Write((int)this.GetMethodToken(method)); //REVIEW: varargs?
+ }
+ void VisitConstructArray(ConstructArray/*!*/ consArr)
+ {
+ if (consArr == null || consArr.Operands == null || consArr.Operands.Count < 1) return;
+ this.Visit(consArr.Operands[0]);
+ this.methodBodyHeap.Write((byte)0x8d);
+ this.methodBodyHeap.Write((int)this.GetTypeToken(consArr.ElementType));
+ }
+ void VisitDelegateNode(DelegateNode/*!*/ delegateNode)
+ {
+ if (this.UseGenerics && delegateNode.Template != null && delegateNode.Template.IsGeneric) return;
+ this.VisitAttributeList(delegateNode.Attributes, delegateNode);
+ this.VisitSecurityAttributeList(delegateNode.SecurityAttributes, delegateNode);
+ this.VisitReferencedType(CoreSystemTypes.MulticastDelegate);
+ for (int i = 0, n = delegateNode.Interfaces == null ? 0 : delegateNode.Interfaces.Count; i < n; i++)
+ { //REVIEW: is this valid?
+ this.GetTypeDefOrRefOrSpecEncoded(delegateNode.Interfaces[i]);
+ if (delegateNode.Interfaces[i] != null) this.interfaceEntries.Add(delegateNode);
+ }
+ for (int i = 0, n = delegateNode.Members.Count; i < n; i++)
+ {
+ Member mem = delegateNode.Members[i];
+ if (mem == null || mem is TypeNode) continue;
+ this.Visit(mem);
+ }
+ }
+ void VisitEndFilter(EndFilter/*!*/ endFilter)
+ {
+ this.DefineSequencePoint(endFilter);
+ this.Visit(endFilter.Value);
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x11);
+ this.stackHeight--;
+ }
+ void VisitEnumNode(EnumNode/*!*/ enumNode)
+ {
+ this.VisitAttributeList(enumNode.Attributes, enumNode);
+ this.VisitSecurityAttributeList(enumNode.SecurityAttributes, enumNode);
+ this.VisitReferencedType(CoreSystemTypes.Enum);
+ for (int i = 0, n = enumNode.Interfaces == null ? 0 : enumNode.Interfaces.Count; i < n; i++)
+ {
+ this.GetTypeDefOrRefOrSpecEncoded(enumNode.Interfaces[i]);
+ if (enumNode.Interfaces[i] != null) this.interfaceEntries.Add(enumNode);
+ }
+ for (int i = 0, n = enumNode.Members.Count; i < n; i++)
+ this.Visit(enumNode.Members[i]);
+ }
+ void VisitEvent(Event/*!*/ Event)
+ {
+ object eindex = this.eventIndex[Event.UniqueKey];
+ if (eindex != null) return;
+ int index = this.eventEntries.Count + 1;
+ this.eventEntries.Add(Event);
+ this.eventIndex[Event.UniqueKey] = index;
+ object evindex = this.eventMapIndex[Event.DeclaringType.UniqueKey];
+ if (evindex == null)
+ {
+ this.eventMapEntries.Add(Event);
+ this.eventMapIndex[Event.DeclaringType.UniqueKey] = this.eventMapEntries.Count;
+ }
+ if (Event.HandlerAdder != null) this.methodSemanticsEntries.Add(Event);
+ if (Event.HandlerRemover != null) this.methodSemanticsEntries.Add(Event);
+ if (Event.HandlerCaller != null) this.methodSemanticsEntries.Add(Event);
+ if (Event.OtherMethods != null)
+ for (int i = 0, n = Event.OtherMethods.Count; i < n; i++)
+ this.methodSemanticsEntries.Add(Event);
+ this.VisitAttributeList(Event.Attributes, Event);
+ }
+ void VisitExpression(Expression/*!*/ expression)
+ {
+ switch (expression.NodeType)
+ {
+ case NodeType.Dup:
+ this.methodBodyHeap.Write((byte)0x25);
+ this.IncrementStackHeight();
+ return;
+ case NodeType.Pop:
+ UnaryExpression unex = expression as UnaryExpression;
+ if (unex != null)
+ {
+ this.Visit(unex.Operand);
+ this.stackHeight--;
+ this.methodBodyHeap.Write((byte)0x26);
+ }
+ return;
+ case NodeType.Arglist:
+ this.IncrementStackHeight();
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x00);
+ return;
+ }
+ }
+ void VisitExpressionList(ExpressionList expressions)
+ {
+ if (expressions == null) return;
+ for (int i = 0, n = expressions.Count; i < n; i++)
+ this.Visit(expressions[i]);
+ }
+ void VisitExpressionStatement(ExpressionStatement/*!*/ statement)
+ {
+#if !MinimalReader
+ if (!(statement.Expression is BlockExpression))
+#endif
+ this.DefineSequencePoint(statement);
+ this.Visit(statement.Expression);
+ }
+ void VisitField(Field/*!*/ field)
+ {
+ this.VisitAttributeList(field.Attributes, field);
+ this.GetFieldIndex(field);
+ if (field.IsVolatile)
+ field.Type = RequiredModifier.For(CoreSystemTypes.IsVolatile, field.Type);
+ this.VisitReferencedType(field.Type);
+ }
+ void VisitFixupList(Fixup fixup, int targetAddress)
+ {
+ while (fixup != null)
+ {
+ this.methodBodyHeap.BaseStream.Position = fixup.fixupLocation;
+ if (fixup.shortOffset)
+ {
+ int offset = targetAddress - fixup.addressOfNextInstruction;
+ Debug.Assert(-128 <= offset && offset <= 127, "Invalid short branch");
+ this.methodBodyHeap.Write((byte)offset);
+ }
+ else
+ this.methodBodyHeap.Write((int)(targetAddress - fixup.addressOfNextInstruction));
+ fixup = fixup.nextFixUp;
+ }
+ }
+ void VisitGenericParameterList(Member/*!*/ member, TypeNodeList/*!*/ parameters)
+ {
+ if (member == null || parameters == null || !this.UseGenerics) return;
+ int sign = member is Method ? -1 : 1;
+ for (int i = 0, n = parameters.Count; i < n; i++)
+ {
+ TypeNode parameter = parameters[i];
+ if (parameter == null) continue;
+ this.typeParameterNumber[parameter.UniqueKey] = sign * (i + 1);
+ this.genericParamEntries.Add(member);
+ if (((ITypeParameter)parameter).DeclaringMember != member)
+ parameter = (TypeNode)parameter.Clone();
+ this.genericParameters.Add(parameter);
+ if (parameter.BaseType is Class && parameter.BaseType != CoreSystemTypes.Object)
+ this.genericParamConstraintEntries.Add(parameter);
+ for (int j = 0, m = parameter.Interfaces == null ? 0 : parameter.Interfaces.Count; j < m; j++)
+ this.genericParamConstraintEntries.Add(parameter);
+ }
+ }
+ void VisitIndexer(Indexer/*!*/ indexer)
+ {
+ this.Visit(indexer.Object);
+ if (indexer.Operands == null || indexer.Operands.Count < 1) return;
+ this.Visit(indexer.Operands[0]);
+ byte opCode;
+ switch (indexer.ElementType.typeCode)
+ {
+ case ElementType.Boolean:
+ case ElementType.Int8: opCode = 0x90; break;
+ case ElementType.UInt8: opCode = 0x91; break;
+ case ElementType.Int16: opCode = 0x92; break;
+ case ElementType.Char:
+ case ElementType.UInt16: opCode = 0x93; break;
+ case ElementType.Int32: opCode = 0x94; break;
+ case ElementType.UInt32: opCode = 0x95; break;
+ case ElementType.Int64:
+ case ElementType.UInt64: opCode = 0x96; break;
+ case ElementType.UIntPtr:
+ case ElementType.IntPtr: opCode = 0x97; break;
+ case ElementType.Single: opCode = 0x98; break;
+ case ElementType.Double: opCode = 0x99; break;
+ default:
+ if (this.UseGenerics && indexer.ElementType is ITypeParameter)
+ opCode = 0xa3;
+ else if (TypeNode.StripModifiers(indexer.ElementType) is Pointer)
+ opCode = 0x97;
+ else
+ opCode = 0x9a;
+ break;
+ }
+ this.methodBodyHeap.Write((byte)opCode);
+ if (opCode == 0xa3) this.methodBodyHeap.Write((int)this.GetTypeToken(indexer.ElementType));
+ this.stackHeight--;
+ }
+ void VisitInterface(Interface/*!*/ Interface)
+ {
+ if (this.UseGenerics && Interface.Template != null && Interface.Template.IsGeneric) return;
+ this.VisitAttributeList(Interface.Attributes, Interface);
+ this.VisitSecurityAttributeList(Interface.SecurityAttributes, Interface);
+ InterfaceList interfaces = Interface.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ this.GetTypeDefOrRefOrSpecEncoded(interfaces[i]);
+ if (interfaces[i] != null) this.interfaceEntries.Add(Interface);
+ }
+ if (Interface.NodeType == NodeType.TypeParameter && !(Interface is MethodTypeParameter))
+ this.interfaceEntries.Add(Interface);
+ for (int i = 0, n = Interface.Members.Count; i < n; i++)
+ {
+ Member mem = Interface.Members[i];
+ if (mem == null || mem is TypeNode) continue;
+ this.Visit(mem);
+ }
+ }
+ void VisitLocal(Local/*!*/ local)
+ {
+ this.IncrementStackHeight();
+ int li = this.GetLocalVarIndex(local);
+ switch (li)
+ {
+ case 0: this.methodBodyHeap.Write((byte)0x06); return;
+ case 1: this.methodBodyHeap.Write((byte)0x07); return;
+ case 2: this.methodBodyHeap.Write((byte)0x08); return;
+ case 3: this.methodBodyHeap.Write((byte)0x09); return;
+ default:
+ if (li < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x11);
+ this.methodBodyHeap.Write((byte)li);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x0c);
+ this.methodBodyHeap.Write((ushort)li);
+ }
+ return;
+ }
+ }
+#if !MinimalReader
+ /// <summary>
+ /// This just gets the local variable index for each local declaration.
+ /// That associates the debug information with the right block because
+ /// it is the block the local is declared in rather than the subblock
+ /// it is first referenced in. (When different, the debugger only knows
+ /// about the local when control is in the subblock.)
+ /// </summary>
+ /// <param name="localDeclarations">The list of locals declared at this statement</param>
+ void VisitLocalDeclarationsStatement(LocalDeclarationsStatement/*!*/ localDeclarations)
+ {
+ if (localDeclarations == null) return;
+ LocalDeclarationList decls = localDeclarations.Declarations;
+ for (int i = 0, n = decls == null ? 0 : decls.Count; i < n; i++)
+ {
+ //^ assert decls != null;
+ LocalDeclaration decl = decls[i];
+ if (decl == null) continue;
+ Field f = decl.Field;
+ if (f == null) continue;
+ //^ assume this.currentMethod != null;
+ Local loc = this.currentMethod.GetLocalForField(f);
+ loc.Type = localDeclarations.Type;
+ this.GetLocalVarIndex(loc);
+ }
+ }
+#endif
+ void VisitLiteral(Literal/*!*/ literal)
+ {
+ this.IncrementStackHeight();
+ IConvertible ic = literal.Value as IConvertible;
+ if (ic == null)
+ {
+ Debug.Assert(literal.Value == null && !literal.Type.IsValueType);
+ this.methodBodyHeap.Write((byte)0x14); return;
+ }
+ TypeCode tc = ic.GetTypeCode();
+ switch (tc)
+ {
+ case TypeCode.Boolean:
+ case TypeCode.SByte:
+ case TypeCode.Byte:
+ case TypeCode.Char:
+ case TypeCode.Int16:
+ case TypeCode.UInt16:
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ case TypeCode.Int64:
+ long n = ic.ToInt64(null);
+ switch (n)
+ {
+ case -1: this.methodBodyHeap.Write((byte)0x15); break;
+ case 0: this.methodBodyHeap.Write((byte)0x16); break;
+ case 1: this.methodBodyHeap.Write((byte)0x17); break;
+ case 2: this.methodBodyHeap.Write((byte)0x18); break;
+ case 3: this.methodBodyHeap.Write((byte)0x19); break;
+ case 4: this.methodBodyHeap.Write((byte)0x1a); break;
+ case 5: this.methodBodyHeap.Write((byte)0x1b); break;
+ case 6: this.methodBodyHeap.Write((byte)0x1c); break;
+ case 7: this.methodBodyHeap.Write((byte)0x1d); break;
+ case 8: this.methodBodyHeap.Write((byte)0x1e); break;
+ default:
+ if (n >= System.SByte.MinValue && n <= System.SByte.MaxValue)
+ {
+ this.methodBodyHeap.Write((byte)0x1f);
+ this.methodBodyHeap.Write((byte)n);
+ }
+ else if (n >= System.Int32.MinValue && n <= System.Int32.MaxValue ||
+ n <= System.UInt32.MaxValue && (tc == TypeCode.Char || tc == TypeCode.UInt16 || tc == TypeCode.UInt32))
+ {
+ if (n == System.UInt32.MaxValue && tc != TypeCode.Int64)
+ this.methodBodyHeap.Write((byte)0x15);
+ else
+ {
+ this.methodBodyHeap.Write((byte)0x20);
+ this.methodBodyHeap.Write((int)n);
+ }
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0x21);
+ this.methodBodyHeap.Write((long)n);
+ tc = TypeCode.Empty; //Suppress conversion to long
+ }
+ break;
+ }
+ if (tc == TypeCode.Int64)
+ this.methodBodyHeap.Write((byte)0x6a);
+ return;
+
+ case TypeCode.UInt64:
+ this.methodBodyHeap.Write((byte)0x21);
+ this.methodBodyHeap.Write(ic.ToUInt64(null));
+ return;
+
+ case TypeCode.Single:
+ this.methodBodyHeap.Write((byte)0x22);
+ this.methodBodyHeap.Write(ic.ToSingle(null));
+ return;
+
+ case TypeCode.Double:
+ this.methodBodyHeap.Write((byte)0x23);
+ this.methodBodyHeap.Write(ic.ToDouble(null));
+ return;
+
+ case TypeCode.String:
+ this.methodBodyHeap.Write((byte)0x72);
+ this.methodBodyHeap.Write((int)(this.GetUserStringIndex((String)literal.Value) | 0x70000000));
+ return;
+ }
+ Debug.Assert(false, "Unexpected literal type");
+ }
+ void VisitMemberBinding(MemberBinding/*!*/ memberBinding)
+ {
+ if (memberBinding.TargetObject != null)
+ {
+ this.Visit(memberBinding.TargetObject);
+ if (memberBinding.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ this.methodBodyHeap.Write((byte)0x7b);
+ }
+ else
+ {
+ this.IncrementStackHeight();
+ if (memberBinding.Volatile)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x13);
+ }
+ this.methodBodyHeap.Write((byte)0x7e);
+ }
+ this.methodBodyHeap.Write((int)this.GetFieldToken((Field)memberBinding.BoundMember));
+ return;
+ }
+ void VisitMethod(Method/*!*/ method)
+ {
+ if (this.UseGenerics && method.Template != null && method.Template.IsGeneric) return;
+ this.GetMethodIndex(method);
+ this.VisitAttributeList(method.Attributes, method);
+ this.VisitSecurityAttributeList(method.SecurityAttributes, method);
+ for (int i = 0, n = method.Parameters == null ? 0 : method.Parameters.Count; i < n; i++)
+ {
+ Parameter par = method.Parameters[i];
+ if (par == null) continue;
+ this.VisitAttributeList(par.Attributes, par);
+ this.VisitReferencedType(par.Type);
+ }
+ if (method.ReturnType != null)
+ this.VisitReferencedType(method.ReturnType);
+ if (!method.IsAbstract && method.Body != null)
+ {
+ if (method.Body.Statements != null && method.Body.Statements.Count > 0)
+ this.VisitMethodBody(method);
+ }
+ MethodList implementedInterfaceMethods = method.ImplementedInterfaceMethods;
+ for (int i = 0, n = implementedInterfaceMethods == null ? 0 : implementedInterfaceMethods.Count; i < n; i++)
+ {
+ Method im = implementedInterfaceMethods[i];
+ if (im == null) continue;
+ this.methodImplEntries.Add(method);
+ }
+ if ((method.Flags & MethodFlags.PInvokeImpl) != 0 && method.PInvokeImportName != null && method.PInvokeModule != null)
+ {
+ this.implMapEntries.Add(method);
+ this.GetStringIndex(method.PInvokeImportName);
+ this.GetModuleRefIndex(method.PInvokeModule);
+ }
+ }
+ void VisitMethodBody(Method/*!*/ method)
+ {
+ //Visit body, emitting IL bytes and gathering information
+ this.methodBodyHeap = new BinaryWriter(new MemoryStream());
+ this.methodInfo = new MethodInfo();
+ this.currentMethod = method;
+ this.stackHeightMax = 0;
+ this.stackHeightExitTotal = 0;
+#if !ROTOR
+ if (this.symWriter != null)
+ {
+ this.methodInfo.debugLocals = new LocalList();
+ this.methodInfo.signatureLengths = new Int32List();
+ this.methodInfo.signatureOffsets = new Int32List();
+ this.methodInfo.statementNodes = new NodeList();
+ this.methodInfo.statementOffsets = new Int32List();
+ this.symWriter.OpenMethod((uint)this.GetMethodDefToken(method));
+ this.symWriter.OpenScope(0u);
+#if !MinimalReader
+ MethodScope scope = method.Scope;
+ if (scope != null)
+ {
+ UsedNamespaceList usedNamespaces = scope.UsedNamespaces;
+ for (int i = 0, n = usedNamespaces == null ? 0 : usedNamespaces.Count; i < n; i++)
+ {
+ //^ assert usedNamespaces != null;
+ UsedNamespace uns = usedNamespaces[i];
+ if (uns == null || uns.Namespace == null) continue;
+ this.symWriter.UsingNamespace(uns.Namespace.ToString());
+ }
+ }
+#endif
+ }
+#endif
+#if !FxCop
+ int originalAddress = 0;
+ if (method.LocalList != null)
+ {
+ for (int i = 0, n = method.LocalList.Count; i < n; i++)
+ {
+ Local loc = method.LocalList[i];
+ if (loc == null) continue;
+ this.GetLocalVarIndex(loc);
+ }
+#if !ROTOR
+ if (this.symWriter != null)
+ {
+ int currentAddress = (int)this.methodBodyHeap.BaseStream.Position;
+ originalAddress = currentAddress;
+ this.symWriter.OpenScope((uint)currentAddress);
+ }
+#endif
+ }
+#endif
+ int exceptionHandlersCount = method.ExceptionHandlers == null ? 0 : method.ExceptionHandlers.Count;
+ if (exceptionHandlersCount > 0)
+ {
+ this.exceptionBlock = new TrivialHashtable();
+ for (int i = 0; i < exceptionHandlersCount; i++)
+ {
+ ExceptionHandler eh = method.ExceptionHandlers[i];
+ if (eh == null || eh.HandlerStartBlock == null || (eh.HandlerType != NodeType.Catch && eh.HandlerType != NodeType.Filter)) continue;
+ this.exceptionBlock[eh.HandlerStartBlock.UniqueKey] = eh;
+ }
+ }
+ this.VisitBlock(method.Body);
+
+#if !FxCop
+ if (method.LocalList != null)
+ {
+#if !ROTOR
+ if (this.symWriter != null)
+ {
+ DefineLocalVariables(originalAddress, method.LocalList);
+ }
+#endif
+ }
+#endif
+
+ this.methodBodiesHeapIndex[method.UniqueKey] = (int)this.methodBodiesHeap.BaseStream.Position;
+ int maxStack = this.stackHeightExitTotal + this.stackHeightMax; //Wildly pessimistic estimate. Works dandy if BBlocks never leave anything on the stack.
+ if (exceptionHandlersCount > 0 && maxStack == 0) maxStack = 1;
+ int codeSize = (int)this.methodBodyHeap.BaseStream.Position;
+ int localVarSigTok = this.methodInfo.localVarSigTok;
+ bool fatHeader = codeSize >= 64 || exceptionHandlersCount > 0 || maxStack > 8 || localVarSigTok != 0;
+ if (fatHeader)
+ {
+ //Emit fat header
+ byte header = 0x03;
+ if (method.InitLocals) header |= 0x10;
+ if (exceptionHandlersCount > 0) header |= 0x08;
+ this.methodBodiesHeap.Write((byte)header);
+ this.methodBodiesHeap.Write((byte)0x30); //top 4 bits represent length of fat header in dwords. Heaven only knows why.
+ this.methodBodiesHeap.Write((short)maxStack);
+ this.methodBodiesHeap.Write((int)codeSize);
+ if (localVarSigTok != 0)
+ {
+ if (this.methodInfo.localVarIndex.Count > 127)
+ {
+ //Need to make space for the two byte count
+ this.methodInfo.localVarSignature.Write((byte)0);
+ byte[] buf = this.methodInfo.localVarSignature.BaseStream.Buffer;
+ int n = buf.Length;
+ for (int i = n - 2; i > 1; i--) buf[i + 1] = buf[i];
+ }
+ this.methodInfo.localVarSignature.BaseStream.Position = 0;
+ this.methodInfo.localVarSignature.Write((byte)7);
+ Ir2md.WriteCompressedInt(this.methodInfo.localVarSignature, this.methodInfo.localVarIndex.Count);
+ Debug.Assert(this.methodInfo.localVarIndex.Count <= 0xFFFE);
+ }
+ this.methodBodiesHeap.Write((int)localVarSigTok);
+ }
+ else
+ {
+ //Emit tiny header
+ this.methodBodiesHeap.Write((byte)(codeSize << 2 | 2));
+ }
+ //Copy body to bodies heap
+ ((MemoryStream)this.methodBodyHeap.BaseStream).WriteTo(this.methodBodiesHeap.BaseStream);
+ int pad = (int)this.methodBodiesHeap.BaseStream.Position;
+ while (pad % 4 != 0) { pad++; this.methodBodiesHeap.Write((byte)0); }
+ if (fatHeader)
+ {
+ //Emit exception handler entries
+ int[] tryOffsets = new int[exceptionHandlersCount];
+ int[] tryLengths = new int[exceptionHandlersCount];
+ int[] handlerOffsets = new int[exceptionHandlersCount];
+ int[] handlerLengths = new int[exceptionHandlersCount];
+ bool fatFormat = false;
+ for (int i = 0; i < exceptionHandlersCount; i++)
+ {
+ ExceptionHandler eh = method.ExceptionHandlers[i];
+ int tryOffset = tryOffsets[i] = (int)this.methodInfo.fixupIndex[eh.TryStartBlock.UniqueKey];
+ int tryLength = tryLengths[i] = ((int)this.methodInfo.fixupIndex[eh.BlockAfterTryEnd.UniqueKey]) - tryOffset;
+ int handlerOffset = handlerOffsets[i] = (int)this.methodInfo.fixupIndex[eh.HandlerStartBlock.UniqueKey];
+ int handlerLength = handlerLengths[i] = ((int)this.methodInfo.fixupIndex[eh.BlockAfterHandlerEnd.UniqueKey]) - handlerOffset;
+ if (tryOffset > 0xffff || tryLength > 0xff || handlerOffset > 0xffff || handlerLength > 0xff) fatFormat = true;
+ }
+ if (exceptionHandlersCount * 12 > 0xff) fatFormat = true;
+ if (fatFormat)
+ {
+ int dataSize = exceptionHandlersCount * 24 + 4;
+ this.methodBodiesHeap.Write((byte)0x41);
+ this.methodBodiesHeap.Write((byte)(dataSize & 0xff));
+ this.methodBodiesHeap.Write((short)((dataSize >> 8) & 0xffff));
+ }
+ else
+ {
+ int dataSize = exceptionHandlersCount * 12 + 4;
+ this.methodBodiesHeap.Write((byte)0x01);
+ this.methodBodiesHeap.Write((byte)dataSize);
+ this.methodBodiesHeap.Write((short)0);
+ }
+ for (int i = 0; i < exceptionHandlersCount; i++)
+ {
+ ExceptionHandler eh = method.ExceptionHandlers[i];
+ byte flags = 0;
+ switch (eh.HandlerType)
+ {
+ case NodeType.Filter: flags = 0x0001; break;
+ case NodeType.Finally: flags = 0x0002; break;
+ case NodeType.FaultHandler: flags = 0x0004; break;
+ }
+ if (fatFormat)
+ {
+ this.methodBodiesHeap.Write((int)flags);
+ this.methodBodiesHeap.Write((int)tryOffsets[i]);
+ this.methodBodiesHeap.Write((int)tryLengths[i]);
+ this.methodBodiesHeap.Write((int)handlerOffsets[i]);
+ this.methodBodiesHeap.Write((int)handlerLengths[i]);
+ }
+ else
+ {
+ this.methodBodiesHeap.Write((short)flags);
+ this.methodBodiesHeap.Write((ushort)tryOffsets[i]);
+ this.methodBodiesHeap.Write((byte)tryLengths[i]);
+ this.methodBodiesHeap.Write((ushort)handlerOffsets[i]);
+ this.methodBodiesHeap.Write((byte)handlerLengths[i]);
+ }
+ if (eh.FilterType != null)
+ this.methodBodiesHeap.Write((int)this.GetTypeToken(eh.FilterType));
+ else if (eh.FilterExpression != null)
+ this.methodBodiesHeap.Write((int)this.methodInfo.fixupIndex[eh.FilterExpression.UniqueKey]);
+ else
+ this.methodBodiesHeap.Write((int)0);
+ }
+ }
+#if !ROTOR
+ if (this.symWriter != null)
+ {
+ MethodInfo mInfo = this.methodInfo;
+ NodeList statementNodes = mInfo.statementNodes;
+ Int32List statementOffsets = mInfo.statementOffsets;
+ int n = statementNodes.Count;
+ int j = 0;
+ int k = 0;
+ Document d = null;
+ ISymUnmanagedDocumentWriter doc = null;
+ for (int i = 0; i < n; i++)
+ {
+ Document e = statementNodes[i].SourceContext.Document;
+ if (e == null) continue;
+ if (e != d)
+ {
+ d = e;
+ if (doc != null) this.DefineSequencePoints(statementNodes, statementOffsets, j, k, doc);
+ doc = this.GetDocumentWriter(d);
+ j = i;
+ k = 0;
+ }
+ k++;
+ }
+ this.DefineSequencePoints(statementNodes, statementOffsets, j, k, doc);
+ this.symWriter.CloseScope((uint)this.methodBodyHeap.BaseStream.Position);
+ this.symWriter.CloseMethod();
+ }
+#endif
+ //this.methodBodyHeap = null;
+ //this.methodInfo = null;
+ //this.currentMethod = null;
+ }
+
+#if !ROTOR
+ private void DefineLocalVariables(int startAddress, LocalList locals)
+ {
+ MethodInfo mInfo = this.methodInfo;
+ for (int i = 0, n = locals.Count; i < n; i++)
+ {
+ Local loc = locals[i];
+ string name = loc.Name.ToString();
+ unsafe
+ {
+ fixed (byte* p = mInfo.localVarSignature.BaseStream.Buffer)
+ {
+ IntPtr sp = (IntPtr)(p + mInfo.signatureOffsets[i]);
+ uint c = (uint)mInfo.signatureLengths[i];
+ this.symWriter.DefineLocalVariable(name, 0u, c, sp, 1u, (uint)this.GetLocalVarIndex(loc), 0u, 0u, 0u);
+ }
+ }
+ }
+ int posOfFirstInstructionOfNextBlock = this.methodBodyHeap.BaseStream.Position;
+ if (posOfFirstInstructionOfNextBlock > startAddress)
+ this.symWriter.CloseScope((uint)(posOfFirstInstructionOfNextBlock - 1));
+ else
+ this.symWriter.CloseScope((uint)startAddress);
+ }
+#endif
+ void DefineSequencePoint(Node node)
+ {
+#if !ROTOR
+ if (this.symWriter != null && node != null && node.SourceContext.Document != null && !node.SourceContext.Document.Hidden)
+ {
+ this.methodInfo.statementNodes.Add(node);
+ this.methodInfo.statementOffsets.Add(this.methodBodyHeap.BaseStream.Position);
+ }
+#endif
+ }
+#if !ROTOR
+ void DefineSequencePoints(NodeList/*!*/ statementNodes, Int32List/*!*/ statementOffsets, int start, int count, ISymUnmanagedDocumentWriter doc)
+ //^ requires this.symWriter != null;
+ {
+ if (count == 0) return;
+ uint[] offsets = new uint[count];
+ uint[] lines = new uint[count];
+ uint[] columns = new uint[count];
+ uint[] endLines = new uint[count];
+ uint[] endColumns = new uint[count];
+ for (int i = 0; i < count; i++)
+ {
+ Node n = statementNodes[i + start];
+ offsets[i] = i + start == 0 ? 0 : (uint)statementOffsets[i + start];
+ lines[i] = (uint)n.SourceContext.StartLine;
+ columns[i] = (uint)n.SourceContext.StartColumn;
+ endLines[i] = (uint)n.SourceContext.EndLine;
+ endColumns[i] = (uint)n.SourceContext.EndColumn;
+ }
+ this.symWriter.DefineSequencePoints(doc, (uint)count, offsets, lines, columns, endLines, endColumns);
+ }
+#endif
+ void VisitModule(Module/*!*/ module)
+ {
+ //REVIEW: check that module has no explicit lists of assembly/module references?
+ this.ForceTemplateTypeMethodBodiesToGetSpecialized(module);
+ this.VisitAttributeList(module.Attributes, module);
+ if (this.assembly != null)
+ {
+ Module m = new Module();
+ m.Attributes = this.assembly.ModuleAttributes;
+ this.VisitAttributeList(m.Attributes, m);
+ this.VisitSecurityAttributeList(this.assembly.SecurityAttributes, this.assembly);
+ }
+ TypeNodeList allTypes = module.Types.Clone();
+ for (int k = 0; k < allTypes.Count; )
+ {
+ int typeCount = module.Types.Count;
+ for (int i = k, n = k, m = allTypes.Count; i < (n = allTypes.Count); )
+ {
+ for (; i < n; i++)
+ {
+ TypeNode t = allTypes[i];
+ if (t == null) continue;
+ if (this.UseGenerics && t.Template != null && t.Template.IsGeneric)
+ {
+ allTypes[i] = null;
+ continue;
+ }
+ this.GetTypeDefIndex(t);
+ if (i >= m) this.nestedClassEntries.Add(t);
+ MemberList members = t.Members;
+ if (members != null)
+ {
+ for (int j = 0, numMembers = members.Count; j < numMembers; j++)
+ {
+ TypeNode nt = members[j] as TypeNode;
+ if (nt != null) allTypes.Add(nt);
+ }
+ }
+ }
+ }
+ for (int i = k, n = allTypes.Count; i < n; i++)
+ {
+ TypeNode t = allTypes[i];
+ if (t == null) continue;
+ if (this.UseGenerics && t.Template != null && t.Template.IsGeneric)
+ {
+ allTypes[i] = null;
+ continue;
+ }
+ MemberList mems = t.Members;
+ if (t is EnumNode)
+ { //Work around JIT bug in Beta2
+ for (int jj = 0, mm = mems.Count; jj < mm; jj++)
+ {
+ Field f = mems[jj] as Field;
+ if (f == null || f.IsStatic) continue;
+ mems[jj] = mems[0];
+ mems[0] = f;
+ break;
+ }
+ }
+ for (int j = 0, m = mems.Count; j < m; j++)
+ {
+ Member mem = mems[j];
+ if (mem == null) continue;
+ switch (mem.NodeType)
+ {
+ case NodeType.Field: this.GetFieldIndex((Field)mem); break;
+ case NodeType.Method:
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ Method meth = (Method)mem;
+ if (this.UseGenerics && meth.Template != null && meth.Template.IsGeneric)
+ this.GetMethodSpecIndex(meth);
+ else
+ this.GetMethodIndex(meth);
+ break;
+ }
+ }
+ }
+ for (int i = k, n = allTypes.Count; i < n; i++, k++)
+ {
+ TypeNode t = allTypes[i];
+ if (t == null) continue;
+ this.Visit(t);
+ }
+ for (int i = typeCount, n = module.Types.Count; i < n; i++)
+ {
+ TypeNode t = module.Types[i];
+ if (t == null) continue;
+ Debug.Assert(t.IsNotFullySpecialized);
+ //allTypes.Add(t);
+ }
+ }
+ }
+ sealed class MethodSpecializer : StandardVisitor
+ {
+ private Module/*!*/ module;
+
+ internal MethodSpecializer(Module/*!*/ module)
+ {
+ this.module = module;
+ //^ base();
+ }
+
+ public override Method VisitMethod(Method method)
+ {
+ if (method == null) return null;
+ if (method.Template == null || method.Template.IsGeneric) return method;
+ TypeNodeList templateParameters = null;
+ TypeNodeList templateArguments = null;
+ if (method.TemplateArguments != null && method.TemplateArguments.Count > 0)
+ {
+ templateParameters = method.Template.TemplateParameters;
+ templateArguments = method.TemplateArguments;
+ }
+ else
+ {
+ TypeNode tdt = method.Template.DeclaringType;
+ TypeNode dt = method.DeclaringType;
+ templateParameters = tdt.ConsolidatedTemplateParameters;
+ templateArguments = dt.ConsolidatedTemplateArguments;
+ if (templateArguments == null) templateArguments = templateParameters;
+ }
+ if (templateParameters == null || templateParameters.Count == 0) return method;
+ TypeNode declaringTemplate = method.DeclaringType == null ? null : method.DeclaringType.Template;
+ bool savedNewTemplateInstanceIsRecursive = false;
+ if (declaringTemplate != null)
+ {
+ savedNewTemplateInstanceIsRecursive = declaringTemplate.NewTemplateInstanceIsRecursive;
+ declaringTemplate.NewTemplateInstanceIsRecursive = method.DeclaringType.IsNotFullySpecialized;
+ }
+ Duplicator duplicator = new Duplicator(this.module, method.DeclaringType);
+#if !MinimalReader
+ TypeNode closureClone = null;
+ if (method.Template.Scope != null && method.Template.Scope.CapturedForClosure)
+ {
+ duplicator.TypesToBeDuplicated[method.Template.Scope.ClosureClass.UniqueKey] = method.Template.Scope.ClosureClass;
+ duplicator.RecordOriginalAsTemplate = true;
+ closureClone = duplicator.VisitTypeNode(method.Template.Scope.ClosureClass);
+ }
+#endif
+ int n = method.Parameters == null ? 0 : method.Parameters.Count;
+ int m = method.Template.Parameters == null ? 0 : method.Template.Parameters.Count;
+ if (n != m) { Debug.Assert(false); if (n > m) n = m; }
+ for (int i = 0; i < n; i++)
+ {
+ Parameter par = method.Parameters[i];
+ Parameter tpar = method.Template.Parameters[i];
+ if (par == null || tpar == null) continue;
+ duplicator.DuplicateFor[tpar.UniqueKey] = par;
+ }
+ n = method.TemplateParameters == null ? 0 : method.TemplateParameters.Count;
+ m = method.Template.TemplateParameters == null ? 0 : method.Template.TemplateParameters.Count;
+ if (n != m && n > 0) { Debug.Assert(false); if (n > m) n = m; }
+ for (int i = 0; i < n; i++)
+ {
+ TypeNode tpar = method.TemplateParameters[i];
+ TypeNode ttpar = method.Template.TemplateParameters[i];
+ if (tpar == null || ttpar == null) continue;
+ duplicator.DuplicateFor[ttpar.UniqueKey] = tpar;
+ }
+ Method dup = duplicator.VisitMethod(method.Template);
+ //^ assume dup != null;
+ Specializer specializer = new Specializer(this.module, templateParameters, templateArguments);
+ specializer.VisitMethod(dup);
+#if !MinimalReader
+ if (closureClone != null)
+ {
+ specializer.VisitTypeNode(closureClone);
+ if (method.TemplateArguments != null && method.TemplateArguments.Count > 0)
+ closureClone.Name = Identifier.For(closureClone.Name.ToString() + closureClone.UniqueKey);
+ MemberList dtMembers = method.DeclaringType.Members;
+ for (int i = 0, nmems = dtMembers == null ? 0 : dtMembers.Count; i < nmems; i++)
+ {
+ ClosureClass closureRef = dtMembers[i] as ClosureClass;
+ if (closureRef != null && closureRef.Name.UniqueIdKey == closureClone.Name.UniqueIdKey)
+ {
+ //This happens when the declaring type was instantiated after Normalizer has already injected a closure into the template
+ dtMembers[i] = closureClone;
+ closureClone = null;
+ break;
+ }
+ }
+ if (closureClone != null)
+ method.DeclaringType.Members.Add(closureClone);
+ }
+#endif
+ if (method.Template.DeclaringType.DeclaringModule != this.module)
+ {
+ //Dealing with imported IR that misses important type information if it contains explicit stack operations (push, pop, dup)
+ //Call a helper visitor to remove these stack operations and in the process supply the missing type information.
+ Unstacker unstacker = new Unstacker();
+ unstacker.Visit(dup);
+ }
+ MethodBodySpecializer mbSpecializer = this.module.GetMethodBodySpecializer(templateParameters, templateArguments);
+ mbSpecializer.methodBeingSpecialized = method;
+ mbSpecializer.dummyMethod = dup;
+ mbSpecializer.VisitMethod(dup);
+ method.Body = dup.Body;
+ // HACK to try to fix parameter declaring method back to the way it was before:
+ method.Parameters = method.Parameters;
+ method.ExceptionHandlers = dup.ExceptionHandlers;
+ if (declaringTemplate != null)
+ declaringTemplate.NewTemplateInstanceIsRecursive = savedNewTemplateInstanceIsRecursive;
+ return method;
+ }
+ }
+ void ForceTemplateTypeMethodBodiesToGetSpecialized(Module/*!*/ module)
+ {
+ MethodSpecializer visitor = new MethodSpecializer(module);
+ if (module == null) return;
+ TypeNodeList types = module.Types;
+ if (types == null) return;
+ for (int i = 0; i < types.Count; i++)
+ this.ForceTemplateTypeMethodBodiesToGetSpecialized(types[i], visitor);
+ }
+ void ForceTemplateTypeMethodBodiesToGetSpecialized(TypeNode/*!*/ type, MethodSpecializer/*!*/ visitor)
+ {
+ if (type == null) return;
+ if (type.IsNotFullySpecialized || type.IsGeneric) return;
+ bool savedNewTemplateInstanceIsRecursive = type.NewTemplateInstanceIsRecursive;
+ type.NewTemplateInstanceIsRecursive = type.IsNotFullySpecialized;
+ MemberList members = type.Members;
+ if (members == null) return;
+ for (int j = 0; j < members.Count; j++)
+ {
+ Member mem = members[j];
+ if (mem == null) continue;
+ TypeNode t = mem as TypeNode;
+ if (t != null)
+ this.ForceTemplateTypeMethodBodiesToGetSpecialized(t, visitor);
+ else
+ visitor.VisitMethod(mem as Method);
+ }
+ type.NewTemplateInstanceIsRecursive = savedNewTemplateInstanceIsRecursive;
+ }
+ void VisitParameter(Parameter/*!*/ parameter)
+ {
+ this.IncrementStackHeight();
+#if !MinimalReader
+ ParameterBinding pb = parameter as ParameterBinding;
+ if (pb != null) parameter = pb.BoundParameter;
+#endif
+ int pi = parameter.ArgumentListIndex;
+ switch (pi)
+ {
+ case 0: this.methodBodyHeap.Write((byte)0x02); return;
+ case 1: this.methodBodyHeap.Write((byte)0x03); return;
+ case 2: this.methodBodyHeap.Write((byte)0x04); return;
+ case 3: this.methodBodyHeap.Write((byte)0x05); return;
+ default:
+ if (pi < 256)
+ {
+ this.methodBodyHeap.Write((byte)0x0e);
+ this.methodBodyHeap.Write((byte)pi);
+ }
+ else
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x09);
+ this.methodBodyHeap.Write((ushort)pi);
+ }
+ return;
+ }
+ }
+ void VisitProperty(Property/*!*/ property)
+ {
+ object pindex = this.propertyIndex[property.UniqueKey];
+ if (pindex != null) return;
+ int index = this.propertyEntries.Count + 1;
+ this.propertyEntries.Add(property);
+ this.propertyIndex[property.UniqueKey] = index;
+ object pmindex = this.propertyMapIndex[property.DeclaringType.UniqueKey];
+ if (pmindex == null)
+ {
+ this.propertyMapEntries.Add(property);
+ this.propertyMapIndex[property.DeclaringType.UniqueKey] = this.propertyMapEntries.Count;
+ }
+ if (property.Getter != null) this.methodSemanticsEntries.Add(property);
+ if (property.Setter != null) this.methodSemanticsEntries.Add(property);
+ if (property.OtherMethods != null)
+ for (int i = 0, n = property.OtherMethods.Count; i < n; i++)
+ this.methodSemanticsEntries.Add(property);
+ this.VisitAttributeList(property.Attributes, property);
+ }
+ void VisitReferencedType(TypeNode type)
+ {
+ if (type == null) return;
+ if (type.IsGeneric && type.Template == null)
+ {
+ TypeNodeList templParams = type.ConsolidatedTemplateParameters;
+ for (int i = 0, n = templParams == null ? 0 : templParams.Count; i < n; i++)
+ this.typeParameterNumber[templParams[i].UniqueKey] = i + 1;
+ }
+ switch (type.typeCode)
+ {
+ case ElementType.Pointer: this.VisitReferencedType(((Pointer)type).ElementType); return;
+ case ElementType.Reference: this.VisitReferencedType(((Reference)type).ElementType); return;
+ case ElementType.Array:
+ case ElementType.SzArray: this.VisitReferencedType(((ArrayType)type).ElementType); return;
+ case ElementType.OptionalModifier:
+ case ElementType.RequiredModifier:
+ TypeModifier tm = (TypeModifier)type;
+ this.VisitReferencedType(tm.Modifier);
+ this.VisitReferencedType(tm.ModifiedType);
+ return;
+ case ElementType.FunctionPointer:
+ FunctionPointer fp = (FunctionPointer)type;
+ this.VisitReferencedType(fp.ReturnType);
+ for (int i = 0, n = fp.ParameterTypes == null ? 0 : fp.ParameterTypes.Count; i < n; i++)
+ this.VisitReferencedType(fp.ParameterTypes[i]);
+ return;
+ case ElementType.ValueType:
+ case ElementType.Class:
+ break;
+ default:
+ return;
+ }
+ if (this.IsStructural(type))
+ this.GetTypeSpecIndex(type);
+ else if (type.DeclaringModule == this.module)
+ this.GetTypeDefIndex(type);
+ else if (type.DeclaringModule != null)
+ this.GetTypeRefIndex(type);
+ else if (type.typeCode == ElementType.ValueType || type.typeCode == ElementType.Class)
+ {
+ //Get here for type parameters
+ if (this.UseGenerics && this.typeParameterNumber[type.UniqueKey] != null) return;
+ type.DeclaringModule = this.module;
+ this.GetTypeDefIndex(type);
+ }
+ else
+ Debug.Assert(false);
+ }
+ void VisitReturn(Return/*!*/ Return)
+ {
+ this.DefineSequencePoint(Return);
+ if (Return.Expression != null)
+ {
+ this.Visit(Return.Expression);
+ this.stackHeight--;
+ }
+ this.methodBodyHeap.Write((byte)0x2a);
+ }
+ void VisitSecurityAttributeList(SecurityAttributeList attrs, Node/*!*/ node)
+ {
+ if (attrs == null) return;
+ int n = attrs.Count;
+ if (n == 0) return;
+ int m = n;
+ for (int j = 0; j < n; j++)
+ {
+ SecurityAttribute a = attrs[j];
+ if (a == null) m--;
+ }
+ if (m == 0) return;
+ n = m;
+ int codedIndex = this.GetSecurityAttributeParentCodedIndex(node);
+ this.securityAttributeCount += n;
+ m = this.nodesWithSecurityAttributes.Count;
+ this.nodesWithSecurityAttributes.Add(node);
+ int i = 0; //after the for loop i will be position where the new node should be in sorted list
+ NodeList nodes = this.nodesWithSecurityAttributes;
+ for (i = m; i > 0; i--)
+ {
+ Node other = nodes[i - 1];
+ int oci = this.GetSecurityAttributeParentCodedIndex(other);
+ if (oci < codedIndex) break;
+ }
+ if (i == m) return; //node is already where it should be
+ for (int j = m; j > i; j--) nodes[j] = nodes[j - 1]; //Make space at postion i
+ nodes[i] = node;
+ }
+ void VisitStatement(Statement/*!*/ statement)
+ {
+ this.DefineSequencePoint(statement);
+ switch (statement.NodeType)
+ {
+ case NodeType.Nop: this.methodBodyHeap.Write((byte)0x00); break;
+ case NodeType.DebugBreak: this.methodBodyHeap.Write((byte)0x01); break;
+ case NodeType.EndFinally: this.methodBodyHeap.Write((byte)0xdc); break;
+ }
+ }
+ void VisitStruct(Struct/*!*/ Struct)
+ {
+ if (this.UseGenerics && Struct.Template != null && Struct.Template.IsGeneric) return;
+ this.VisitAttributeList(Struct.Attributes, Struct);
+ this.VisitSecurityAttributeList(Struct.SecurityAttributes, Struct);
+ this.VisitReferencedType(CoreSystemTypes.ValueType);
+ InterfaceList interfaces = Struct.Interfaces;
+ for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
+ {
+ this.GetTypeDefOrRefOrSpecEncoded(interfaces[i]);
+ if (interfaces[i] != null) this.interfaceEntries.Add(Struct);
+ }
+ for (int i = 0, n = Struct.Members.Count; i < n; i++)
+ {
+ Member m = Struct.Members[i];
+ if (m is TypeNode) continue;
+ this.Visit(m);
+ }
+ if ((Struct.Flags & (TypeFlags.ExplicitLayout | TypeFlags.SequentialLayout)) != 0 && (Struct.PackingSize != 0 || Struct.ClassSize != 0))
+ this.classLayoutEntries.Add(Struct);
+ }
+ void VisitSwitchInstruction(SwitchInstruction/*!*/ switchInstruction)
+ {
+ this.Visit(switchInstruction.Expression);
+ this.stackHeight--;
+ BlockList targets = switchInstruction.Targets;
+ int n = targets != null ? targets.Count : 0;
+ int addressOfNextInstruction = ((int)this.methodBodyHeap.BaseStream.Position) + 5 + 4 * n;
+ this.methodBodyHeap.Write((byte)0x45);
+ this.methodBodyHeap.Write((uint)n);
+ for (int i = 0; i < n; i++)
+ this.methodBodyHeap.Write((int)this.GetOffset(targets[i], addressOfNextInstruction));
+ }
+ void VisitTernaryExpression(TernaryExpression/*!*/ expression)
+ {
+ this.Visit(expression.Operand1);
+ this.Visit(expression.Operand2);
+ this.Visit(expression.Operand3);
+ this.methodBodyHeap.Write((byte)0xfe);
+ if (expression.NodeType == NodeType.Cpblk)
+ this.methodBodyHeap.Write((byte)0x17);
+ else
+ this.methodBodyHeap.Write((byte)0x18);
+ this.stackHeight -= 3;
+ }
+ void VisitThis(This/*!*/ This)
+ {
+ this.IncrementStackHeight();
+ this.methodBodyHeap.Write((byte)0x02);
+ }
+ void VisitThrow(Throw/*!*/ Throw)
+ {
+ this.DefineSequencePoint(Throw);
+ if (Throw.NodeType == NodeType.Rethrow)
+ {
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x1a);
+ }
+ else
+ {
+ this.Visit(Throw.Expression);
+ this.methodBodyHeap.Write((byte)0x7a);
+ }
+ this.stackHeight--;
+ }
+ void VisitUnaryExpression(UnaryExpression/*!*/ unaryExpression)
+ {
+ switch (unaryExpression.NodeType)
+ {
+ case NodeType.Ldtoken:
+ this.methodBodyHeap.Write((byte)0xd0);
+ Literal lit = unaryExpression.Operand as Literal;
+ if (lit != null)
+ {
+ if (lit.Value == null) return;
+ this.methodBodyHeap.Write((int)this.GetTypeDefToken((TypeNode)lit.Value));
+ }
+ else
+ {
+ if (unaryExpression.Operand == null) return;
+ Member m = ((MemberBinding)unaryExpression.Operand).BoundMember;
+ if (m == null) return;
+ Method meth = m as Method;
+ if (meth != null)
+ this.methodBodyHeap.Write((int)this.GetMethodToken(meth));
+ else
+ this.methodBodyHeap.Write((int)this.GetFieldToken((Field)m));
+ }
+ this.IncrementStackHeight();
+ return;
+
+ case NodeType.Ldftn:
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x06);
+ this.methodBodyHeap.Write((int)this.GetMethodToken((Method)((MemberBinding)unaryExpression.Operand).BoundMember));
+ this.IncrementStackHeight();
+ return;
+
+ case NodeType.Sizeof:
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x1c);
+ this.methodBodyHeap.Write((int)this.GetTypeToken((TypeNode)((Literal)unaryExpression.Operand).Value));
+ this.IncrementStackHeight();
+ return;
+
+ case NodeType.SkipCheck:
+ this.methodBodyHeap.Write((byte)0xfe);
+ this.methodBodyHeap.Write((byte)0x19);
+ switch (unaryExpression.Operand.NodeType)
+ {
+ case NodeType.Castclass:
+ case NodeType.Unbox:
+ this.methodBodyHeap.Write((byte)0x01);
+ break;
+ default:
+ Debug.Assert(false);
+ this.methodBodyHeap.Write((byte)0x00);
+ break;
+ }
+ this.VisitExpression(unaryExpression.Operand);
+ return;
+ }
+ this.Visit(unaryExpression.Operand);
+ byte opCode = 0;
+ switch (unaryExpression.NodeType)
+ {
+ case NodeType.Neg: opCode = 0x65; break;
+ case NodeType.Not: opCode = 0x66; break;
+ case NodeType.Conv_I1: opCode = 0x67; break;
+ case NodeType.Conv_I2: opCode = 0x68; break;
+ case NodeType.Conv_I4: opCode = 0x69; break;
+ case NodeType.Conv_I8: opCode = 0x6a; break;
+ case NodeType.Conv_R4: opCode = 0x6b; break;
+ case NodeType.Conv_R8: opCode = 0x6c; break;
+ case NodeType.Conv_U4: opCode = 0x6d; break;
+ case NodeType.Conv_U8: opCode = 0x6e; break;
+ case NodeType.Conv_R_Un: opCode = 0x76; break;
+ case NodeType.Conv_Ovf_I1_Un: opCode = 0x82; break;
+ case NodeType.Conv_Ovf_I2_Un: opCode = 0x83; break;
+ case NodeType.Conv_Ovf_I4_Un: opCode = 0x84; break;
+ case NodeType.Conv_Ovf_I8_Un: opCode = 0x85; break;
+ case NodeType.Conv_Ovf_U1_Un: opCode = 0x86; break;
+ case NodeType.Conv_Ovf_U2_Un: opCode = 0x87; break;
+ case NodeType.Conv_Ovf_U4_Un: opCode = 0x88; break;
+ case NodeType.Conv_Ovf_U8_Un: opCode = 0x89; break;
+ case NodeType.Conv_Ovf_I_Un: opCode = 0x8a; break;
+ case NodeType.Conv_Ovf_U_Un: opCode = 0x8b; break;
+ case NodeType.Ldlen: opCode = 0x8e; break;
+ case NodeType.Conv_Ovf_I1: opCode = 0xb3; break;
+ case NodeType.Conv_Ovf_U1: opCode = 0xb4; break;
+ case NodeType.Conv_Ovf_I2: opCode = 0xb5; break;
+ case NodeType.Conv_Ovf_U2: opCode = 0xb6; break;
+ case NodeType.Conv_Ovf_I4: opCode = 0xb7; break;
+ case NodeType.Conv_Ovf_U4: opCode = 0xb8; break;
+ case NodeType.Conv_Ovf_I8: opCode = 0xb9; break;
+ case NodeType.Conv_Ovf_U8: opCode = 0xba; break;
+ case NodeType.Ckfinite: opCode = 0xc3; break;
+ case NodeType.Conv_U2: opCode = 0xd1; break;
+ case NodeType.Conv_U1: opCode = 0xd2; break;
+ case NodeType.Conv_I: opCode = 0xd3; break;
+ case NodeType.Conv_Ovf_I: opCode = 0xd4; break;
+ case NodeType.Conv_Ovf_U: opCode = 0xd5; break;
+ case NodeType.Conv_U: opCode = 0xe0; break;
+ case NodeType.Localloc: opCode = 0x0f; this.methodBodyHeap.Write((byte)0xfe); break;
+ case NodeType.Refanytype: opCode = 0x1d; this.methodBodyHeap.Write((byte)0xfe); break;
+ }
+ this.methodBodyHeap.Write((byte)opCode);
+ }
+ static void WriteArrayShape(BinaryWriter/*!*/ target, ArrayType/*!*/ arrayType)
+ {
+ Ir2md.WriteCompressedInt(target, arrayType.Rank);
+ int n = arrayType.Sizes == null ? 0 : arrayType.Sizes.Length;
+ Ir2md.WriteCompressedInt(target, n);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert arrayType.Sizes != null;
+ Ir2md.WriteCompressedInt(target, arrayType.Sizes[i]);
+ }
+ n = arrayType.LowerBounds == null ? 0 : arrayType.LowerBounds.Length;
+ Ir2md.WriteCompressedInt(target, n);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert arrayType.LowerBounds != null;
+ Ir2md.WriteCompressedInt(target, arrayType.LowerBounds[i]);
+ }
+ }
+ internal static void WriteCompressedInt(BinaryWriter/*!*/ target, int val)
+ {
+ if (val <= 0x7f)
+ target.Write((byte)val);
+ else if (val < 0x3fff)
+ {
+ target.Write((byte)((val >> 8) | 0x80));
+ target.Write((byte)(val & 0xff));
+ }
+ else if (val < 0x1fffffff)
+ {
+ target.Write((byte)((val >> 24) | 0xc0));
+ target.Write((byte)((val & 0xff0000) >> 16));
+ target.Write((byte)((val & 0xff00) >> 8));
+ target.Write((byte)(val & 0xff));
+ }
+ else
+ Debug.Assert(false, "index too large for compression");
+ }
+ TypeNode/*!*/ WriteCustomModifiers(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ switch (type.NodeType)
+ {
+ case NodeType.RequiredModifier:
+ case NodeType.OptionalModifier:
+ TypeModifier tm = (TypeModifier)type;
+ target.Write((byte)tm.typeCode);
+ this.WriteTypeDefOrRefEncoded(target, tm.Modifier);
+ return this.WriteCustomModifiers(target, tm.ModifiedType);
+ }
+ return type;
+ }
+ void WriteCustomAttributeLiteral(BinaryWriter/*!*/ writer, Literal/*!*/ literal, bool needsTag)
+ {
+ if (literal.Type == null) return;
+ ElementType typeCode = literal.Type.typeCode;
+ if (needsTag)
+ {
+ if (typeCode == ElementType.ValueType)
+ { //Boxed enum
+ writer.Write((byte)0x55);
+ this.WriteSerializedTypeName(writer, literal.Type);
+ }
+ else if (typeCode == ElementType.Class)
+ { //a Type value
+ writer.Write((byte)0x50);
+ }
+ else if (typeCode != ElementType.Object) //a primitive
+ writer.Write((byte)typeCode);
+ }
+ Object value = literal.Value;
+ //if (value == null) return; //TODO: nope, find some other way
+ switch (typeCode)
+ {
+ case ElementType.Boolean: writer.Write((bool)value); return;
+ case ElementType.Char: writer.Write((ushort)(char)value); return;
+ case ElementType.Double: writer.Write((double)value); return;
+ case ElementType.Single: writer.Write((float)value); return;
+ case ElementType.Int16: writer.Write((short)value); return;
+ case ElementType.Int32: writer.Write((int)value); return;
+ case ElementType.Int64: writer.Write((long)value); return;
+ case ElementType.Int8: writer.Write((sbyte)value); return;
+ case ElementType.UInt16: writer.Write((ushort)value); return;
+ case ElementType.UInt32: writer.Write((uint)value); return;
+ case ElementType.UInt64: writer.Write((ulong)value); return;
+ case ElementType.UInt8: writer.Write((byte)value); return;
+ case ElementType.String: writer.Write((string)value, false); return;
+ case ElementType.ValueType: this.WriteCustomAttributeLiteral(writer, new Literal(value, ((EnumNode)literal.Type).UnderlyingType), false); return;
+ case ElementType.Class: this.WriteSerializedTypeName(writer, (TypeNode)value); return;
+ case ElementType.SzArray:
+ TypeNode elemType = ((ArrayType)literal.Type).ElementType;
+ if (needsTag)
+ writer.Write((byte)elemType.typeCode);
+ Array array = (Array)value;
+ int numElems = array == null ? -1 : array.Length;
+ writer.Write((int)numElems);
+ for (int i = 0; i < numElems; i++)
+ this.WriteCustomAttributeLiteral(writer, new Literal(array.GetValue(i), elemType), false);
+ return;
+ case ElementType.Object:
+ Literal lit = (Literal)literal.Clone();
+ TypeNode t = null;
+ switch (Convert.GetTypeCode(lit.Value))
+ {
+ case TypeCode.Boolean: t = CoreSystemTypes.Boolean; break;
+ case TypeCode.Byte: t = CoreSystemTypes.UInt8; break;
+ case TypeCode.Char: t = CoreSystemTypes.Char; break;
+ case TypeCode.Double: t = CoreSystemTypes.Double; break;
+ case TypeCode.Int16: t = CoreSystemTypes.Int16; break;
+ case TypeCode.Int32: t = CoreSystemTypes.Int32; break;
+ case TypeCode.Int64: t = CoreSystemTypes.Int64; break;
+ case TypeCode.SByte: t = CoreSystemTypes.Int8; break;
+ case TypeCode.Single: t = CoreSystemTypes.Single; break;
+ case TypeCode.String: t = CoreSystemTypes.String; break;
+ case TypeCode.UInt16: t = CoreSystemTypes.UInt16; break;
+ case TypeCode.UInt32: t = CoreSystemTypes.UInt32; break;
+ case TypeCode.UInt64: t = CoreSystemTypes.UInt64; break;
+ case TypeCode.Empty:
+ case TypeCode.Object:
+ Array arr = lit.Value as Array;
+ if (arr != null)
+ {
+#if !NoReflection
+ t = TypeNode.GetTypeNode(arr.GetType());
+#else
+ System.Type reflType = arr.GetType();
+ System.Type reflElemType = reflType.GetElementType();
+ AssemblyNode assem = AssemblyNode.GetAssembly(reflType.Assembly.Location);
+ TypeNode cciElemType = assem.GetType(Identifier.For(reflElemType.Namespace), Identifier.For(reflElemType.Name));
+ t = cciElemType.GetArrayType(reflType.GetArrayRank());
+#endif
+ }
+ else
+ t = CoreSystemTypes.Type;
+ break;
+ }
+ if (t == null) break;
+ lit.Type = t;
+ this.WriteCustomAttributeLiteral(writer, lit, true);
+ return;
+ }
+ Debug.Assert(false, "Unexpected type in custom attribute");
+ }
+ bool AttributesContains(AttributeList al, TypeNode/*!*/ a)
+ {
+ if (al == null) return false;
+ for (int i = 0, n = al.Count; i < n; i++)
+ {
+ if (al[i] != null && al[i].Type == a)
+ return true;
+ }
+ return false;
+ }
+ void WriteMethodSignature(BinaryWriter/*!*/ target, Method/*!*/ method)
+ {
+ if (this.UseGenerics)
+ {
+ if (method.Template != null && method.Template.IsGeneric)
+ {
+ //Signature is being used in MethodDef table
+ TypeNodeList types = method.TemplateArguments;
+ int m = types == null ? 0 : types.Count;
+ target.Write((byte)(method.CallingConvention | CallingConventionFlags.Generic));
+ Ir2md.WriteCompressedInt(target, m);
+ }
+ else if (method.DeclaringType.Template != null && method.DeclaringType.Template.IsGeneric)
+ {
+ Method unspecializedMethod = this.GetUnspecializedMethod(method);
+ this.WriteMethodSignature(target, unspecializedMethod);
+ return;
+ }
+ else if (method.IsGeneric)
+ {
+ TypeNodeList types = method.TemplateParameters;
+ int m = types == null ? 0 : types.Count;
+ target.Write((byte)(method.CallingConvention | CallingConventionFlags.Generic));
+ Ir2md.WriteCompressedInt(target, m);
+ }
+ else
+ target.Write((byte)method.CallingConvention);
+ }
+ else
+ target.Write((byte)method.CallingConvention);
+ ParameterList pars = method.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Ir2md.WriteCompressedInt(target, n);
+
+ TypeNode returnType = method.ReturnType;
+#if ExtendedRuntime
+ if (method.HasOutOfBandContract || this.AttributesContains(method.ReturnAttributes, SystemTypes.NotNullAttribute)) {
+ returnType = TypeNode.DeepStripModifiers(returnType, (method.Template != null) ? method.Template.ReturnType : null, SystemTypes.NonNullType, SystemTypes.NullableType);
+ // returnType = TypeNode.DeepStripModifier(returnType, SystemTypes.NullableType, (method.Template != null) ? returnType.GetTemplateInstance(returnType, returnType.TemplateArguments) : null);
+ }
+#endif
+ if (returnType == null) returnType = SystemTypes.Object;
+ this.WriteTypeSignature(target, returnType, true);
+ for (int i = 0; i < n; i++)
+ {
+ Parameter p = pars[i];
+ if (p == null) continue;
+ TypeNode parameterType = p.Type;
+#if ExtendedRuntime
+ if (method.HasOutOfBandContract || this.AttributesContains(p.Attributes, SystemTypes.NotNullAttribute)) {
+ parameterType = TypeNode.DeepStripModifiers(parameterType, (method.Template != null) ? method.Template.Parameters[i].Type : null, SystemTypes.NonNullType, SystemTypes.NullableType);
+ //parameterType = TypeNode.DeepStripModifier(parameterType, SystemTypes.NullableType, (method.Template != null) ? parameterType.GetTemplateInstance(parameterType, parameterType.TemplateArguments) : null);
+ }
+#endif
+ if (parameterType == null) parameterType = SystemTypes.Object;
+ this.WriteTypeSignature(target, parameterType);
+ }
+ }
+ void WriteMethodSpecSignature(BinaryWriter/*!*/ target, Method/*!*/ method)
+ //^ requires this.UseGenerics && method.Template != null && method.Template.IsGeneric;
+ {
+ Debug.Assert(this.UseGenerics && method.Template != null && method.Template.IsGeneric);
+ target.Write((byte)0x0a);
+ TypeNodeList types = method.TemplateArguments;
+ int m = types == null ? 0 : types.Count;
+ Ir2md.WriteCompressedInt(target, m);
+ for (int i = 0; i < m; i++)
+ {
+ //^ assert types != null;
+ this.WriteTypeSignature(target, types[i]);
+ }
+ }
+ void WriteMethodSignature(BinaryWriter/*!*/ target, FunctionPointer/*!*/ fp)
+ {
+ target.Write((byte)fp.CallingConvention);
+ TypeNodeList parTypes = fp.ParameterTypes;
+ int n = parTypes == null ? 0 : parTypes.Count;
+ Ir2md.WriteCompressedInt(target, n);
+ if (fp.ReturnType != null)
+ this.WriteTypeSignature(target, fp.ReturnType);
+ int m = fp.VarArgStart;
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert parTypes != null;
+ if (i == m) target.Write((byte)0x41); //Sentinel
+ this.WriteTypeSignature(target, parTypes[i]);
+ }
+ }
+ void WritePropertySignature(BinaryWriter/*!*/ target, Property/*!*/ prop)
+ {
+ byte propHeader = (byte)0x8;
+ if (!prop.IsStatic) propHeader |= (byte)0x20; //bizarre redundant way to indicate that property accessors are instance methods
+ target.Write(propHeader);
+ ParameterList pars = prop.Parameters;
+ int n = pars == null ? 0 : pars.Count;
+ Ir2md.WriteCompressedInt(target, n);
+ if (prop.Type != null) this.WriteTypeSignature(target, prop.Type);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assert pars != null;
+ Parameter par = pars[i];
+ if (par == null || par.Type == null) continue;
+ this.WriteTypeSignature(target, par.Type);
+ }
+ }
+ void WriteSerializedTypeName(BinaryWriter target, TypeNode type)
+ {
+ if (target == null || type == null) return;
+ target.Write(this.GetSerializedTypeName(type), false);
+ }
+ string GetSerializedTypeName(TypeNode/*!*/ type)
+ {
+ bool isAssemblyQualified = true;
+ return this.GetSerializedTypeName(type, ref isAssemblyQualified);
+ }
+ string GetSerializedTypeName(TypeNode/*!*/ type, ref bool isAssemblyQualified)
+ {
+ if (type == null) return null;
+ this.VisitReferencedType(type);
+ StringBuilder sb = new StringBuilder();
+ TypeModifier tMod = type as TypeModifier;
+ if (tMod != null)
+ {
+ sb.Append(this.GetTypeDefOrRefOrSpecEncoded(type));
+ sb.Append('!');
+ return sb.ToString();
+ }
+ ArrayType arrType = type as ArrayType;
+ if (arrType != null)
+ {
+ type = arrType.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, arrType.ElementType, ref isAssemQual);
+ if (arrType.IsSzArray())
+ sb.Append("[]");
+ else
+ {
+ sb.Append('[');
+ if (arrType.Rank == 1) sb.Append('*');
+ for (int i = 1; i < arrType.Rank; i++) sb.Append(',');
+ sb.Append(']');
+ }
+ goto done;
+ }
+ Pointer pointer = type as Pointer;
+ if (pointer != null)
+ {
+ type = pointer.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, pointer.ElementType, ref isAssemQual);
+ sb.Append('*');
+ goto done;
+ }
+ Reference reference = type as Reference;
+ if (reference != null)
+ {
+ type = reference.ElementType;
+ bool isAssemQual = false;
+ this.AppendSerializedTypeName(sb, reference.ElementType, ref isAssemQual);
+ sb.Append('&');
+ goto done;
+ }
+ if (type.Template == null)
+ sb.Append(type.FullName);
+ else
+ {
+ sb.Append(type.Template.FullName);
+ sb.Append('[');
+ for (int i = 0, n = type.TemplateArguments == null ? 0 : type.TemplateArguments.Count; i < n; i++)
+ {
+ //^ assert type.TemplateArguments != null;
+ bool isAssemQual = true;
+ this.AppendSerializedTypeName(sb, type.TemplateArguments[i], ref isAssemQual);
+ if (i < n - 1) sb.Append(',');
+ }
+ sb.Append(']');
+ }
+ done:
+ if (isAssemblyQualified)
+ this.AppendAssemblyQualifierIfNecessary(sb, type, out isAssemblyQualified);
+ return sb.ToString();
+ }
+ void AppendAssemblyQualifierIfNecessary(StringBuilder/*!*/ sb, TypeNode type, out bool isAssemQualified)
+ {
+ isAssemQualified = false;
+ if (type == null) return;
+ AssemblyNode referencedAssembly = type.DeclaringModule as AssemblyNode;
+ if (referencedAssembly != null && referencedAssembly != this.module /*&& referencedAssembly != CoreSystemTypes.SystemAssembly*/)
+ {
+ sb.Append(", ");
+ sb.Append(referencedAssembly.StrongName);
+ isAssemQualified = true;
+ }
+ }
+ void AppendSerializedTypeName(StringBuilder/*!*/ sb, TypeNode type, ref bool isAssemQualified)
+ {
+ if (type == null) return;
+ string argTypeName = this.GetSerializedTypeName(type, ref isAssemQualified);
+ if (isAssemQualified) sb.Append('[');
+ sb.Append(argTypeName);
+ if (isAssemQualified) sb.Append(']');
+ }
+ void WriteTypeDefOrRefEncoded(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ if (!type.IsGeneric && this.IsStructural(type) && !(type is ITypeParameter))
+ this.WriteTypeSpecEncoded(target, type);
+ else if (type.DeclaringModule == this.module)
+ this.WriteTypeDefEncoded(target, type);
+ else if (type.DeclaringModule != null)
+ this.WriteTypeRefEncoded(target, type);
+ else
+ Debug.Assert(false);
+ }
+ void WriteTypeDefEncoded(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ int tok = this.GetTypeDefIndex(type);
+ Ir2md.WriteCompressedInt(target, (tok << 2));
+ }
+ void WriteTypeRefEncoded(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ int tok = this.GetTypeRefIndex(type);
+ Ir2md.WriteCompressedInt(target, (tok << 2) | 1);
+ }
+ void WriteTypeSpecEncoded(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ int tok = this.GetTypeSpecIndex(type);
+ Ir2md.WriteCompressedInt(target, (tok << 2) | 2);
+ }
+ void WriteTypeSignature(BinaryWriter/*!*/ target, TypeNode/*!*/ type)
+ {
+ this.WriteTypeSignature(target, type, false);
+ }
+ void WriteTypeSignature(BinaryWriter/*!*/ target, TypeNode/*!*/ type, bool instantiateGenericTypes)
+ {
+ if (type == null) return;
+ TypeNode t = this.WriteCustomModifiers(target, type);
+ if (this.UseGenerics)
+ {
+ if (t.Template != null && t.Template.IsGeneric && t.TemplateParameters == null)
+ {
+ target.Write((byte)0x15);
+ TypeNode template = t.Template;
+ while (template.Template != null) template = template.Template;
+ this.WriteTypeSignature(target, template);
+ TypeNodeList templArgs = t.ConsolidatedTemplateArguments;
+ int n = templArgs == null ? 0 : templArgs.Count;
+ Ir2md.WriteCompressedInt(target, n);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assume templArgs != null;
+ TypeNode targ = templArgs[i];
+ if (targ == null) continue;
+ this.WriteTypeSignature(target, targ);
+ }
+ return;
+ }
+ else if (t.IsGeneric && instantiateGenericTypes)
+ {
+ while (t.Template != null) t = t.Template;
+ target.Write((byte)0x15);
+ this.WriteTypeSignature(target, t);
+ TypeNodeList templPars = t.ConsolidatedTemplateParameters;
+ int n = templPars == null ? 0 : templPars.Count;
+ Ir2md.WriteCompressedInt(target, n);
+ for (int i = 0; i < n; i++)
+ {
+ //^ assume templPars != null;
+ TypeNode tp = templPars[i];
+ if (tp == null) continue;
+ this.WriteTypeSignature(target, tp);
+ }
+ return;
+ }
+ if (t is ITypeParameter)
+ {
+ object num = this.typeParameterNumber[t.UniqueKey];
+ if (num is int)
+ {
+ int number = (int)num;
+ if (number < 0)
+ {
+ target.Write((byte)0x1e); number = -number;
+ }
+ else
+ target.Write((byte)0x13);
+ Ir2md.WriteCompressedInt(target, number - 1);
+ return;
+ }
+ }
+ }
+ target.Write((byte)t.typeCode);
+ switch (t.typeCode)
+ {
+ case ElementType.Pointer: this.WriteTypeSignature(target, ((Pointer)t).ElementType); break;
+ case ElementType.Reference: this.WriteTypeSignature(target, ((Reference)t).ElementType); break;
+ case ElementType.ValueType:
+ case ElementType.Class: this.WriteTypeDefOrRefEncoded(target, t); break;
+ case ElementType.Array: this.WriteTypeSignature(target, ((ArrayType)t).ElementType); Ir2md.WriteArrayShape(target, (ArrayType)t); break;
+ case ElementType.FunctionPointer: this.WriteMethodSignature(target, (FunctionPointer)t); break;
+ case ElementType.SzArray: this.WriteTypeSignature(target, ((ArrayType)t).ElementType); break;
+ }
+ }
+
+#if !ROTOR
+ void IMetaDataEmit.SetModuleProps(string szName)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.Save(string szFile, uint dwSaveFlags)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SaveToStream(void* pIStream, uint dwSaveFlags)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataEmit.GetSaveSize(uint fSave)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineTypeDef(char* szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineNestedType(char* szTypeDef, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements, uint tdEncloser)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetHandler([MarshalAs(UnmanagedType.IUnknown), In]object pUnk)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineMethod(uint td, char* zName, uint dwMethodFlags, byte* pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DefineMethodImpl(uint td, uint tkBody, uint tkDecl)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineTypeRefByName(uint tkResolutionScope, char* szName)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineImportType(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue, IMetaDataImport pImport,
+ uint tdImport, IntPtr pAssemEmit)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineMemberRef(uint tkImport, string szName, byte* pvSigBlob, uint cbSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineImportMember(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue,
+ IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineEvent(uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint* rmdOtherMethods)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetClassLayout(uint td, uint dwPackSize, COR_FIELD_OFFSET* rFieldOffsets, uint ulClassSize)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DeleteClassLayout(uint td)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetFieldMarshal(uint tk, byte* pvNativeType, uint cbNativeType)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DeleteFieldMarshal(uint tk)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefinePermissionSet(uint tk, uint dwAction, void* pvPermission, uint cbPermission)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetRVA(uint md, uint ulRVA)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.GetTokenFromSig(byte* pvSig, uint cbSig)
+ {
+ BinaryWriter sig = new BinaryWriter(new MemoryStream());
+ for (int i = 0; i < cbSig; i++) sig.Write(*(pvSig + i));
+ return (uint)(0x11000000 | this.GetStandAloneSignatureIndex(sig));
+ }
+ uint IMetaDataEmit.DefineModuleRef(string szName)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetParent(uint mr, uint tk)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.GetTokenFromTypeSpec(byte* pvSig, uint cbSig)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SaveToMemory(void* pbData, uint cbData)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataEmit.DefineUserString(string szString, uint cchString)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DeleteToken(uint tkObj)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetMethodProps(uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetTypeDefProps(uint td, uint dwTypeDefFlags, uint tkExtends, uint* rtkImplements)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetEventProps(uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, uint* rmdOtherMethods)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.SetPermissionSetProps(uint tk, uint dwAction, void* pvPermission, uint cbPermission)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DefinePinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetPinvokeMap(uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.DeletePinvokeMap(uint tk)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineCustomAttribute(uint tkObj, uint tkType, void* pCustomAttribute, uint cbCustomAttribute)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetCustomAttributeValue(uint pcv, void* pCustomAttribute, uint cbCustomAttribute)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineField(uint td, string szName, uint dwFieldFlags, byte* pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag,
+ void* pValue, uint cchValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineProperty(uint td, string szProperty, uint dwPropFlags, byte* pvSig, uint cbSig, uint dwCPlusTypeFlag,
+ void* pValue, uint cchValue, uint mdSetter, uint mdGetter, uint* rmdOtherMethods)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.DefineParam(uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetFieldProps(uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetPropertyProps(uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue, uint mdSetter, uint mdGetter, uint* rmdOtherMethods)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe void IMetaDataEmit.SetParamProps(uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, void* pValue, uint cchValue)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataEmit.DefineSecurityAttributeSet(uint tkObj, IntPtr rSecAttrs, uint cSecAttrs)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.ApplyEditAndContinue([MarshalAs(UnmanagedType.IUnknown)]object pImport)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataEmit.TranslateSigWithScope(IntPtr pAssemImport, void* pbHashValue, uint cbHashValue,
+ IMetaDataImport import, byte* pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, byte* pvTranslatedSig, uint cbTranslatedSigMax)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetMethodImplFlags(uint md, uint dwImplFlags)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.SetFieldRVA(uint fd, uint ulRVA)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.Merge(IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs(UnmanagedType.IUnknown)]object pHandler)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataEmit.MergeEnd()
+ {
+ throw new NotImplementedException();
+ }
+ [PreserveSig]
+ void IMetaDataImport.CloseEnum(uint hEnum)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.CountEnum(uint hEnum)
+ {
+ throw new NotImplementedException();
+ }
+ void IMetaDataImport.ResetEnum(uint hEnum, uint ulPos)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumTypeDefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeDefs, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumInterfaceImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rImpls, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumTypeRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeRefs, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindTypeDefByName(string szTypeDef, uint tkEnclosingClass)
+ {
+ throw new NotImplementedException();
+ }
+ Guid IMetaDataImport.GetScopeProps(StringBuilder szName, uint cchName, out uint pchName)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetModuleFromScope()
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetTypeDefProps(uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags)
+ {
+ pchTypeDef = 0;
+ if (td == 0) return 0;
+ TypeNode t = null;
+ if ((td & 0xFF000000) == 0x1B000000)
+ {
+ t = this.typeSpecEntries[(int)(td & 0xFFFFFF) - 1];
+ if (t.Template != null) t = t.Template;
+ }
+ else
+ t = this.typeDefEntries[(int)(td & 0xFFFFFF) - 1];
+ if (t == null || t.Name == null) return 0;
+ string tName = t.Name.ToString();
+ if (tName == null) return 0;
+ pchTypeDef = (uint)tName.Length;
+ if (pchTypeDef >= cchTypeDef) pchTypeDef = cchTypeDef - 1;
+ char* pTypeDef = (char*)szTypeDef.ToPointer();
+ for (int i = 0; i < pchTypeDef; i++) *(pTypeDef + i) = tName[i];
+ *(pTypeDef + pchTypeDef) = (char)0;
+ uint* pFlags = (uint*)pdwTypeDefFlags.ToPointer();
+ *(pFlags) = (uint)t.Flags;
+ TypeNode bt = t.BaseType;
+ if (bt == null) return 0;
+ return (uint)this.GetTypeToken(bt);
+ }
+ uint IMetaDataImport.GetInterfaceImplProps(uint iiImpl, out uint pClass)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetTypeRefProps(uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.ResolveTypeRef(uint tr, [In] ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out object ppIScope)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMembers(ref uint phEnum, uint cl, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMembers, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMembersWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMembers, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.EnumMethods(ref uint phEnum, uint cl, uint* rMethods, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMethodsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethods, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.EnumFields(ref uint phEnum, uint cl, uint* rFields, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumFieldsWithName(ref uint phEnum, uint cl, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rFields, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumParams(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rParams, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMemberRefs(ref uint phEnum, uint tkParent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rMemberRefs, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMethodImpls(ref uint phEnum, uint td, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodBody,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rMethodDecl, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumPermissionSets(ref uint phEnum, uint tk, uint dwActions, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rPermission,
+ uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindMember(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindMethod(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindField(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindMemberRef(uint td, string szName, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] pvSigBlob, uint cbSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetMethodProps(uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr,
+ IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA)
+ {
+ Method m = null;
+ if ((mb & 0xFF000000) == 0x0A000000)
+ m = this.memberRefEntries[(int)(mb & 0xFFFFFF) - 1] as Method;
+ else
+ m = this.methodEntries[(int)(mb & 0xFFFFFF) - 1];
+ pchMethod = 0;
+ pClass = 0;
+ if (m == null || m.DeclaringType == null) return 0;
+ pClass = (uint)this.GetTypeDefToken(m.DeclaringType);
+ string methName = m.Name == null ? null : m.Name.ToString();
+ if (methName == null) return 0;
+ pchMethod = (uint)methName.Length;
+ char* pMethName = (char*)szMethod.ToPointer();
+ for (int i = 0; i < pchMethod; i++) *(pMethName + i) = methName[i];
+ *(pMethName + pchMethod) = (char)0;
+ return 0;
+ }
+ unsafe uint IMetaDataImport.GetMemberRefProps(uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out byte* ppvSigBlob)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.EnumProperties(ref uint phEnum, uint td, uint* rProperties, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.EnumEvents(ref uint phEnum, uint td, uint* rEvents, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetEventProps(uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags,
+ out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 11)] uint[] rmdOtherMethod, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumMethodSemantics(ref uint phEnum, uint mb, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] rEventProp, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetMethodSemantics(uint mb, uint tkEventProp)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetClassLayout(uint td, out uint pdwPackSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] COR_FIELD_OFFSET[] rFieldOffset, uint cMax, out uint pcFieldOffset)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetFieldMarshal(uint tk, out byte* ppvNativeType)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetRVA(uint tk, out uint pulCodeRVA)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetPermissionSetProps(uint pm, out uint pdwAction, out void* ppvPermission)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetSigFromToken(uint mdSig, out byte* ppvSig)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetModuleRefProps(uint mur, StringBuilder szName, uint cchName)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumModuleRefs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rModuleRefs, uint cmax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetTypeSpecFromToken(uint typespec, out byte* ppvSig)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetNameFromToken(uint tk)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumUnresolvedMethods(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rMethods, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetUserString(uint stk, StringBuilder szString, uint cchString)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetPinvokeMap(uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumSignatures(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rSignatures, uint cmax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumTypeSpecs(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rTypeSpecs, uint cmax)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumUserStrings(ref uint phEnum, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] rStrings, uint cmax)
+ {
+ throw new NotImplementedException();
+ }
+ [PreserveSig]
+ int IMetaDataImport.GetParamForMethodIndex(uint md, uint ulParamSeq, out uint pParam)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.EnumCustomAttributes(ref uint phEnum, uint tk, uint tkType, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] rCustomAttributes, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetCustomAttributeProps(uint cv, out uint ptkObj, out uint ptkType, out void* ppBlob)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.FindTypeRef(uint tkResolutionScope, string szName)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetMemberProps(uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr,
+ out byte* ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out void* ppValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetFieldProps(uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr,
+ out byte* ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out void* ppValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetPropertyProps(uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags,
+ out byte* ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out void* ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter,
+ out uint pmdGetter, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 14)] uint[] rmdOtherMethod, uint cMax)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetParamProps(uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName,
+ out uint pdwAttr, out uint pdwCPlusTypeFlag, out void* ppValue)
+ {
+ throw new NotImplementedException();
+ }
+ unsafe uint IMetaDataImport.GetCustomAttributeByName(uint tkObj, string szName, out void* ppData)
+ {
+ throw new NotImplementedException();
+ }
+ [PreserveSig]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ bool IMetaDataImport.IsValidToken(uint tk)
+ {
+ throw new NotImplementedException();
+ }
+ uint IMetaDataImport.GetNestedClassProps(uint tdNestedClass)
+ {
+ TypeNode t = null;
+ if ((tdNestedClass & 0xFF000000) == 0x1B000000)
+ t = this.typeSpecEntries[(int)(tdNestedClass & 0xFFFFFF) - 1];
+ else
+ t = this.typeDefEntries[(int)(tdNestedClass & 0xFFFFFF) - 1];
+ if (t == null || t.DeclaringType == null) return 0;
+ return (uint)this.GetTypeToken(t.DeclaringType);
+ }
+ unsafe uint IMetaDataImport.GetNativeCallConvFromSig(void* pvSig, uint cbSig)
+ {
+ throw new NotImplementedException();
+ }
+ int IMetaDataImport.IsGlobal(uint pd)
+ {
+ throw new NotImplementedException();
+ }
+#endif
+ }
+#if WHIDBEYwithGenericsAndIEqualityComparer
+ public class ByteArrayKeyComparer : IEqualityComparer, IComparer
+ {
+ int IComparer.Compare(object x, object y)
+ {
+ if (x == null || y == null) throw new ArgumentNullException();
+ byte[] xa = (byte[])x;
+ byte[] ya = (byte[])y;
+ int n = xa.Length;
+ int result = n - ya.Length;
+ if (result != 0) return result;
+ for (int i = 0; i < n; i++)
+ {
+ result = xa[i] - ya[i];
+ if (result != 0) return result;
+ }
+ return 0;
+ }
+ bool IEqualityComparer.Equals(object x, object y)
+ {
+ if (x == null || y == null) return x == y;
+ return ((IComparer)this).Compare(x, y) == 0;
+ }
+ int IEqualityComparer.GetHashCode(object/*!*/ x)
+ {
+ Debug.Assert(x != null);
+ byte[] xa = (byte[])x;
+ int hcode = 1;
+ for (int i = 0, n = xa.Length; i < n; i++)
+ hcode = hcode * 17 + xa[i];
+ return hcode;
+ }
+ }
+#elif WHIDBEYwithGenerics
+ public class ByteArrayKeyComparer : IKeyComparer{
+ int IComparer.Compare(object x, object y) {
+ if (x == null || y == null) throw new ArgumentNullException();
+ byte[] xa = (byte[])x;
+ byte[] ya = (byte[])y;
+ int n = xa.Length;
+ int result = n - ya.Length;
+ if (result != 0) return result;
+ for (int i = 0; i < n; i++){
+ result = xa[i] - ya[i];
+ if (result != 0) return result;
+ }
+ return 0;
+ }
+ bool IKeyComparer.Equals(object x, object y){
+ return ((IKeyComparer)this).Compare(x, y) == 0;
+ }
+ int IHashCodeProvider.GetHashCode(object x) {
+ Debug.Assert(x != null);
+ byte[] xa = (byte[])x;
+ int hcode = 1;
+ for (int i = 0, n = xa.Length; i < n; i++)
+ hcode = hcode * 17 + xa[i];
+ return hcode;
+ }
+ }
+#else
+ public class ByteArrayComparer : IComparer{
+ int IComparer.Compare(object x, object y){
+ if (x == null || y == null) throw new ArgumentNullException();
+ byte[] xa = (byte[])x;
+ byte[] ya = (byte[])y;
+ int n = xa.Length;
+ int result = n - ya.Length;
+ if (result != 0) return result;
+ for (int i = 0; i < n; i++){
+ result = xa[i] - ya[i];
+ if (result != 0) return result;
+ }
+ return 0;
+ }
+ }
+ public class ByteArrayHasher : IHashCodeProvider{
+ int IHashCodeProvider.GetHashCode(object x){
+ Debug.Assert(x != null);
+ byte[] xa = (byte[])x;
+ int hcode = 1;
+ for (int i = 0, n = xa.Length; i < n; i++)
+ hcode = hcode*17 + xa[i];
+ return hcode;
+ }
+ }
+#endif
+ internal class Fixup
+ {
+ internal int fixupLocation;
+ internal int addressOfNextInstruction;
+ internal bool shortOffset;
+ internal Fixup nextFixUp;
+ }
+ internal class MethodInfo
+ {
+ internal TrivialHashtable/*!*/ fixupIndex = new TrivialHashtable();
+ internal int localVarSigTok;
+ internal BinaryWriter/*!*/ localVarSignature;
+ internal TrivialHashtable/*!*/ localVarIndex;
+#if !ROTOR
+ internal NodeList/*!*/ statementNodes;
+ internal LocalList/*!*/ debugLocals;
+ internal Int32List/*!*/ signatureLengths;
+ internal Int32List/*!*/ signatureOffsets;
+ internal Int32List/*!*/ statementOffsets;
+#endif
+
+ public MethodInfo()
+ {
+ //^ base();
+ }
+ }
+ public class KeyFileNotFoundException : System.ArgumentException { }
+ public class AssemblyCouldNotBeSignedException : System.ApplicationException { }
+ public class DebugSymbolsCouldNotBeWrittenException : System.ApplicationException { }
+ internal class Writer
+ {
+ private Writer() { }
+ internal static void WritePE(System.CodeDom.Compiler.CompilerParameters/*!*/ compilerParameters, Module/*!*/ module)
+ //^ requires module.Location != null;
+ {
+ if (compilerParameters == null) { Debug.Assert(false); return; }
+ CompilerOptions options = compilerParameters as CompilerOptions;
+ if (options == null)
+ Writer.WritePE(module.Location, compilerParameters.IncludeDebugInformation, module, false, null, null);
+ else
+ {
+ if (options.FileAlignment > 512) module.FileAlignment = options.FileAlignment;
+ Writer.WritePE(module.Location, options.IncludeDebugInformation, module, options.DelaySign, options.AssemblyKeyFile, options.AssemblyKeyName);
+ }
+ }
+ internal static void WritePE(string/*!*/ location, bool writeDebugSymbols, Module/*!*/ module)
+ {
+ Writer.WritePE(location, writeDebugSymbols, module, false, null, null);
+ }
+ private static void WritePE(string/*!*/ location, bool writeDebugSymbols, Module/*!*/ module, bool delaySign, string keyFileName, string keyName)
+ {
+ AssemblyNode assem = module as AssemblyNode;
+ location = Path.GetFullPath(location);
+ module.Directory = Path.GetDirectoryName(location);
+ bool keyFileNameDoesNotExist = false;
+ if (assem != null)
+ {
+ assem.KeyContainerName = keyName;
+ if (keyFileName != null && keyFileName.Length > 0)
+ {
+ if (!File.Exists(keyFileName)) keyFileName = Path.Combine(module.Directory, keyFileName);
+ if (File.Exists(keyFileName))
+ {
+ using (FileStream keyFile = File.OpenRead(keyFileName))
+ {
+ long size = keyFile.Length;
+ if (size > int.MaxValue) throw new System.IO.FileLoadException();
+ int n = (int)size;
+ byte[] key = new byte[n];
+ keyFile.Read(key, 0, n);
+ assem.KeyBlob = key;
+ }
+ }
+ else
+ keyFileNameDoesNotExist = true;
+ }
+ assem.PublicKeyOrToken = Writer.GetPublicKey(assem);
+ }
+ using (FileStream exeFstream = new FileStream(location, FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ string debugSymbolsLocation = writeDebugSymbols ? Path.ChangeExtension(location, "pdb") : null;
+ if (debugSymbolsLocation != null && File.Exists(debugSymbolsLocation))
+ File.Delete(debugSymbolsLocation);
+ MemoryStream exeMstream = new MemoryStream();
+ Ir2md.WritePE(module, debugSymbolsLocation, new BinaryWriter(exeMstream));
+ exeMstream.WriteTo(exeFstream);
+ }
+ if (keyFileNameDoesNotExist) throw new KeyFileNotFoundException();
+ if (delaySign || assem == null) return;
+ if (assem.KeyBlob != null || (assem.KeyContainerName != null && assem.KeyContainerName.Length > 0))
+ {
+ try
+ {
+ if (!Writer.StrongNameSignatureGeneration(location, keyName, assem.KeyBlob, assem.KeyBlob == null ? 0 : assem.KeyBlob.Length, IntPtr.Zero, IntPtr.Zero))
+ throw new AssemblyCouldNotBeSignedException();
+ }
+ catch
+ {
+ if (!Writer.MscorsnStrongNameSignatureGeneration(location, keyName, assem.KeyBlob, assem.KeyBlob == null ? 0 : assem.KeyBlob.Length, IntPtr.Zero, IntPtr.Zero))
+ throw new AssemblyCouldNotBeSignedException();
+ }
+ }
+ }
+ [DllImport("mscoree.dll", EntryPoint = "StrongNameSignatureGeneration",
+ SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true,
+ CallingConvention = CallingConvention.StdCall)]
+ private static extern bool StrongNameSignatureGeneration(
+ string wszFilePath, // [in] valid path to the PE file for the assembly
+ string wszKeyContainer, // [in] desired key container name
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
+ byte[] pbKeyBlob, // [in] public/private key blob (optional)
+ int cbKeyBlob,
+ IntPtr ppbSignatureBlob, // [out] signature blob
+ IntPtr pcbSignatureBlob);
+ [DllImport("mscorsn.dll", EntryPoint = "StrongNameSignatureGeneration",
+ SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true,
+ CallingConvention = CallingConvention.StdCall)]
+ private static extern bool MscorsnStrongNameSignatureGeneration(
+ string wszFilePath, // [in] valid path to the PE file for the assembly
+ string wszKeyContainer, // [in] desired key container name
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)]
+ byte[] pbKeyBlob, // [in] public/private key blob (optional)
+ int cbKeyBlob,
+ IntPtr ppbSignatureBlob, // [out] signature blob
+ IntPtr pcbSignatureBlob);
+ private unsafe static byte[] GetPublicKey(AssemblyNode/*!*/ assem)
+ {
+ Debug.Assert(assem != null);
+ IntPtr publicKey = IntPtr.Zero;
+ int size;
+ try
+ {
+ if (assem.KeyBlob != null)
+ {
+ Writer.StrongNameGetPublicKey(null, assem.KeyBlob, assem.KeyBlob.Length, out publicKey, out size);
+ if (publicKey == IntPtr.Zero) return assem.KeyBlob;
+ }
+ else if (assem.KeyContainerName != null)
+ {
+ Writer.StrongNameGetPublicKey(assem.KeyContainerName, null, 0, out publicKey, out size);
+ if (publicKey == IntPtr.Zero) return null;
+ }
+ else
+ return assem.PublicKeyOrToken;
+ byte[] result = new byte[size];
+ byte* ptr = (byte*)publicKey;
+ for (int i = 0; i < size; i++) result[i] = *ptr++;
+ return result;
+ }
+ catch { }
+ {
+ if (assem.KeyBlob != null)
+ {
+ Writer.MscorsnStrongNameGetPublicKeyUsing(null, assem.KeyBlob, assem.KeyBlob.Length, out publicKey, out size);
+ if (publicKey == IntPtr.Zero) return assem.KeyBlob;
+ }
+ else if (assem.KeyContainerName != null)
+ {
+ Writer.MscorsnStrongNameGetPublicKeyUsing(assem.KeyContainerName, null, 0, out publicKey, out size);
+ if (publicKey == IntPtr.Zero) return null;
+ }
+ else
+ return assem.PublicKeyOrToken;
+ byte[] result = new byte[size];
+ byte* ptr = (byte*)publicKey;
+ for (int i = 0; i < size; i++) result[i] = *ptr++;
+ return result;
+ }
+ }
+ [DllImport("mscoree.dll", EntryPoint = "StrongNameGetPublicKey",
+ SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true,
+ CallingConvention = CallingConvention.StdCall)]
+ private static extern bool StrongNameGetPublicKey(
+ string wszKeyContainer, // [in] desired key container name
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
+ byte[] pbKeyBlob, // [in] public/private key blob (optional)
+ int cbKeyBlob,
+ [Out] out IntPtr ppbPublicKeyBlob, // [out] public key blob
+ [Out] out int pcbPublicKeyBlob);
+ [DllImport("mscorsn.dll", EntryPoint = "StrongNameGetPublicKey",
+ SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true,
+ CallingConvention = CallingConvention.StdCall)]
+ private static extern bool MscorsnStrongNameGetPublicKeyUsing(
+ string wszKeyContainer, // [in] desired key container name
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)]
+ byte[] pbKeyBlob, // [in] public/private key blob (optional)
+ int cbKeyBlob,
+ [Out] out IntPtr ppbPublicKeyBlob, // [out] public key blob
+ [Out] out int pcbPublicKeyBlob);
+
+ internal static void WritePE(Stream/*!*/ executable, Stream debugSymbols, Module/*!*/ module)
+ {
+ MemoryStream mstream = new MemoryStream();
+ Ir2md.WritePE(module, null, new BinaryWriter(mstream)); //TODO: need to write the PDB symbols to the stream
+ mstream.WriteTo(executable);
+ }
+ internal static void WritePE(out byte[] executable, Module/*!*/ module)
+ {
+ MemoryStream mstream = new MemoryStream();
+ Ir2md.WritePE(module, null, new BinaryWriter(mstream));
+ executable = mstream.ToArray();
+ }
+ internal static void WritePE(out byte[] executable, out byte[] debugSymbols, Module/*!*/ module)
+ {
+ MemoryStream mstream = new MemoryStream();
+ Ir2md.WritePE(module, null, new BinaryWriter(mstream));
+ executable = mstream.ToArray();
+ debugSymbols = null;
+ }
+ internal unsafe static void AddWin32Icon(Module/*!*/ module, string win32IconFilePath)
+ {
+ if (module == null || win32IconFilePath == null) { Debug.Assert(false); return; }
+ using (System.IO.FileStream resStream = File.OpenRead(win32IconFilePath))
+ {
+ Writer.AddWin32Icon(module, resStream);
+ }
+ }
+ internal unsafe static void AddWin32Icon(Module/*!*/ module, Stream win32IconStream)
+ {
+ if (module == null || win32IconStream == null) { Debug.Assert(false); return; }
+ long size = win32IconStream.Length;
+ if (size > int.MaxValue) throw new System.IO.FileLoadException();
+ int n = (int)size;
+ byte[] buffer = new byte[n];
+ win32IconStream.Read(buffer, 0, n);
+ byte* pb = (byte*)Marshal.AllocHGlobal(n);
+ for (int i = 0; i < n; i++) pb[i] = buffer[i];
+ MemoryCursor cursor = new MemoryCursor(pb, n/*, module*/);
+ if (module.Win32Resources == null) module.Win32Resources = new Win32ResourceList();
+ int reserved = cursor.ReadUInt16();
+ if (reserved != 0) throw new NullReferenceException();
+ int resourceType = cursor.ReadUInt16();
+ if (resourceType != 1) throw new NullReferenceException();
+ int imageCount = cursor.ReadUInt16();
+ BinaryWriter indexHeap = new BinaryWriter(new MemoryStream());
+ indexHeap.Write((ushort)0); //Reserved
+ indexHeap.Write((ushort)1); //idType
+ indexHeap.Write((ushort)imageCount);
+ Win32Resource resource = new Win32Resource();
+ for (int i = 0; i < imageCount; i++)
+ {
+ resource = new Win32Resource();
+ resource.CodePage = 0;
+ resource.Id = module.Win32Resources.Count + 2;
+ resource.LanguageId = 0;
+ resource.Name = null;
+ resource.TypeId = 3;
+ resource.TypeName = null;
+ indexHeap.Write(cursor.ReadByte()); //width
+ indexHeap.Write(cursor.ReadByte()); //height
+ indexHeap.Write(cursor.ReadByte()); //color count
+ indexHeap.Write(cursor.ReadByte()); //reserved
+ indexHeap.Write(cursor.ReadUInt16()); //planes
+ indexHeap.Write(cursor.ReadUInt16()); //bit count
+ int len = cursor.ReadInt32();
+ int offset = cursor.ReadInt32();
+ indexHeap.Write((int)len);
+ indexHeap.Write((int)module.Win32Resources.Count + 2);
+ MemoryCursor c = new MemoryCursor(cursor);
+ c.Position = offset;
+ resource.Data = c.ReadBytes(len);
+ module.Win32Resources.Add(resource);
+ }
+ resource.CodePage = 0;
+ resource.Data = indexHeap.BaseStream.ToArray();
+ resource.Id = 0x7f00;
+ resource.LanguageId = 0;
+ resource.Name = null;
+ resource.TypeId = 0xe;
+ resource.TypeName = null;
+ module.Win32Resources.Add(resource);
+ }
+ internal unsafe static void AddWin32ResourceFileToModule(Module/*!*/ module, string/*!*/ win32ResourceFilePath)
+ {
+ if (module == null || win32ResourceFilePath == null) { Debug.Assert(false); return; }
+ using (System.IO.FileStream resStream = File.OpenRead(win32ResourceFilePath))
+ {
+ Writer.AddWin32ResourceFileToModule(module, resStream);
+ }
+ }
+ internal unsafe static void AddWin32ResourceFileToModule(Module/*!*/ module, Stream/*!*/ win32ResourceStream)
+ {
+ if (module == null || win32ResourceStream == null) { Debug.Assert(false); return; }
+ long size = win32ResourceStream.Length;
+ if (size > int.MaxValue) throw new System.IO.FileLoadException();
+ int n = (int)size;
+ byte[] buffer = new byte[n];
+ win32ResourceStream.Read(buffer, 0, n);
+ byte* pb = (byte*)Marshal.AllocHGlobal(n);
+ for (int i = 0; i < n; i++) pb[i] = buffer[i];
+ MemoryCursor cursor = new MemoryCursor(pb, n/*, module*/);
+ if (module.Win32Resources == null) module.Win32Resources = new Win32ResourceList();
+ while (cursor.Position < n)
+ {
+ Win32Resource resource = new Win32Resource();
+ resource.CodePage = 0; //Review: Should this be settable?
+ int dataSize = cursor.ReadInt32();
+ cursor.ReadUInt32(); //headerSize
+ if (cursor.Int16(0) == -1)
+ {
+ cursor.ReadInt16();
+ resource.TypeId = cursor.ReadUInt16();
+ resource.TypeName = null;
+ }
+ else
+ {
+ resource.TypeId = 0;
+ resource.TypeName = cursor.ReadUTF16();
+ }
+ if (cursor.Int16(0) == -1)
+ {
+ cursor.ReadInt16();
+ resource.Id = cursor.ReadUInt16();
+ resource.Name = null;
+ }
+ else
+ {
+ resource.Id = 0;
+ resource.Name = cursor.ReadUTF16();
+ }
+ cursor.ReadUInt32(); //dataVersion
+ cursor.ReadUInt16(); //memoryFlags
+ resource.LanguageId = cursor.ReadUInt16();
+ cursor.ReadUInt32(); //version
+ cursor.ReadUInt32(); //characteristics
+ resource.Data = cursor.ReadBytes(dataSize);
+ if (resource.Data != null)
+ module.Win32Resources.Add(resource);
+ }
+ }
+ internal static void AddWin32VersionInfo(Module/*!*/ module, CompilerOptions/*!*/ options)
+ {
+ if (module == null || options == null) { Debug.Assert(false); return; }
+ Win32Resource resource = new Win32Resource();
+ resource.CodePage = 0;
+ resource.Id = 1;
+ resource.LanguageId = 0;
+ resource.Name = null;
+ resource.TypeId = 0x10;
+ resource.TypeName = null;
+ resource.Data = Writer.FillInVsVersionStructure(module, options);
+ if (module.Win32Resources == null) module.Win32Resources = new Win32ResourceList();
+ module.Win32Resources.Add(resource);
+ }
+ private static byte[] FillInVsVersionStructure(Module/*!*/ module, CompilerOptions/*!*/ options)
+ {
+ AssemblyNode assembly = module as AssemblyNode;
+ BinaryWriter data = new BinaryWriter(new MemoryStream(), Encoding.Unicode);
+ data.Write((ushort)0); //Space for length
+ data.Write((ushort)0x34); //VS_FIXEDFILEINFO length
+ data.Write((ushort)0); //Type of data in version resource
+ data.Write("VS_VERSION_INFO", true);
+ data.Write((ushort)0); //Padding to 4 byte boundary
+ // VS_FIXEDFILEINFO starts here
+ data.Write((uint)0xFEEF04BD); //Signature
+ data.Write((uint)0x00010000); //Version of VS_FIXEDFILEINFO
+ Version fileVersion = Writer.ParseVersion(options.TargetInformation.Version, true);
+ if (fileVersion == null && assembly != null) fileVersion = assembly.Version;
+ if (fileVersion == null) fileVersion = new Version();
+ data.Write((ushort)fileVersion.Minor);
+ data.Write((ushort)fileVersion.Major);
+ data.Write((ushort)fileVersion.Revision);
+ data.Write((ushort)fileVersion.Build);
+ Version productVersion = Writer.ParseVersion(options.TargetInformation.ProductVersion, true);
+ if (productVersion == null) productVersion = fileVersion;
+ data.Write((ushort)productVersion.Minor);
+ data.Write((ushort)productVersion.Major);
+ data.Write((ushort)productVersion.Revision);
+ data.Write((ushort)productVersion.Build);
+ data.Write((uint)0x3f); //FileFlagsMask
+ data.Write((uint)0x0); //FileFlags
+ data.Write((uint)0x4); //OS: Win32 (After all, this is a Win32 resource.)
+ if (options.GenerateExecutable)
+ data.Write((uint)1); //App
+ else
+ data.Write((uint)2); //Dll
+ data.Write((uint)0); //File subtype
+ data.Write((ulong)0); //File Date
+ // VarFileInfo
+ data.Write((ushort)0x44); //Length of VarFileInfo
+ data.Write((ushort)0x0); //Length of value
+ data.Write((ushort)0x1); //type (text)
+ data.Write("VarFileInfo", true);
+ data.Write((ushort)0); //padding to 4 byte boundary
+ // Var
+ data.Write((ushort)0x24); //Length of Var
+ data.Write((ushort)0x04); //length of Value
+ data.Write((ushort)0); //Type (binary)
+ data.Write("Translation", true);
+ data.Write((uint)0); //Padding
+ data.Write((ushort)0x4b0); //Code Page for Unicode
+ // StringFileInfo
+ int positionOfInfoLength = data.BaseStream.Position;
+ data.Write((ushort)0); //length of rest of resource
+ data.Write((ushort)0); //Value length, always 0
+ data.Write((ushort)1); //Type (text)
+ data.Write("StringFileInfo", true);
+ // StringInfo
+ int stringInfoLengthPos = data.BaseStream.Position;
+ data.Write((ushort)0); //Space for length
+ data.Write((ushort)0); //Value length, always 0
+ data.Write((ushort)1); //Type (text)
+ data.Write("000004b0", true); //Code page for Unicode
+ Writer.WriteVersionString(data, options.TargetInformation.Description, "Comments");
+ Writer.WriteVersionString(data, options.TargetInformation.Company, "CompanyName");
+ Writer.WriteVersionString(data, options.TargetInformation.Title, "FileDescription");
+ Writer.WriteVersionString(data, Writer.ConvertToString(fileVersion), "FileVersion");
+ string fileName = module.Name + (options.GenerateExecutable ? ".exe" : ".dll");
+ Writer.WriteVersionString(data, fileName, "InternalName");
+ Writer.WriteVersionString(data, options.TargetInformation.Copyright, "LegalCopyright");
+ Writer.WriteVersionString(data, options.TargetInformation.Trademark, "LegalTrademarks");
+ Writer.WriteVersionString(data, fileName, "OriginalFilename");
+ Writer.WriteVersionString(data, options.TargetInformation.Product, "ProductName");
+ Writer.WriteVersionString(data, Writer.ConvertToString(productVersion), "ProductVersion");
+ if (assembly != null)
+ Writer.WriteVersionString(data, assembly.Version == null ? "" : assembly.Version.ToString(), "Assembly Version");
+ int len = data.BaseStream.Position;
+ data.BaseStream.Position = stringInfoLengthPos;
+ data.Write((ushort)(len - stringInfoLengthPos));
+ data.BaseStream.Position = 0;
+ data.Write((ushort)len);
+ data.BaseStream.Position = positionOfInfoLength;
+ data.Write((ushort)len - positionOfInfoLength);
+ return data.BaseStream.ToArray();
+ }
+ private static void WriteVersionString(BinaryWriter/*!*/ data, string value, string/*!*/ key)
+ {
+ if (value == null) return;
+ int totalLength = 6;
+ totalLength += key.Length * 2;
+ totalLength += 4 - (totalLength % 4);
+ totalLength += value.Length * 2;
+ totalLength += 4 - (totalLength % 4);
+ data.Write((ushort)totalLength);
+ data.Write((ushort)(value.Length + 1));
+ data.Write((ushort)1); //Type (text)
+ data.Write(key, true);
+ if (data.BaseStream.Position % 4 != 0) data.Write((char)0);
+ data.Write(value, true);
+ if (data.BaseStream.Position % 4 != 0) data.Write((char)0);
+ }
+ private static string/*!*/ ConvertToString(Version/*!*/ version)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append(version.Major.ToString());
+ if (version.Minor != 0 || version.Build != 0 || version.Revision != 0)
+ {
+ sb.Append('.');
+ sb.Append(version.Minor.ToString());
+ }
+ if (version.Build != 0 || version.Revision != 0)
+ {
+ sb.Append('.');
+ sb.Append(version.Build.ToString());
+ }
+ if (version.Revision != 0)
+ {
+ sb.Append('.');
+ sb.Append(version.Revision.ToString());
+ }
+ return sb.ToString();
+ }
+ private static Version ParseVersion(string vString, bool allowWildcards)
+ {
+ if (vString == null) return null;
+ ushort major = 1;
+ ushort minor = 0;
+ ushort build = 0;
+ ushort revision = 0;
+ try
+ {
+ int n = vString.Length;
+ int i = vString.IndexOf('.', 0);
+ if (i < 0) throw new FormatException();
+ major = UInt16.Parse(vString.Substring(0, i), CultureInfo.InvariantCulture);
+ int j = vString.IndexOf('.', i + 1);
+ if (j < i + 1)
+ minor = UInt16.Parse(vString.Substring(i + 1, n - i - 1), CultureInfo.InvariantCulture);
+ else
+ {
+ minor = UInt16.Parse(vString.Substring(i + 1, j - i - 1), CultureInfo.InvariantCulture);
+ if (vString[j + 1] == '*' && allowWildcards)
+ {
+ if (j + 1 < n - 1) return null;
+ build = Writer.DaysSince2000();
+ revision = Writer.SecondsSinceMidnight();
+ }
+ else
+ {
+ int k = vString.IndexOf('.', j + 1);
+ if (k < j + 1)
+ build = UInt16.Parse(vString.Substring(j + 1, n - j - 1), CultureInfo.InvariantCulture);
+ else
+ {
+ build = UInt16.Parse(vString.Substring(j + 1, k - j - 1), CultureInfo.InvariantCulture);
+ if (vString[k + 1] == '*' && allowWildcards)
+ {
+ if (j + 1 < n - 1) return null;
+ revision = Writer.SecondsSinceMidnight();
+ }
+ else
+ revision = UInt16.Parse(vString.Substring(k + 1, n - k - 1), CultureInfo.InvariantCulture);
+ }
+ }
+ }
+ }
+ catch (FormatException)
+ {
+ major = minor = build = revision = UInt16.MaxValue;
+ }
+ catch (OverflowException)
+ {
+ major = minor = build = revision = UInt16.MaxValue;
+ }
+ if (major == UInt16.MaxValue && minor == UInt16.MaxValue && build == UInt16.MaxValue && revision == UInt16.MaxValue)
+ {
+ return null;
+ }
+ return new Version(major, minor, build, revision);
+ }
+ private static ushort DaysSince2000()
+ {
+ return (ushort)(DateTime.Now - new DateTime(2000, 1, 1)).Days;
+ }
+ private static ushort SecondsSinceMidnight()
+ {
+ TimeSpan sinceMidnight = DateTime.Now - DateTime.Today;
+ return (ushort)((sinceMidnight.Hours * 60 * 60 + sinceMidnight.Minutes * 60 + sinceMidnight.Seconds) / 2);
+ }
+
+ }
+}
+#endif
diff --git a/tools/Sandcastle/ProductionTools/ChmBuilder.config b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.config
index 4382125..5c0b7b8 100644
--- a/tools/Sandcastle/ProductionTools/ChmBuilder.config
+++ b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.config
@@ -2,10 +2,23 @@
<configuration>
<languages>
<language id="1033" codepage="65001" name="0x409 English (United States)" />
+ <language id="1028" codepage="950" name="0x404 Chinese (Taiwan)" />
+ <language id="1029" codepage="1250" name="0x405 Czech" />
+ <language id="1038" codepage="1250" name="0x40e Hungarian" />
+ <language id="1041" codepage="932" name="0x411 Japanese" />
+ <language id="1042" codepage="949" name="0x412 Korean" />
+ <language id="1045" codepage="1250" name="0x415 Polish" />
+ <language id="1049" codepage="1251" name="0x419 Russian" />
+ <language id="1055" codepage="1254" name="0x41f Turkish" />
<language id="2052" codepage="936" name="0x804 Chinese (PRC)" />
</languages>
- <!-- {0}:projectName, {1}:defaultTopic, {2}:Language -->
+
+ <chmTitles>
+ <title projectName="Test">Chm Test build</title>
+ </chmTitles>
+
+ <!-- {0}:projectName, {1}:defaultTopic, {2}:Language, {3}:Title -->
<hhpTemplate>
<line>[OPTIONS]</line>
<!--
@@ -18,7 +31,7 @@
<line>Default Topic={1}</line>
<line>Full-text search=Yes</line>
<line>Language={2}</line>
- <line>Title={0}</line>
+ <line>Title={3}</line>
<line>[FILES]</line>
<line>icons\*.gif</line>
diff --git a/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.cs b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.cs
new file mode 100644
index 0000000..1e2aeb2
--- /dev/null
+++ b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.cs
@@ -0,0 +1,739 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.IO;
+using System.Reflection;
+using Microsoft.Ddue.Tools.CommandLine;
+
+
+namespace Microsoft.Ddue.Tools
+{
+
+ /// <summary>
+ /// <language id="1033" codepage="65001" name="0x409 English (United States)" />
+ /// <language id="2052" codepage="936" name="0x804 Chinese (PRC)" />
+ /// </summary>
+ internal struct LangInfo
+ {
+ public int CodePage;
+ public int ID;
+ public string Name;
+ }
+
+ internal struct KKeywordInfo
+ {
+ public string File;
+ public string MainEntry;
+ public string SubEntry;
+ }
+
+ public class ChmBuilder
+ {
+
+ private ChmBuilderArgs _args;
+ private XPathDocument _config;
+ //private bool _metadata;
+
+ //defalut topic of chm: get this value when gerenating hhc, save to hhp
+ private string _defaultTopic = string.Empty;
+ private bool _hasToc;
+
+ private int _indentCount = 0;
+ //private string _htmlDirectory;
+ //private string _tocFile;
+ //private string _projectName;
+ //private string _outputDirectory;
+ private LangInfo _lang;
+
+ //store all "K" type Keywords
+ List < KKeywordInfo > kkwdTable = new List < KKeywordInfo >();
+
+ //store all titles from html files
+ Hashtable titleTable = new Hashtable();
+
+
+ public ChmBuilder(ChmBuilderArgs args)
+ {
+ this._args = args;
+ _args.htmlDirectory = StripEndBackSlash(Path.GetFullPath(_args.htmlDirectory));
+ if (String.IsNullOrEmpty(_args.tocFile))
+ _hasToc = false;
+ else
+ _hasToc = true;
+ _args.outputDirectory = StripEndBackSlash(Path.GetFullPath(_args.outputDirectory));
+ _config = new XPathDocument(args.configFile);
+ LoadLanginfo(_args.langid);
+ }
+ public static int Main(string[] args)
+ {
+ ConsoleApplication.WriteBanner();
+
+ OptionCollection options = new OptionCollection();
+ options.Add(new SwitchOption("?", "Show this help page."));
+ options.Add(new StringOption("html", "Specify a html directory.", "htmlDirectory"));
+ options.Add(new StringOption("project", "Specify a project name.", "projectName"));
+ options.Add(new StringOption("toc", "Specify a toc file.", "tocFile"));
+ options.Add(new StringOption("lcid", "Specify a language id.If unspecified, 1033 is used.", "languageId"));
+ options.Add(new StringOption("out", "Specify an output directory. If unspecified, Chm is used.", "outputDirectory"));
+ options.Add(new BooleanOption("metadata", "Specify whether output metadata or not. Default value is false."));
+ options.Add(new StringOption("config", "Specify a configuration file. If unspecified, ChmBuilder.config is used", "configFilePath"));
+
+ ParseArgumentsResult results = options.ParseArguments(args);
+ if (results.Options["?"].IsPresent)
+ {
+ Console.WriteLine("ChmBuilder /html: /project: /toc: /out: /metadata:");
+ options.WriteOptionSummary(Console.Out);
+ return (0);
+ }
+
+ ChmBuilderArgs cbArgs = new ChmBuilderArgs();
+
+ // check for invalid options
+ if (!results.Success)
+ {
+ results.WriteParseErrors(Console.Out);
+ return (1);
+ }
+
+ // check for missing or extra assembly directories
+ if (results.UnusedArguments.Count != 0)
+ {
+ Console.WriteLine("No non-option arguments are supported.");
+ return (1);
+ }
+
+ if (!results.Options["html"].IsPresent)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "You must specify a html directory.");
+ return (1);
+ }
+ cbArgs.htmlDirectory = (string)results.Options["html"].Value;
+ if (!Directory.Exists(cbArgs.htmlDirectory))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Direcotry: {0} not found.", cbArgs.htmlDirectory));
+ return (1);
+ }
+
+ if (!results.Options["project"].IsPresent)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "You must specify a project name.");
+ return (1);
+ }
+ cbArgs.projectName = (string)results.Options["project"].Value;
+
+ if (results.Options["lcid"].IsPresent)
+ {
+ try
+ {
+ cbArgs.langid = Convert.ToInt32(results.Options["lcid"].Value);
+ }
+ catch
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("{0} is not a valid integer.", results.Options["lcid"].Value));
+ return (1);
+ }
+ }
+
+
+ if (results.Options["toc"].IsPresent)
+ {
+ cbArgs.tocFile = (string)results.Options["toc"].Value;
+ if (!File.Exists(cbArgs.tocFile))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("File: {0} not found.", cbArgs.tocFile));
+ return (1);
+ }
+ }
+
+ if (!results.Options["out"].IsPresent)
+ cbArgs.outputDirectory = "Chm";
+ else
+ cbArgs.outputDirectory = (string)results.Options["out"].Value;
+ if (!Directory.Exists(cbArgs.outputDirectory))
+ {
+ Directory.CreateDirectory(cbArgs.outputDirectory);
+ //ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Direcotry: {0} not found.", cbArgs.outputDirectory));
+ //return (1);
+ }
+
+ if (results.Options["metadata"].IsPresent && (bool)results.Options["metadata"].Value)
+ {
+ cbArgs.metadata = true;
+ }
+
+ if (results.Options["config"].IsPresent)
+ {
+ cbArgs.configFile = (string)results.Options["config"].Value;
+ }
+ if (!File.Exists(cbArgs.configFile))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Config file: {0} not found.", cbArgs.configFile));
+ return (1);
+ }
+
+ try
+ {
+ ChmBuilder chmBuilder = new ChmBuilder(cbArgs);
+ chmBuilder.Run();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ return (1);
+ }
+ return 0;
+ }
+
+ //there are some special characters in hxs html, just convert them to what we want
+ public static string ReplaceMarks(string input)
+ {
+ string ret = input.Replace("%3C", "<");
+ ret = ret.Replace("%3E", ">");
+ ret = ret.Replace("%2C", ",");
+ return ret;
+ }
+
+ /// <summary>
+ /// eg: "c:\tmp\" to "c:\tmp"
+ /// </summary>
+ /// <param name="dir"></param>
+ /// <returns></returns>
+ public static string StripEndBackSlash(string dir)
+ {
+ if (dir.EndsWith("\\"))
+ return dir.Substring(0, dir.Length - 1);
+ else
+ return dir;
+ }
+
+ public void Run()
+ {
+ WriteHtmls();
+ WriteHhk();
+ if (_hasToc) WriteHhc();
+ WriteHhp();
+ }
+
+ private static int CompareKeyword(KKeywordInfo x, KKeywordInfo y)
+ {
+ if (x.MainEntry != y.MainEntry)
+ return (x.MainEntry.CompareTo(y.MainEntry));
+ else
+ {
+ string s1 = x.SubEntry;
+ string s2 = y.SubEntry;
+ if (s1 == null)
+ s1 = string.Empty;
+ if (s2 == null)
+ s2 = string.Empty;
+ return (s1.CompareTo(s2));
+ }
+ }
+
+ /// <summary>
+ /// read chmTitle from chmBuilder.config
+ /// </summary>
+ /// <returns></returns>
+ private string GetChmTitle()
+ {
+
+ XPathNodeIterator iter = _config.CreateNavigator().Select("/configuration/chmTitles/title");
+ while (iter.MoveNext())
+ {
+ if (iter.Current.GetAttribute("projectName", string.Empty).ToLower() == _args.projectName.ToLower())
+ return iter.Current.Value;
+ }
+
+ //if no title found, set title to projectname
+ return _args.projectName;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ private void InsertSeealsoIndice()
+ {
+ kkwdTable.Sort(CompareKeyword);
+ string lastMainEntry = string.Empty;
+ for (int i = 0; i < kkwdTable.Count; i++)
+ {
+ if (!string.IsNullOrEmpty(kkwdTable[i].SubEntry))
+ {
+ if (i > 0)
+ lastMainEntry = kkwdTable[i - 1].MainEntry;
+ if (lastMainEntry != kkwdTable[i].MainEntry)
+ {
+ KKeywordInfo seealso = new KKeywordInfo();
+ seealso.MainEntry = kkwdTable[i].MainEntry;
+ kkwdTable.Insert(i, seealso);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// load language info from config file
+ /// </summary>
+ /// <param name="lcid"></param>
+ private void LoadLanginfo(int lcid)
+ {
+ XPathNavigator node = _config.CreateNavigator().SelectSingleNode(String.Format("/configuration/languages/language[@id='{0}']", lcid.ToString()));
+ if (node != null)
+ {
+ _lang = new LangInfo();
+ _lang.ID = lcid;
+ _lang.CodePage = Convert.ToInt32(node.GetAttribute("codepage", string.Empty));
+ _lang.Name = node.GetAttribute("name", string.Empty);
+ }
+ else
+ {
+ throw new ArgumentException(String.Format("language {0} is not found in config file.", lcid));
+ }
+ }
+
+ private void WriteHhc()
+ {
+ XmlReaderSettings settings = new XmlReaderSettings();
+ settings.ConformanceLevel = ConformanceLevel.Fragment;
+ settings.IgnoreWhitespace = true;
+ settings.IgnoreComments = true;
+ XmlReader reader = XmlReader.Create(_args.tocFile, settings);
+
+ //<param name="Local" value="Html\15ed547b-455d-808c-259e-1eaa3c86dccc.htm">
+ //"html" before GUID
+ string _localFilePrefix = _args.htmlDirectory.Substring(_args.htmlDirectory.LastIndexOf('\\') + 1);
+
+ string fileAttr;
+ string titleValue;
+ using (StreamWriter sw = new StreamWriter(String.Format("{0}\\{1}.hhc", _args.outputDirectory, _args.projectName), false, Encoding.GetEncoding(_lang.CodePage)))
+ {
+ sw.WriteLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML/EN\">");
+ sw.WriteLine("<HTML>");
+ sw.WriteLine(" <BODY>");
+
+ bool bDefaultTopic = true;
+ while (reader.Read())
+ {
+ switch (reader.NodeType)
+ {
+ case XmlNodeType.Element:
+ if (reader.Name == "topic")
+ {
+ _indentCount = reader.Depth;
+ fileAttr = reader.GetAttribute("file") + ".htm";
+ if (titleTable.Contains(fileAttr))
+ titleValue = (string)titleTable[fileAttr];
+ else
+ titleValue = String.Empty;
+
+ WriteHhcLine(sw, "<UL>");
+ WriteHhcLine(sw, " <LI><OBJECT type=\"text/sitemap\">");
+ WriteHhcLine(sw, String.Format(" <param name=\"Name\" value=\"{0}\">", titleValue));
+ WriteHhcLine(sw, String.Format(" <param name=\"Local\" value=\"{0}\\{1}\">", _localFilePrefix, fileAttr));
+ if (bDefaultTopic)
+ {
+ _defaultTopic = _localFilePrefix + "\\" + reader.GetAttribute("file") + ".htm";
+ bDefaultTopic = false;
+ }
+ WriteHhcLine(sw, " </OBJECT></LI>");
+ if (reader.IsEmptyElement)
+ {
+ WriteHhcLine(sw, "</UL>");
+ }
+ }
+ break;
+
+ case XmlNodeType.EndElement:
+ if (reader.Name == "topic")
+ {
+ _indentCount = reader.Depth;
+ WriteHhcLine(sw, "</UL>");
+ }
+ break;
+
+ default:
+ //Console.WriteLine(reader.Name);
+ break;
+ }
+ }
+ sw.WriteLine(" </BODY>");
+ sw.WriteLine("</HTML>");
+ }
+ }
+
+ private void WriteHhcLine(TextWriter writer, string value)
+ {
+ //write correct indent space
+ writer.WriteLine();
+ for (int i = 0; i < _indentCount - 1; i++)
+ writer.Write(" ");
+ writer.Write(value);
+ }
+
+ private void WriteHhk()
+ {
+ int iPrefix = _args.outputDirectory.Length + 1;
+ bool isIndent = false;
+
+
+ InsertSeealsoIndice();
+ using (StreamWriter sw = new StreamWriter(String.Format("{0}\\{1}.hhk", _args.outputDirectory, _args.projectName), false, Encoding.GetEncoding(_lang.CodePage)))
+ {
+ sw.WriteLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML/EN\">");
+ sw.WriteLine("<HTML>");
+ sw.WriteLine(" <BODY>");
+ sw.WriteLine(" <UL>");
+
+ foreach (KKeywordInfo ki in kkwdTable)
+ {
+ if (!string.IsNullOrEmpty(ki.MainEntry))
+ {
+ string kwdValue = ki.MainEntry;
+ if (!string.IsNullOrEmpty(ki.SubEntry))
+ {
+ if (!isIndent)
+ {
+ isIndent = true;
+ sw.WriteLine(" <UL>");
+ }
+ kwdValue = ki.SubEntry;
+ }
+ else
+ {
+ if (isIndent)
+ {
+ isIndent = false;
+ sw.WriteLine(" </UL>");
+ }
+ }
+
+ sw.WriteLine(" <LI><OBJECT type=\"text/sitemap\">");
+ sw.WriteLine(String.Format(" <param name=\"Name\" value=\"{0}\">", kwdValue));
+ if (String.IsNullOrEmpty(ki.File))
+ sw.WriteLine(String.Format(" <param name=\"See Also\" value=\"{0}\">", kwdValue));
+ else
+ sw.WriteLine(String.Format(" <param name=\"Local\" value=\"{0}\">", ki.File.Substring(iPrefix)));
+ sw.WriteLine(" </OBJECT><LI>");
+ }
+ }
+
+ sw.WriteLine(" </UL>");
+ sw.WriteLine(" </BODY>");
+ sw.WriteLine("</HTML>");
+ }
+ }
+
+
+ /// <summary>
+ /// In hhp.template, {0} is projectName, {1} is defalutTopic, {2}:Language, {3}:Title
+ /// </summary>
+ private void WriteHhp()
+ {
+ string hhpFile = String.Format("{0}\\{1}.hhp", _args.outputDirectory, _args.projectName);
+ Encoding ei = Encoding.GetEncoding(_lang.CodePage);
+
+ using (FileStream writer = File.OpenWrite(hhpFile))
+ {
+ string var0 = _args.projectName;
+ string var1 = _defaultTopic;
+ string var2 = _lang.Name;
+ string var3 = GetChmTitle();
+
+ XPathNodeIterator iter = _config.CreateNavigator().Select("/configuration/hhpTemplate/line");
+
+ while (iter.MoveNext())
+ {
+ String line = iter.Current.Value;
+ AddText(writer, String.Format(line, var0, var1, var2, var3), ei);
+ AddText(writer, "\r\n", ei);
+ }
+ }
+ }
+
+ private void AddText(FileStream fs, string value, Encoding ei)
+ {
+ byte[] info = ei.GetBytes(value);
+ fs.Write(info, 0, info.Length);
+ }
+
+ private void WriteHtmls()
+ {
+ string _outhtmldir = _args.outputDirectory + _args.htmlDirectory.Substring(_args.htmlDirectory.LastIndexOf('\\'));
+ HxsChmConverter converter = new HxsChmConverter(_args.htmlDirectory, _outhtmldir, titleTable, kkwdTable, _args.metadata);
+ converter.Process();
+ }
+ }
+
+ /// <summary>
+ /// Convert hxs-ready html page to chm-ready page
+ /// 1. strip of xmlisland;
+ /// 2. <mshelp:link> link tiltle </link> ==> <span class="nolink">link title</span>
+ /// </summary>
+ internal class HxsChmConverter
+ {
+ private string _currentFile;
+ private string _currentTitle;
+ private string _htmlDir;
+ List < KKeywordInfo > _kkeywords;
+ private bool _metadata;
+ private string _outputDir;
+
+ Hashtable _titles;
+
+ private int _topicCount = 0;
+
+ public HxsChmConverter(string htmlDir, string outputDir, Hashtable titles, List < KKeywordInfo > kkeywords, bool metadata)
+ {
+ _htmlDir = htmlDir;
+ _outputDir = outputDir;
+ _titles = titles;
+ _kkeywords = kkeywords;
+ _metadata = metadata;
+ }
+
+ public void Process()
+ {
+ _topicCount = 0;
+ ProcessDirectory(_htmlDir, _outputDir);
+ Console.WriteLine("Processed {0} files.", _topicCount);
+ }
+
+ private void ProcessDirectory(string srcDir, string destDir)
+ {
+ if (!Directory.Exists(destDir))
+ {
+ Directory.CreateDirectory(destDir);
+ }
+
+ string[] fileEntries = Directory.GetFiles(srcDir);
+ foreach (string fileName in fileEntries)
+ {
+ string destFile = destDir + fileName.Substring(fileName.LastIndexOf('\\'));
+
+ FileInfo fi = new FileInfo(fileName);
+ string extion = fi.Extension.ToLower();
+ //process .htm and .html files, just copy other files, like css, gif. TFS DCR 318537
+ if (extion == ".htm" || extion == ".html")
+ {
+ try
+ {
+ ProcessFile(fileName, destFile);
+ }
+ /*
+ catch (XmlException ex)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Invalid XML file {0}", fileName));
+ ConsoleApplication.WriteMessage(LogLevel.Error, ex.Message);
+ _stop = true;
+ return;
+ }
+ */
+ catch (Exception)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("failed to process file {0}", fileName));
+ throw;
+ }
+ }
+ else
+ File.Copy(fileName, destFile, true);
+ }
+
+ // Recurse into subdirectories of this directory.
+ string[] subdirectoryEntries = Directory.GetDirectories(srcDir, "*", SearchOption.TopDirectoryOnly);
+ foreach (string subdirectory in subdirectoryEntries)
+ {
+ DirectoryInfo di = new DirectoryInfo(subdirectory);
+ string newSubdir = destDir + "\\" + di.Name;
+ ProcessDirectory(subdirectory, newSubdir);
+ }
+ }
+
+ private void ProcessFile(string srcFile, string destFile)
+ {
+ //Console.WriteLine("Processing:{0}",srcFile);
+
+ XmlReaderSettings settings = new XmlReaderSettings();
+ settings.ConformanceLevel = ConformanceLevel.Fragment;
+ settings.IgnoreWhitespace = false;
+ settings.IgnoreComments = true;
+ XmlReader reader = XmlReader.Create(srcFile, settings);
+
+ XmlWriterSettings settings2 = new XmlWriterSettings();
+ settings2.Indent = false;
+ settings2.IndentChars = "\t";
+ settings2.OmitXmlDeclaration = true;
+ XmlWriter writer = XmlWriter.Create(destFile, settings2);
+
+ _currentTitle = String.Empty;
+ _currentFile = destFile;
+
+ _topicCount++;
+
+ while (reader.Read())
+ {
+ if (_metadata == false && reader.Name.ToLower() == "xml" && reader.NodeType == XmlNodeType.Element)
+ {
+ //skip xml data island
+ reader.ReadOuterXml();
+ }
+
+ switch (reader.NodeType)
+ {
+
+ case XmlNodeType.Element:
+ string elementName = reader.Name.ToLower();
+
+ //skip <mshelp:link> node,
+ if (elementName == "mshelp:link")
+ {
+ writer.WriteStartElement("span");
+ writer.WriteAttributeString("class", "nolink");
+ reader.MoveToContent();
+ }
+
+ else
+ {
+ if (!String.IsNullOrEmpty(reader.Prefix))
+ writer.WriteStartElement(reader.Prefix, reader.LocalName, null);
+ else
+ writer.WriteStartElement(reader.Name);
+
+ if (reader.HasAttributes)
+ {
+ while (reader.MoveToNextAttribute())
+ {
+ if (!String.IsNullOrEmpty(reader.Prefix))
+ writer.WriteAttributeString(reader.Prefix, reader.LocalName, null, reader.Value);
+ else
+ //If we write the following content to output file, we will get xmlexception saying the 2003/5 namespace is redefined. So hard code to skip "xmlns".
+ //<pre>My.Computer.FileSystem.RenameFile(<span class="literal" xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">
+ if (!(reader.Depth > 2 && reader.Name.StartsWith("xmlns")))
+ writer.WriteAttributeString(reader.Name, reader.Value);
+ }
+ // Move the reader back to the element node.
+ reader.MoveToElement();
+ }
+
+ //read html/head/title, save it to _currentTitle
+ if (reader.Depth == 2 && elementName == "title")
+ {
+ if (!reader.IsEmptyElement) //skip <Title/> node, fix bug 425406
+ {
+ reader.Read();
+ if (reader.NodeType == XmlNodeType.Text)
+ {
+ _currentTitle = reader.Value;
+ writer.WriteRaw(reader.Value);
+ }
+ }
+ }
+
+ if (reader.IsEmptyElement)
+ writer.WriteEndElement();
+ }
+ break;
+
+ case XmlNodeType.Text:
+ writer.WriteValue(reader.Value);
+ break;
+
+ case XmlNodeType.EndElement:
+ writer.WriteFullEndElement();
+ break;
+
+ case XmlNodeType.Whitespace:
+ case XmlNodeType.SignificantWhitespace:
+ writer.WriteWhitespace(reader.Value);
+ break;
+
+
+ default:
+ //Console.WriteLine(reader.Name);
+ break;
+ }
+ }
+
+ writer.Close();
+
+ ReadXmlIsland(srcFile);
+
+ _titles.Add(destFile.Substring(destFile.LastIndexOf("\\") + 1), _currentTitle);
+ }
+
+
+ /// <summary>
+ /// As XmlReader is forward only and we added support for leaving xmlisland data.
+ /// We have to use another xmlreader to find TocTile, keywords etc.
+ /// </summary>
+ /// <param name="filename"></param>
+ private void ReadXmlIsland(string filename)
+ {
+ XmlReaderSettings settings = new XmlReaderSettings();
+ settings.ConformanceLevel = ConformanceLevel.Fragment;
+ settings.IgnoreWhitespace = false;
+ settings.IgnoreComments = true;
+ XmlReader reader = XmlReader.Create(filename, settings);
+
+ //Fix TFS bug 289403: search if there is comma in k keyword except those in () or <>.
+ //sample1: "StoredNumber (T1,T2) class, about StoredNumber (T1,T2) class";
+ //sample2: "StoredNumber <T1,T2> class, about StoredNumber <T1,T2> class";
+ Regex r = new Regex(@",([^\)\>]+|([^\<\>]*\<[^\<\>]*\>[^\<\>]*)?|([^\(\)]*\([^\(\)]*\)[^\(\)]*)?)$");
+
+ while (reader.Read())
+ {
+ if (reader.IsStartElement())
+ {
+ if (reader.Name.ToLower() == "mshelp:toctitle")
+ {
+ string titleAttr = reader.GetAttribute("Title");
+ if (!String.IsNullOrEmpty(titleAttr))
+ _currentTitle = titleAttr;
+ }
+
+ if (reader.Name.ToLower() == "mshelp:keyword")
+ {
+ string indexType = reader.GetAttribute("Index");
+ if (indexType == "K")
+ {
+ KKeywordInfo kkwdinfo = new KKeywordInfo();
+ string kkeyword = reader.GetAttribute("Term");
+ if (!string.IsNullOrEmpty(kkeyword))
+ {
+ kkeyword = ChmBuilder.ReplaceMarks(kkeyword);
+ Match match = r.Match(kkeyword);
+ if (match.Success)
+ {
+ kkwdinfo.MainEntry = kkeyword.Substring(0, match.Index);
+ kkwdinfo.SubEntry = kkeyword.Substring(match.Index + 1).TrimStart(new char[] { ' ' });
+ }
+ else
+ {
+ kkwdinfo.MainEntry = kkeyword;
+ }
+
+ kkwdinfo.File = _currentFile;
+ _kkeywords.Add(kkwdinfo);
+ }
+ }
+ }
+ }
+
+ if (reader.NodeType == XmlNodeType.EndElement)
+ {
+ if (reader.Name == "xml")
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.csproj b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.csproj
new file mode 100644
index 0000000..8ee8adf
--- /dev/null
+++ b/tools/Sandcastle/Source/ChmBuilder/ChmBuilder.csproj
@@ -0,0 +1,74 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ChmBuilder</RootNamespace>
+ <AssemblyName>ChmBuilder</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ChmBuilder.cs">
+ </Compile>
+ <Compile Include="ChmBuilderArgs.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ChmBuilder.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/ChmBuilder/ChmBuilderArgs.cs b/tools/Sandcastle/Source/ChmBuilder/ChmBuilderArgs.cs
new file mode 100644
index 0000000..7f21b83
--- /dev/null
+++ b/tools/Sandcastle/Source/ChmBuilder/ChmBuilderArgs.cs
@@ -0,0 +1,41 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.IO;
+using System.Reflection;
+using Microsoft.Ddue.Tools.CommandLine;
+
+
+namespace Microsoft.Ddue.Tools
+{
+ public class ChmBuilderArgs
+ {
+ public string configFile;
+ public string htmlDirectory;
+ public int langid;
+ public bool metadata;
+ public string outputDirectory;
+ public string projectName;
+ public string tocFile;
+
+ public ChmBuilderArgs()
+ {
+ this.langid = 1033;
+ this.tocFile = string.Empty;
+ this.metadata = false;
+ string configDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ this.configFile = Path.Combine(configDirectory, "ChmBuilder.config");
+ }
+
+ }
+}
diff --git a/tools/Sandcastle/Source/ChmBuilder/GlobalSuppressions.cs b/tools/Sandcastle/Source/ChmBuilder/GlobalSuppressions.cs
new file mode 100644
index 0000000..07e378e
--- /dev/null
+++ b/tools/Sandcastle/Source/ChmBuilder/GlobalSuppressions.cs
@@ -0,0 +1,53 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#GetChmTitle()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ProcessDirectory(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ProcessFile(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ReadXmlIsland(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt32(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#LoadLanginfo(System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#LoadLanginfo(System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#LoadLanginfo(System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhc()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhk()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ProcessDirectory(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhc()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhk()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhp()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.CompareTo(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#CompareKeyword(Microsoft.Ddue.Tools.KKeywordInfo,Microsoft.Ddue.Tools.KKeywordInfo)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.EndsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#StripEndBackSlash(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.LastIndexOf(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ProcessFile(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#ProcessFile(System.String,System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "BackSlash", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#StripEndBackSlash(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Chm")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Chm", Scope = "type", Target = "Microsoft.Ddue.Tools.ChmBuilder")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Chm", Scope = "type", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "langid", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#langid")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#htmlDirectory")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#langid")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#metadata")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#outputDirectory")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#tocFile")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#projectName")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#.ctor(Microsoft.Ddue.Tools.ChmBuilderArgs)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#.ctor()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilderArgs.#configFile")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.HxsChmConverter.#.ctor(System.String,System.String,System.Collections.Hashtable,System.Collections.Generic.List`1<Microsoft.Ddue.Tools.KKeywordInfo>,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#AddText(System.IO.FileStream,System.String,System.Text.Encoding)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])", Scope = "member", Target = "Microsoft.Ddue.Tools.ChmBuilder.#WriteHhp()")]
diff --git a/tools/Sandcastle/Source/ChmBuilder/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/ChmBuilder/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6f99eff
--- /dev/null
+++ b/tools/Sandcastle/Source/ChmBuilder/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ChmBuilder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MS")]
+[assembly: AssemblyProduct("ChmBuilder")]
+[assembly: AssemblyCopyright("Copyright © MS 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(false)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("92e901de-6fa9-46c8-a46b-4ae15c60f3f2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/CommandLine/BooleanOption.cs b/tools/Sandcastle/Source/CommandLine/BooleanOption.cs
new file mode 100644
index 0000000..6ea23a1
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/BooleanOption.cs
@@ -0,0 +1,36 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public sealed class BooleanOption : Option {
+
+ public BooleanOption(string name) : base(name) { }
+
+ public BooleanOption(string name, string description) : base(name, description) { }
+
+ internal override ParseResult ParseArgument(string argument) {
+ if ((argument != "+") && (argument != "-")) return (ParseResult.MalformedArgument);
+ if (present) return (ParseResult.MultipleOccurance);
+ present = true;
+ if (argument == "+") {
+ value = true;
+ } else {
+ value = false;
+ }
+ return (ParseResult.Success);
+ }
+
+ internal override void WriteTemplate(TextWriter writer) {
+ writer.WriteLine("/{0}+|-", Name);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/CommandLine.csproj b/tools/Sandcastle/Source/CommandLine/CommandLine.csproj
new file mode 100644
index 0000000..84d6af1
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/CommandLine.csproj
@@ -0,0 +1,93 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CommandLine</RootNamespace>
+ <AssemblyName>CommandLine</AssemblyName>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <Optimize>true</Optimize>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BooleanOption.cs" />
+ <Compile Include="ConsoleApplication.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="ListOption.cs" />
+ <Compile Include="LogLevel.cs" />
+ <Compile Include="Option.cs" />
+ <Compile Include="OptionCollection.cs" />
+ <Compile Include="OutputWriter.cs" />
+ <Compile Include="ParseArgumentsResult.cs" />
+ <Compile Include="ParseResult.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="StringOption.cs" />
+ <Compile Include="SwitchOption.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/CommandLine/ConsoleApplication.cs b/tools/Sandcastle/Source/CommandLine/ConsoleApplication.cs
new file mode 100644
index 0000000..17df3c7
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/ConsoleApplication.cs
@@ -0,0 +1,64 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public static class ConsoleApplication {
+
+ public static XPathDocument GetConfigurationFile() {
+ return (GetConfigurationFile(Assembly.GetCallingAssembly().Location + ".config"));
+ }
+
+ public static XPathDocument GetConfigurationFile(string file) {
+ return (new XPathDocument(file));
+ }
+
+ public static string[] GetFiles(string filePattern) {
+
+ // get the full path to the relevent directory
+ string directoryPath = Path.GetDirectoryName(filePattern);
+ if ((directoryPath == null) || (directoryPath.Length == 0)) directoryPath = Environment.CurrentDirectory;
+ directoryPath = Path.GetFullPath(directoryPath);
+
+ // get the file name, which may contain wildcards
+ string filePath = Path.GetFileName(filePattern);
+
+ // look up the files and load them
+ string[] files = Directory.GetFiles(directoryPath, filePath);
+
+ return (files);
+
+ }
+
+ // Write the name, version, and copyright information of the calling assembly
+
+ public static void WriteBanner() {
+ Assembly application = Assembly.GetCallingAssembly();
+ AssemblyName applicationData = application.GetName();
+ Console.WriteLine("{0} (v{1})", applicationData.Name, applicationData.Version);
+ Object[] copyrightAttributes = application.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), true);
+ foreach (AssemblyCopyrightAttribute copyrightAttribute in copyrightAttributes) {
+ Console.WriteLine(copyrightAttribute.Copyright);
+ }
+ }
+
+ public static void WriteMessage(LogLevel level, string message) {
+ Console.WriteLine("{0}: {1}", level, message);
+ }
+
+ public static void WriteMessage(LogLevel level, string format, params object[] arg)
+ {
+ Console.Write("{0}: ", level);
+ Console.WriteLine(format, arg);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/GlobalSuppressions.cs b/tools/Sandcastle/Source/CommandLine/GlobalSuppressions.cs
new file mode 100644
index 0000000..ee0c048
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/GlobalSuppressions.cs
@@ -0,0 +1,29 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools.CommandLine")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1050:DeclareTypesInNamespaces", Scope = "type", Target = "OutputWriter")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.Option.#present")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.Option.#value")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XPath.XPathDocument", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.ConsoleApplication.#GetConfigurationFile()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1059:MembersShouldNotExposeCertainConcreteTypes", MessageId = "System.Xml.XPath.XPathDocument", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.ConsoleApplication.#GetConfigurationFile(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1708:IdentifiersShouldDifferByMoreThanCase", Scope = "type", Target = "Microsoft.Ddue.Tools.CommandLine.Option")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Option", Scope = "type", Target = "Microsoft.Ddue.Tools.CommandLine.Option")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.Option.#Description")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.Option.#Name")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "value", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.Option.#IsRequired")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.OptionCollection.#Add(Microsoft.Ddue.Tools.CommandLine.Option)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.CommandLine.OptionCollection.#Remove(Microsoft.Ddue.Tools.CommandLine.Option)")]
diff --git a/tools/Sandcastle/Source/CommandLine/ListOption.cs b/tools/Sandcastle/Source/CommandLine/ListOption.cs
new file mode 100644
index 0000000..85ec160
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/ListOption.cs
@@ -0,0 +1,47 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public class ListOption : Option {
+
+ private string template = "xxxx";
+
+ private List < string > values = new List < string >();
+
+ public ListOption(string name) : base(name) { }
+
+ public ListOption(string name, string description) : base(name, description) { }
+
+ public ListOption(string name, string description, string template) : base(name, description) {
+ this.template = template;
+ }
+
+ public override Object Value {
+ get {
+ return (values.ToArray());
+ }
+ }
+
+ internal override ParseResult ParseArgument(string argument) {
+ if (argument.Length == 0) return (ParseResult.MalformedArgument);
+ if (argument[0] != ':') return (ParseResult.MalformedArgument);
+ present = true;
+ string[] atoms = argument.Substring(1).Split(',');
+ foreach (string atom in atoms) values.Add(atom);
+ return (ParseResult.Success);
+ }
+
+ internal override void WriteTemplate(TextWriter writer) {
+ writer.WriteLine("/{0}:{1}[,{1},{1},...]", Name, template);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/LogLevel.cs b/tools/Sandcastle/Source/CommandLine/LogLevel.cs
new file mode 100644
index 0000000..e1766ac
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/LogLevel.cs
@@ -0,0 +1,18 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+
+ public enum LogLevel {
+ Info, Warn, Error
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/Option.cs b/tools/Sandcastle/Source/CommandLine/Option.cs
new file mode 100644
index 0000000..6ca902d
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/Option.cs
@@ -0,0 +1,97 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public abstract class Option {
+
+ internal bool processed;
+
+ protected bool present;
+ [CLSCompliant(false)]
+ protected object value;
+ private string description;
+
+ // Data Members
+
+ private string name;
+ private bool required;
+
+ // Constructors
+
+ protected Option(string name) {
+ foreach (char character in name) {
+ if (!(Char.IsLetter(character) || (character == '?'))) throw new ArgumentException("Names must consist of letters.", "name");
+ }
+ this.name = name;
+ }
+
+ protected Option(string name, string description) : this(name) {
+ this.description = description;
+ }
+
+ protected Option(string name, string description, bool required) : this(name, description) {
+ this.required = required;
+ }
+
+ public string Description {
+ get {
+ return (description);
+ }
+ set {
+ if (processed) throw new InvalidOperationException();
+ description = value;
+ }
+ }
+
+ public virtual bool IsPresent {
+ get {
+ if (!processed) throw new InvalidOperationException();
+ return (present);
+ }
+ }
+
+ public bool IsRequired {
+ get {
+ return (required);
+ }
+ set {
+ if (processed) throw new InvalidOperationException();
+ required = value;
+ }
+ }
+
+ // Accessors
+
+ public string Name {
+ get {
+ return (name);
+ }
+ set {
+ if (processed) throw new InvalidOperationException();
+ name = value;
+ }
+ }
+
+ public virtual Object Value {
+ get {
+ if (!processed) throw new InvalidOperationException();
+ return (value);
+ }
+ }
+
+ // To be implemented by children
+
+ internal abstract ParseResult ParseArgument(string args);
+
+ internal abstract void WriteTemplate(TextWriter writer);
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/OptionCollection.cs b/tools/Sandcastle/Source/CommandLine/OptionCollection.cs
new file mode 100644
index 0000000..882a673
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/OptionCollection.cs
@@ -0,0 +1,182 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Collections;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+
+ public sealed class OptionCollection : ICollection < Option >, ICollection, IEnumerable < Option >, IEnumerable {
+ private Dictionary < string, Option > map = new Dictionary < string, Option >();
+
+ private List < Option > options = new List < Option >();
+
+
+ public int Count {
+ get {
+ return (options.Count);
+ }
+ }
+
+ // Extras for ICollection<Option>
+
+ bool ICollection < Option >.IsReadOnly {
+ get {
+ return (false);
+ }
+ }
+
+ // Extras for ICollection
+
+ bool ICollection.IsSynchronized {
+ get {
+ return (false);
+ }
+ }
+
+ Object ICollection.SyncRoot {
+ get {
+ return (this);
+ }
+ }
+
+ public Option this[string name] {
+ get {
+ Option option;
+ if (map.TryGetValue(name, out option)) {
+ return (option);
+ } else {
+ return (null);
+ }
+ }
+ }
+
+ public void Add(Option option) {
+ if (option == null) throw new ArgumentNullException("option");
+ map.Add(option.Name, option);
+ options.Add(option);
+ }
+
+
+ public void Clear() {
+ options.Clear();
+ map.Clear();
+ }
+
+ bool ICollection < Option >.Contains(Option option) {
+ return (options.Contains(option));
+ }
+
+ void ICollection < Option >.CopyTo(Option[] array, int startIndex) {
+ options.CopyTo(array, startIndex);
+ }
+
+ void ICollection.CopyTo(Array array, int startIndex) {
+ ((ICollection)options).CopyTo(array, startIndex);
+ }
+
+ // Extras for IEnumerable<Option>
+
+ IEnumerator < Option > IEnumerable < Option >.GetEnumerator() {
+ return (options.GetEnumerator());
+ }
+
+ // Extras for IEnumerable
+
+ IEnumerator IEnumerable.GetEnumerator() {
+ return (options.GetEnumerator());
+ }
+
+ // Parse arguments -- the main show
+
+ public ParseArgumentsResult ParseArguments(string[] args) {
+
+ // keep track of results
+ ParseArgumentsResult results = new ParseArgumentsResult();
+ results.options = this;
+
+ // parse arguments
+ ParseArguments(args, results);
+
+ return (results);
+
+ }
+
+ public bool Remove(Option option) {
+ int index = options.IndexOf(option);
+ if (index < 0) return (false);
+ options.RemoveAt(index);
+ map.Remove(option.Name);
+ return (true);
+ }
+
+ // Print help
+
+ public void WriteOptionSummary(TextWriter writer) {
+ if (writer == null) throw new ArgumentNullException("writer");
+ foreach (Option option in options) {
+ writer.WriteLine();
+ option.WriteTemplate(writer);
+ writer.WriteLine(option.Description);
+ }
+ }
+
+ private void ParseArguments(string[] args, ParseArgumentsResult results) {
+
+ foreach (string arg in args) {
+ if (arg.Length == 0) continue;
+ if (arg[0] == '/') {
+ // option processing
+ // find the named option
+ int index = 1;
+ while (index < arg.Length) {
+ if ((!Char.IsLetter(arg, index)) && (arg[index] != '?')) break;
+ index++;
+ }
+ string key = arg.Substring(1, index - 1);
+ string value = arg.Substring(index);
+ // invoke the appropriate logic
+ if (map.ContainsKey(key)) {
+ Option option = (Option)map[key];
+ ParseResult result = option.ParseArgument(value);
+ if (result != ParseResult.Success) {
+ results.errors.Add(arg, result);
+ }
+ } else {
+ results.errors.Add(arg, ParseResult.UnrecognizedOption);
+ }
+ } else if (arg[0] == '@') {
+ string responseFile = arg.Substring(1);
+ List < string > responses = new List < string >();
+ using (TextReader reader = File.OpenText(responseFile)) {
+ while (true) {
+ string response = reader.ReadLine();
+ if (response == null) break;
+ responses.Add(response);
+ }
+ }
+ ParseArguments(responses.ToArray(), results);
+ } else {
+ // non-option processing
+ results.nonoptions.Add(arg);
+ }
+ }
+
+ // make sure the required arguments were present
+ foreach (Option option in map.Values) {
+ option.processed = true;
+ if ((option.IsRequired) && (!option.IsPresent)) {
+ results.errors.Add(option.Name, ParseResult.MissingOption);
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/OutputWriter.cs b/tools/Sandcastle/Source/CommandLine/OutputWriter.cs
new file mode 100644
index 0000000..c98efd5
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/OutputWriter.cs
@@ -0,0 +1,27 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+
+public static class OutputWriter {
+
+ private static int warningCount;
+
+ public static int WarningCount {
+ get {
+ return (warningCount);
+ }
+ }
+
+ public static void WriteWarning(string text) {
+ warningCount++;
+ Console.WriteLine(text);
+ }
+
+ public static void WriteWarning(string format, params Object[] values) {
+ warningCount++;
+ Console.WriteLine(format, values);
+ }
+}
diff --git a/tools/Sandcastle/Source/CommandLine/ParseArgumentsResult.cs b/tools/Sandcastle/Source/CommandLine/ParseArgumentsResult.cs
new file mode 100644
index 0000000..fc7fab6
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/ParseArgumentsResult.cs
@@ -0,0 +1,63 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public sealed class ParseArgumentsResult {
+
+ internal Dictionary < string, ParseResult > errors = new Dictionary < string, ParseResult >();
+
+ internal List < string > nonoptions = new List < string >();
+
+ // data
+
+ internal OptionCollection options;
+
+ internal ParseArgumentsResult() { }
+
+ // accessors
+
+ public OptionCollection Options {
+ get {
+ return (options);
+ }
+ }
+
+ public bool Success {
+ get {
+ if (errors.Count == 0) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+ }
+
+ public ReadOnlyCollection < string > UnusedArguments {
+
+ get {
+ return (new ReadOnlyCollection < string >(nonoptions));
+ }
+ }
+
+ public void WriteParseErrors(TextWriter writer) {
+
+ if (writer == null) throw new ArgumentNullException("writer");
+ foreach (KeyValuePair < string, ParseResult > error in errors) {
+ writer.WriteLine("{0}: {1}", error.Value, error.Key);
+
+ }
+
+ }
+
+ }
+
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/ParseResult.cs b/tools/Sandcastle/Source/CommandLine/ParseResult.cs
new file mode 100644
index 0000000..6129310
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/ParseResult.cs
@@ -0,0 +1,18 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+namespace Microsoft.Ddue.Tools.CommandLine
+{
+
+ internal enum ParseResult {
+ Success,
+ ArgumentNotAllowed,
+ MalformedArgument,
+ MissingOption,
+ UnrecognizedOption,
+ MultipleOccurance
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/CommandLine/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cd3d1c8
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/Properties/AssemblyInfo.cs
@@ -0,0 +1,42 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CommandLine")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("CommandLine")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("fd7d22ad-e481-446e-af49-3db9db2f4b61")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/CommandLine/StringOption.cs b/tools/Sandcastle/Source/CommandLine/StringOption.cs
new file mode 100644
index 0000000..e9beb95
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/StringOption.cs
@@ -0,0 +1,48 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public sealed class StringOption : Option {
+
+ private string template = "xxxx";
+
+ public StringOption(string name) : base(name) { }
+
+ public StringOption(string name, string description) : base(name, description) { }
+
+ public StringOption(string name, string description, string template) : base(name, description) {
+ this.template = template;
+ }
+
+ public string Template {
+ get {
+ return (template);
+ }
+ set {
+ template = value;
+ }
+ }
+
+ internal override ParseResult ParseArgument(string argument) {
+ if (!(argument.Length > 0)) return (ParseResult.MalformedArgument);
+ if (argument[0] != ':') return (ParseResult.MalformedArgument);
+ if (present) return (ParseResult.MultipleOccurance);
+ present = true;
+ value = argument.Substring(1);
+ return (ParseResult.Success);
+ }
+
+ internal override void WriteTemplate(TextWriter writer) {
+ writer.WriteLine("/{0}:{1}", Name, template);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/CommandLine/SwitchOption.cs b/tools/Sandcastle/Source/CommandLine/SwitchOption.cs
new file mode 100644
index 0000000..394d137
--- /dev/null
+++ b/tools/Sandcastle/Source/CommandLine/SwitchOption.cs
@@ -0,0 +1,31 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+namespace Microsoft.Ddue.Tools.CommandLine {
+
+ public sealed class SwitchOption : Option {
+
+ public SwitchOption(string name) : base(name) { }
+
+ public SwitchOption(string name, string description) : base(name, description) { }
+
+ internal override ParseResult ParseArgument(string argument) {
+ if (argument.Length > 0) return (ParseResult.MalformedArgument);
+ if (present) return (ParseResult.MultipleOccurance);
+ present = true;
+ return (ParseResult.Success);
+ }
+
+ internal override void WriteTemplate(TextWriter writer) {
+ writer.WriteLine("/{0}", Name);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/DBCSFix/DBCSFix.csproj b/tools/Sandcastle/Source/DBCSFix/DBCSFix.csproj
new file mode 100644
index 0000000..26b7d78
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/DBCSFix.csproj
@@ -0,0 +1,83 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{80407AE8-7A1F-4C28-8627-6C871E1D717A}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DBCSFix</RootNamespace>
+ <AssemblyName>DBCSFix</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ <DependentUpon>Settings.settings</DependentUpon>
+ </Compile>
+ <Compile Include="Settings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="readme.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/DBCSFix/GlobalSuppressions.cs b/tools/Sandcastle/Source/DBCSFix/GlobalSuppressions.cs
new file mode 100644
index 0000000..951acfd
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/GlobalSuppressions.cs
@@ -0,0 +1,16 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
diff --git a/tools/Sandcastle/Source/DBCSFix/Program.cs b/tools/Sandcastle/Source/DBCSFix/Program.cs
new file mode 100644
index 0000000..515da50
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/Program.cs
@@ -0,0 +1,210 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using Microsoft.Ddue.Tools.CommandLine;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace DBCSFix
+{
+ internal class Program
+ {
+ public static void Main(string[] args)
+ {
+ ConsoleApplication.WriteBanner();
+
+ // get and validate args
+ OptionCollection programOptions = new OptionCollection();
+ programOptions.Add(new SwitchOption("?", "Show this help page."));
+ programOptions.Add(new StringOption("d", @"The directory containing CHM input files (e.g., HHP file). For example, 'C:\DocProject\Output\Chm'. Default is the current directory."));
+ programOptions.Add(new StringOption("l", @"The language code ID in decimal. For example, '1033'. Default is '1033' (for EN-US)."));
+ ParseArgumentsResult options = programOptions.ParseArguments(args);
+ if (options.Options["?"].IsPresent)
+ programOptions.WriteOptionSummary(Console.Error);
+
+ // determine the working dir
+ string chmDirectory;
+ if (options.Options["d"].IsPresent)
+ chmDirectory = options.Options["d"].Value.ToString();
+ else
+ chmDirectory = Environment.CurrentDirectory;
+
+ // determine the desired language
+ string lcid;
+ if (options.Options["l"].IsPresent)
+ lcid = options.Options["l"].Value.ToString();
+ else
+ lcid = "1033";
+
+ // ensure working dir exists
+ if (!Directory.Exists(chmDirectory))
+ {
+ Console.WriteLine("The specified directory '{0}' doesn't exist. Quitting.", chmDirectory);
+ return;
+ }
+
+ // convert unsupported high-order chars to ascii equivalents
+ substituteAsciiEquivalents(chmDirectory, lcid);
+
+ // no further work required for 1033
+ if (String.Equals(lcid, "1033"))
+ return;
+
+ // convert unsupported chars to named entities
+ substituteNamedEntities(chmDirectory);
+
+ // convert charset declarations from utf8 to proper ansi codepage value
+ substituteCodepages(chmDirectory, lcid);
+
+ // convert char encodings from utf8 to ansi
+ convertUtf8ToAnsi(chmDirectory, lcid);
+ }
+
+ private static void convertUtf8ToAnsi(string chmDirectory, string lcid)
+ {
+ Console.WriteLine("Converting character encodings from utf8 to ansi.");
+ Encoding ansi = Encoding.GetEncoding(encodingNameForLcid(lcid));
+
+ List < string > files = new List < string >();
+ files.AddRange(Directory.GetFiles(chmDirectory, "*.htm", SearchOption.AllDirectories));
+
+ foreach (string file in files)
+ {
+ using (StreamWriter sw = new StreamWriter(file + ".tmp", false, ansi))
+ {
+ using (StreamReader input = new StreamReader(file))
+ {
+ Encoding sourceEncoding = input.CurrentEncoding;
+ string line;
+ while ((line = input.ReadLine()) != null)
+ {
+ byte[] sourceBytes = sourceEncoding.GetBytes(line);
+ byte[] ansiBytes = Encoding.Convert(sourceEncoding, ansi, sourceBytes);
+ sw.WriteLine(ansi.GetString(ansiBytes));
+ }
+ }
+ }
+
+ File.Delete(file);
+ File.Move(file + ".tmp", file);
+ }
+ }
+
+ private static string encodingNameForLcid(string lcid)
+ {
+ string charset = System.Configuration.ConfigurationSettings.AppSettings[lcid];
+ if (String.IsNullOrEmpty(charset))
+ return "Windows-1252";
+ else
+ return charset;
+ }
+
+ private static void substituteAsciiEquivalents(string chmDirectory, string lcid)
+ {
+ Console.WriteLine("Converting unsupported high-order characters to 7-bit ASCII equivalents.");
+
+ /* substitution table:
+ * Char name utf8 (hex) ascii
+ * Non-breaking space \xC2\xA0 "&nbsp;" (for all languages except Japanese)
+ * Non-breaking hyphen \xE2\x80\x91 "-"
+ * En dash \xE2\x80\x93 "-"
+ * Left curly single quote \xE2\x80\x98 "'"
+ * Right curly single quote \xE2\x80\x99 "'"
+ * Left curly double quote \xE2\x80\x9C "\""
+ * Right curly double quote \xE2\x80\x9D "\""
+ * Horizontal ellipsis U+2026 "..."
+ */
+
+ Dictionary < Regex, string > substitutionPatterns = new Dictionary < Regex, string >();
+ substitutionPatterns.Add(new Regex(@"\u2018|\u2019", RegexOptions.Compiled), "'");
+ substitutionPatterns.Add(new Regex(@"\u201C|\u201D", RegexOptions.Compiled), "\"");
+ substitutionPatterns.Add(new Regex(@"\u2026", RegexOptions.Compiled), "...");
+ if (chmDirectory != "1041")
+ substitutionPatterns.Add(new Regex(@"\u00A0", RegexOptions.Compiled), "&nbsp;");
+ else
+ substitutionPatterns.Add(new Regex(@"\u00A0", RegexOptions.Compiled), " ");
+
+ string ansi = Encoding.GetEncoding(encodingNameForLcid(lcid)).HeaderName;
+ Console.WriteLine("EncodingName: " + ansi);
+ if (!string.Equals(ansi, "Windows-1252"))
+ {
+ substitutionPatterns.Add(new Regex(@"\u2011|\u2013", RegexOptions.Compiled), "-");
+ substituteInFiles(chmDirectory, "*.htm", substitutionPatterns);
+ }
+ else
+ {
+ // replace em-dashes with hyphens, if not windows-1252 (e.g., 1033)
+ substitutionPatterns.Add(new Regex(@"\u2011|\u2013|\u2014", RegexOptions.Compiled), "-");
+ }
+ }
+
+ private static void substituteCodepages(string chmDirectory, string lcid)
+ {
+ Console.WriteLine("Inserting charset declarations.");
+
+ Dictionary < Regex, string > substitutionPatterns = new Dictionary < Regex, string >();
+ substitutionPatterns.Add(new Regex(@"CHARSET=UTF-8", RegexOptions.Compiled | RegexOptions.IgnoreCase), "CHARSET=" + encodingNameForLcid(lcid));
+
+ substituteInFiles(chmDirectory, "*.htm", substitutionPatterns);
+ }
+
+ private static void substituteInFiles(string directory, string fileSpec, ICollection < KeyValuePair < Regex, string > > substitutionPatterns)
+ {
+ Debug.Assert(Directory.Exists(directory), "Specified directory doesn't exist.");
+ Debug.Assert(!String.IsNullOrEmpty(fileSpec), "FileSpec is empty");
+ Debug.Assert(substitutionPatterns.Count > 0, "No substitution patterns.");
+
+ string[] files = Directory.GetFiles(directory, fileSpec, SearchOption.AllDirectories);
+ foreach (string file in files)
+ {
+ using (StreamWriter output = new StreamWriter(file + ".tmp", true, Encoding.UTF8))
+ {
+ using (StreamReader input = new StreamReader(file))
+ {
+ string line;
+ while ((line = input.ReadLine()) != null)
+ {
+ foreach (KeyValuePair < Regex, string > pattern in substitutionPatterns)
+ {
+ line = pattern.Key.Replace(line, pattern.Value);
+ }
+ output.WriteLine(line);
+ }
+ }
+ }
+
+ File.Delete(file);
+ File.Move(file + ".tmp", file);
+ }
+ }
+
+ private static void substituteNamedEntities(string chmDirectory)
+ {
+ Console.WriteLine("Converting other unsupported high-order characters to named entities.");
+
+ /* substitution table:
+ * Char name utf8 (hex) named entity
+ * Copyright \xC2\xA0 &copy
+ * Registered trademark \xC2\xAE &reg
+ * Em dash \xE2\x80\x94 &mdash;
+ * Trademark \xE2\x84\xA2 &trade;
+ */
+
+ Dictionary < Regex, string > substitutionPatterns = new Dictionary < Regex, string >();
+ substitutionPatterns.Add(new Regex(@"\u00A9", RegexOptions.Compiled), "&copy;");
+ substitutionPatterns.Add(new Regex(@"\u00AE", RegexOptions.Compiled), "&reg;");
+ substitutionPatterns.Add(new Regex(@"\u2014", RegexOptions.Compiled), "&mdash;");
+ substitutionPatterns.Add(new Regex(@"\u2122", RegexOptions.Compiled), "&trade;");
+
+ substituteInFiles(chmDirectory, "*.htm", substitutionPatterns);
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/DBCSFix/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/DBCSFix/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ae06688
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/Properties/AssemblyInfo.cs
@@ -0,0 +1,37 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DBCSFix")]
+[assembly: AssemblyDescription("Works around codepage limitations in the CHM compiler.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DBCSFix")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6b2709f4-d535-4a7a-bacf-f6564c42a653")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/DBCSFix/Properties/Settings.Designer.cs b/tools/Sandcastle/Source/DBCSFix/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..2a727ca
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.1433
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DBCSFix.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/tools/Sandcastle/Source/DBCSFix/Properties/Settings.settings b/tools/Sandcastle/Source/DBCSFix/Properties/Settings.settings
new file mode 100644
index 0000000..8e615f2
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/Properties/Settings.settings
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles />
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/DBCSFix/Settings.cs b/tools/Sandcastle/Source/DBCSFix/Settings.cs
new file mode 100644
index 0000000..f2ad7ea
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/Settings.cs
@@ -0,0 +1,34 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+namespace DBCSFix.Properties
+{
+
+
+ // This class allows you to handle specific events on the settings class:
+ // The SettingChanging event is raised before a setting's value is changed.
+ // The PropertyChanged event is raised after a setting's value is changed.
+ // The SettingsLoaded event is raised after the setting values are loaded.
+ // The SettingsSaving event is raised before the setting values are saved.
+ internal sealed partial class Settings {
+
+ public Settings() {
+ // // To add event handlers for saving and changing settings, uncomment the lines below:
+ //
+ // this.SettingChanging += this.SettingChangingEventHandler;
+ //
+ // this.SettingsSaving += this.SettingsSavingEventHandler;
+ //
+ }
+
+ private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
+ // Add code to handle the SettingChangingEvent event here.
+ }
+
+ private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
+ // Add code to handle the SettingsSaving event here.
+ }
+ }
+}
diff --git a/tools/Sandcastle/ProductionTools/DBCSFix.exe.config b/tools/Sandcastle/Source/DBCSFix/app.config
index 17fa07c..17fa07c 100644
--- a/tools/Sandcastle/ProductionTools/DBCSFix.exe.config
+++ b/tools/Sandcastle/Source/DBCSFix/app.config
diff --git a/tools/Sandcastle/Source/DBCSFix/readme.txt b/tools/Sandcastle/Source/DBCSFix/readme.txt
new file mode 100644
index 0000000..dfe8694
--- /dev/null
+++ b/tools/Sandcastle/Source/DBCSFix/readme.txt
@@ -0,0 +1,42 @@
+dbcsFix.exe
+(C) Microsoft 2007
+
+FUNCTION:
+dbcsFix.exe attempts to work around limitations in the CHM compiler regarding character encodings and representations. Specifically:
+1. Replaces some characters with ASCII equivelents, as follows:
+ /* substitution table:
+ * Char name utf8 (hex) ascii
+ * Non-breaking space \xC2\xA0 "&nbsp;" (for all languages except Japanese)
+ * Non-breaking hyphen \xE2\x80\x91 "-"
+ * En dash \xE2\x80\x93 "-"
+ * Left curly single quote \xE2\x80\x98 "'"
+ * Right curly single quote \xE2\x80\x99 "'"
+ * Left curly double quote \xE2\x80\x9C "\""
+ * Right curly double quote \xE2\x80\x9D "\""
+ * Horizontal ellipsis U+2026 "..."
+ */
+After this step, no further work is done when LCID == 1033.
+
+2. Replaces some characters with named entitites, as follows:
+ /* substitution table:
+ * Char name utf8 (hex) named entity
+ * Copyright \xC2\xA0 &copy
+ * Registered trademark \xC2\xAE &reg
+ * Em dash \xE2\x80\x94 &mdash;
+ * Trademark \xE2\x84\xA2 &trade;
+ */
+
+3. Replaces the default "CHARSET=UTF-8" setting in the HTML generated by ChmBuilder with "CHARSET=" + the proper value for the specified LCID, as determined by the application's .config file
+
+4. Re-encodes all input HTML from their current encoding (UTF-8, as output by ChmBuilder) to the correct encoding for the specified LCID.
+
+USAGE:
+dbcsFix.exe [-d=Directory] [-l=LCID]
+-d is the directory containing CHM input files (e.g., HHP file). For example, 'C:\DocProject\Output\Chm'. Default is the current directory.
+-l is the language code ID in decimal. For example, '1033'. Default is '1033' (for EN-US).
+
+Usage is also available with -?
+
+After processing the inputs with dbcsFix.exe, the call to the CHM compiler must be made when the system locale is the same as the value set when calling this tool. This can be done either by changing your system settings via the control panel, or by using the 3rd party utility SbAppLocale (http://www.steelbytes.com/?mid=45). In the latter case, the call should be similar to:
+SbAppLocale.exe $(LCID) "%PROGRAMFILES%\HTML Help Workshop\hhc.exe" Path\Project.Hhp
+
diff --git a/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs
new file mode 100644
index 0000000..f935921
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/ExtensionMethodAddIn.cs
@@ -0,0 +1,328 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ // Extension method add in
+
+ public class ExtensionMethodAddIn : MRefBuilderAddIn {
+
+ private Dictionary < TypeNode, List < Method > > index = new Dictionary < TypeNode, List < Method > >();
+
+ private bool isExtensionMethod = false;
+
+ private ManagedReflectionWriter reflector;
+
+ public ExtensionMethodAddIn(ManagedReflectionWriter reflector, XPathNavigator configuration) : base(reflector, configuration) {
+ this.reflector = reflector;
+ reflector.RegisterStartTagCallback("apis", new MRefBuilderCallback(RecordExtensionMethods));
+ reflector.RegisterEndTagCallback("elements", new MRefBuilderCallback(AddExtensionMethods));
+ reflector.RegisterStartTagCallback("apidata", new MRefBuilderCallback(AddExtensionSubsubgroup));
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="writer"></param>
+ /// <param name="type">the current type being extended</param>
+ /// <param name="extensionMethodTemplate">A reference to the extension method. For generic methods, this is a reference to the
+ /// non-specialized method, e.g. System.Linq.Enumerable.Select``2.
+ /// </param>
+ /// <param name="specialization">When the current type implements or inherits from a specialization of a generic type,
+ /// this parameter has a TypeNode for the type used as apecialization of the generic type's first template param.
+ /// </param>
+ private void AddExtensionMethod(XmlWriter writer, TypeNode type, Method extensionMethodTemplate, TypeNode specialization)
+ {
+ // If this is a specialization of a generic method, construct a Method object that describes the specialization
+ Method extensionMethodTemplate2 = extensionMethodTemplate;
+ if (extensionMethodTemplate2.IsGeneric && (specialization != null))
+ {
+ // the specialization type is the first of the method's template arguments
+ TypeNodeList templateArgs = new TypeNodeList();
+ templateArgs.Add(specialization);
+ // add any additional template arguments
+ for (int i = 1; i < extensionMethodTemplate.TemplateParameters.Count; i++)
+ templateArgs.Add(extensionMethodTemplate.TemplateParameters[i]);
+ extensionMethodTemplate2 = extensionMethodTemplate.GetTemplateInstance(type, templateArgs);
+ }
+ TypeNode extensionMethodTemplateReturnType = extensionMethodTemplate2.ReturnType;
+ ParameterList extensionMethodTemplateParameters = extensionMethodTemplate2.Parameters;
+
+ ParameterList extensionMethodParameters = new ParameterList();
+ for (int i = 1; i < extensionMethodTemplateParameters.Count; i++)
+ {
+ Parameter extensionMethodParameter = extensionMethodTemplateParameters[i];
+ extensionMethodParameters.Add(extensionMethodParameter);
+ }
+ Method extensionMethod = new Method(extensionMethodTemplate.DeclaringType, new AttributeList(), extensionMethodTemplate.Name, extensionMethodParameters, extensionMethodTemplate.ReturnType, null);
+ extensionMethod.Flags = extensionMethodTemplate.Flags & ~MethodFlags.Static;
+
+ // for generic methods, set the template args and params so the template data is included in the id and the method data
+ if (extensionMethodTemplate2.IsGeneric)
+ {
+ extensionMethod.IsGeneric = true;
+ if (specialization != null)
+ {
+ // set the template args for the specialized generic method
+ extensionMethod.TemplateArguments = extensionMethodTemplate2.TemplateArguments;
+ }
+ else
+ {
+ // set the generic template params for the non-specialized generic method
+ extensionMethod.TemplateParameters = extensionMethodTemplate2.TemplateParameters;
+ }
+ }
+
+ // Get the id
+ string extensionMethodTemplateId = reflector.ApiNamer.GetMemberName(extensionMethodTemplate);
+
+ // write the element node
+ writer.WriteStartElement("element");
+ writer.WriteAttributeString("api", extensionMethodTemplateId);
+ writer.WriteAttributeString("source", "extension");
+ isExtensionMethod = true;
+ reflector.WriteMember(extensionMethod);
+ isExtensionMethod = false;
+ writer.WriteEndElement();
+ }
+
+ private void AddExtensionMethods(XmlWriter writer, Object info)
+ {
+
+ MemberDictionary members = info as MemberDictionary;
+ if (members == null) return;
+
+ TypeNode type = members.Type;
+
+ InterfaceList contracts = type.Interfaces;
+ foreach (Interface contract in contracts)
+ {
+ List<Method> extensionMethods = null;
+ if (index.TryGetValue(contract, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, null);
+ }
+ if (contract.IsGeneric && (contract.TemplateArguments != null) && (contract.TemplateArguments.Count > 0))
+ {
+ Interface templateContract = (Interface)ReflectionUtilities.GetTemplateType(contract);
+ TypeNode specialization = contract.TemplateArguments[0];
+ if (index.TryGetValue(templateContract, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ {
+ if (IsValidTemplateArgument(specialization, extensionMethod.TemplateParameters[0]))
+ {
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, specialization);
+ }
+ }
+ }
+ }
+ }
+
+ TypeNode comparisonType = type;
+ while (comparisonType != null)
+ {
+ List<Method> extensionMethods = null;
+ if (index.TryGetValue(comparisonType, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, null);
+ }
+ if (comparisonType.IsGeneric && (comparisonType.TemplateArguments != null) && (comparisonType.TemplateArguments.Count > 0))
+ {
+ TypeNode templateType = ReflectionUtilities.GetTemplateType(comparisonType);
+ TypeNode specialization = comparisonType.TemplateArguments[0];
+ if (index.TryGetValue(templateType, out extensionMethods))
+ {
+ foreach (Method extensionMethod in extensionMethods)
+ {
+ if (IsValidTemplateArgument(specialization, extensionMethod.TemplateParameters[0]))
+ {
+ if (!IsExtensionMethodHidden(extensionMethod, members))
+ AddExtensionMethod(writer, type, extensionMethod, specialization);
+ }
+ }
+ }
+ }
+ comparisonType = comparisonType.BaseType;
+ }
+ }
+
+ private void AddExtensionSubsubgroup(XmlWriter writer, Object data) {
+ if (isExtensionMethod) writer.WriteAttributeString("subsubgroup", "extension");
+ }
+
+ private bool HasExtensionAttribute(Method method) {
+ AttributeList attributes = method.Attributes;
+ foreach (AttributeNode attribute in attributes) {
+ if (attribute.Type.FullName == "System.Runtime.CompilerServices.ExtensionAttribute") return (true);
+ }
+ return (false);
+ }
+
+ private bool IsValidTemplateArgument(TypeNode type, TypeNode parameter) {
+ if (type == null) throw new ArgumentNullException("type");
+ if (parameter == null) throw new ArgumentNullException("parameter");
+
+ // check that the parameter really is a type parameter
+
+ ITypeParameter itp = parameter as ITypeParameter;
+ if (itp == null) throw new ArgumentException("The 'parameter' argument is null or not an 'ITypeParameter'.");
+
+ // test constraints
+
+ bool reference = ((itp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) > 0);
+ if (reference && type.IsValueType) return (false);
+
+ bool value = ((itp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) > 0);
+ if (value && !type.IsValueType) return (false);
+
+ bool constructor = ((itp.TypeParameterFlags & TypeParameterFlags.DefaultConstructorConstraint) > 0);
+
+
+ InterfaceList contracts = parameter.Interfaces;
+ if (contracts != null) {
+ foreach (Interface contract in contracts) {
+ if (!type.IsAssignableTo(contract)) return (false);
+ }
+ }
+
+ TypeNode parent = parameter.BaseType;
+ if ((parent != null) && !type.IsAssignableTo(parent)) return (false);
+
+ // okay, passed all tests
+
+ return (true);
+
+ }
+
+ private void RecordExtensionMethods(XmlWriter writer, Object info)
+ {
+ NamespaceList spaces = (NamespaceList)info;
+ foreach (Namespace space in spaces)
+ {
+ TypeNodeList types = space.Types;
+ foreach (TypeNode type in types)
+ {
+
+ MemberList members = type.Members;
+
+ // go through the members, looking for fields signaling extension methods
+ foreach (Member member in members)
+ {
+
+ Method method = member as Method;
+ if (method == null) continue;
+
+ if (!reflector.ApiFilter.IsExposedMember(method)) continue;
+
+ if (!HasExtensionAttribute(method)) continue;
+
+ ParameterList parameters = method.Parameters;
+ TypeNode extendedType = parameters[0].Type;
+
+ // recognize generic extension methods where the extended type is a specialization of a generic type,
+ // and the extended type's specialized template arg is a type parameter declared by the generic extension method
+ // In this case, we need to save a TypeNode for the non-specialized type in the index,
+ // because a TypeNode for the specialized type won't match correctly in AddExtensionMethods
+ // Note: we are not interested in extended types that are specialized by a specific type rather than by the extension method's template param.
+ if (method.IsGeneric && (method.TemplateParameters.Count > 0))
+ {
+ if (extendedType.IsGeneric && (extendedType.TemplateArguments != null) && (extendedType.TemplateArguments.Count == 1))
+ {
+ // is the extended type's template arg a template parameter, rather than a specialized type?
+ TypeNode arg = extendedType.TemplateArguments[0];
+ if (arg.IsTemplateParameter)
+ {
+ // is the template parameter declared on the extension method
+ ITypeParameter gtp = (ITypeParameter)arg;
+ if ((gtp.DeclaringMember == method) && (gtp.ParameterListIndex == 0))
+ {
+ // get a TypeNode for the non-specialized type
+ extendedType = ReflectionUtilities.GetTemplateType(extendedType);
+ }
+ }
+ }
+ }
+
+ List<Method> methods = null;
+ if (!index.TryGetValue(extendedType, out methods))
+ {
+ methods = new List<Method>();
+ index.Add(extendedType, methods);
+ }
+ methods.Add(method);
+
+ }
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Determines whether an extension method is hidden by a member that's already defined on the type being extended.
+ /// The extension method is hidden if it has the same name, template params, and parameters as a defined method.
+ /// </summary>
+ /// <param name="extensionMethod">The extension method to compare.</param>
+ /// <param name="members">A dictionary of the members defined on the type being extended.</param>
+ /// <returns></returns>
+ private bool IsExtensionMethodHidden(Method extensionMethod, MemberDictionary members)
+ {
+ if (!members.MemberNames.Contains(extensionMethod.Name.Name))
+ return false;
+
+ // get a list of members with the same name as the extension method
+ List<Member> membersList = members[extensionMethod.Name.Name];
+ foreach (Member member in membersList)
+ {
+ // the hiding member must be a method
+ if (member.NodeType != NodeType.Method)
+ continue;
+ Method method = (Method)member;
+
+ // do the generic template parameters of both methods match?
+ if (!method.TemplateParametersMatch(extensionMethod.TemplateParameters))
+ continue;
+
+ // do both methods have the same number of parameters?
+ // (not counting the extension method's first param, which identifies the extended type)
+ if (method.Parameters.Count != (extensionMethod.Parameters.Count - 1))
+ continue;
+
+ // do the parameter types of both methods match?
+ if (DoParameterTypesMatch(extensionMethod.Parameters, method.Parameters))
+ return true;
+ }
+ return false;
+ }
+
+ private bool DoParameterTypesMatch(ParameterList extensionParams, ParameterList methodParams)
+ {
+ for (int i = 0; i < methodParams.Count; i++)
+ {
+ if (methodParams[i].Type.FullName != extensionParams[i + 1].Type.FullName)
+ return false;
+ }
+ return true;
+ }
+
+
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs b/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs
new file mode 100644
index 0000000..dcd54ad
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/GlobalSuppressions.cs
@@ -0,0 +1,81 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mref")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#ApiNamer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#.ctor(System.IO.TextWriter,Microsoft.Ddue.Tools.Reflection.ApiFilter,Microsoft.Ddue.Tools.Reflection.ApiNamer)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "namer", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#.ctor(System.IO.TextWriter,Microsoft.Ddue.Tools.Reflection.ApiNamer)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.MemberDictionary")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", Scope = "type", Target = "Microsoft.Ddue.Tools.MemberDictionary")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Type")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Contains(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "1#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#CopyTo(System.Compiler.Member[],System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Remove(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt64(System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetAppliedFields(System.Compiler.EnumNode,System.Int64)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToInt64(System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteLiteral(System.Compiler.Literal,System.Boolean)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteStartTypeReference(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetVisibility(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteEventData(System.Compiler.Event)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WritePropertyData(System.Compiler.Property)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#AssemblyNotFound(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#UnresolvedAssemblyReferenceHandler(System.Object,Microsoft.Ddue.Tools.Reflection.AssemblyReferenceEventArgs)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.LastIndexOf(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.EndsWith(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#AddAttachedMembers(System.Xml.XmlWriter,System.Object)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "index", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#CopyTo(System.Compiler.Member[],System.Int32)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#AddAttachedMembers(System.Xml.XmlWriter,System.Object)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#AllMembers")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#Item[System.String]")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "extensionMethodTemplateReturnType", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#AddExtensionMethod(System.Xml.XmlWriter,System.Compiler.TypeNode,System.Compiler.Method,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "constructor", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#IsValidTemplateArgument(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#HasExtensionAttribute(System.Compiler.Method)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#IsValidTemplateArgument(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "isSealed", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#.ctor(System.Compiler.TypeNode,Microsoft.Ddue.Tools.Reflection.ApiFilter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.ICollection`1<System.Compiler.Member>.Add(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.ICollection`1<System.Compiler.Member>.IsReadOnly")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.IEnumerable.GetEnumerator()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "Microsoft.Ddue.Tools.MemberDictionary.#System.Collections.Generic.IEnumerable`1<System.Compiler.Member>.GetEnumerator()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.MRefBuilder")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#AssemblyNotFound(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "addin", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilder.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "configuration", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilderAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "writer", Scope = "member", Target = "Microsoft.Ddue.Tools.MRefBuilderAddIn.#.ctor(Microsoft.Ddue.Tools.ManagedReflectionWriter,System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#GetParamArrayAttribute(System.Compiler.Parameter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Members")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Types")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#Namespaces")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteApiData(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteAssignment(System.Compiler.NamedArgument)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "type", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteAttributes(System.Compiler.AttributeList,System.Compiler.SecurityAttributeList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteMember(System.Compiler.Member,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "member", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteMemberContainers(System.Compiler.Member,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteNamespaces(System.Compiler.NamespaceList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "spaces", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteNamespaces(System.Compiler.NamespaceList)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.ManagedReflectionWriter.#WriteStartTypeReference(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.DxCoach.ResourceHelper.#GetStream(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.DxCoach.ResourceHelper.#GetString(System.String)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "type", Scope = "member", Target = "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn.#GetContentProperty(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.ExtensionMethodAddIn.#DoParameterTypesMatch(System.Compiler.ParameterList,System.Compiler.ParameterList)")]
diff --git a/tools/Sandcastle/ProductionTools/MRefBuilder.config b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config
index 24a3a51..2f6c5cd 100644
--- a/tools/Sandcastle/ProductionTools/MRefBuilder.config
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.config
@@ -1,12 +1,15 @@
<configuration>
<dduetools>
<platform version="2.0" path="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\" />
- <resolver type="Microsoft.Ddue.Tools.Reflection.AssemblyResolver" assembly="%DXROOT%\ProductionTools\MRefBuilder.exe" use-gac="false" />
+ <resolver type="Microsoft.Ddue.Tools.Reflection.AssemblyResolver" assembly="Reflection.dll" use-gac="false" />
<!--
<namer type="Microsoft.Ddue.Tools.Reflection.OrcasNamer" assembly="Microsoft.Ddue.Tools.Reflection.dll" />
+ -->
<addins>
<addin type="Microsoft.Ddue.Tools.XamlAttachedMembersAddIn" assembly="MRefBuilder.exe" />
+ <addin type="Microsoft.Ddue.Tools.ExtensionMethodAddIn" assembly="MRefBuilder.exe" />
</addins>
+ <!--
<apiFilter expose="true">
<namespace name="System" expose="true">
<type name="Object" expose="false">
@@ -20,6 +23,7 @@
<!-- The expections are attributes relating to data binding. Do show them. -->
<namespace name="System.ComponentModel" expose="false">
<type name="BindableAttribute" expose="true"/>
+ <type name="BrowsableAttribute" expose="true" />
<type name="ComplexBindingPropertiesAttribute" expose="true"/>
<type name="DataObjectAttribute" expose="true"/>
<type name="DefaultBindingPropertyAttribute" expose="true"/>
@@ -29,6 +33,7 @@
<type name="TypeConverterAttribute" expose="true"/>
</namespace>
<namespace name="System.ComponentModel.Design" expose="false" />
+ <namespace name="System.ComponentModel.Design.Serialization" expose="false" />
<!-- Most attributes in System.Diagnostics control debugger behavior. Don't show them. -->
<namespace name="System.Diagnostics" expose="false">
<type name="ConditionalAttribute" expose="true"/>
@@ -44,7 +49,9 @@
<type name="DefaultMemberAttribute" expose="false" />
</namespace>
<!-- Attributes in System.Runtime.CompilerServices control obscure details of compilation. Don't show them. -->
- <namespace name="System.Runtime.CompilerServices" expose="false" />
+ <namespace name="System.Runtime.CompilerServices" expose="false">
+ <type name="ExtensionAttribute" expose="true" />
+ </namespace>
<!-- Attributes in System.Runtime.ConstrinedExecution control obscure details of compilation. Don't show them. -->
<namespace name="System.Runtime.ConstrainedExecution" expose="false" />
<!-- Most atributes in System.Runtime.InteropServices control obscure details of COM interop. Don't show them. -->
@@ -58,6 +65,8 @@
<namespace name="System.Runtime.Versioning" expose="false" />
<!-- Attributes in System.Security might hint as security implementation details. Don't show them. -->
<namespace name="System.Security" expose="false">
+ <type name="SecurityCriticalAttribute" expose="true" />
+ <type name="SecurityTreatAsSafeAttribute" expose="true" />
<type name="AllowPartiallyTrustedCallersAttribute" expose="true" />
</namespace>
<!-- Attributes in System.Web.Compilation control interaction with the Expression designer. Don't show them. -->
@@ -65,6 +74,7 @@
<!-- The ASP.NET team only wants these attributes exposed from their namespace. Their logic ecscapes me, but here it is. -->
<namespace name="System.Web.UI" expose="false">
<type name="ControlValuePropertyAttribute" expose="true"/>
+ <type name="PersistenceModeAttribute" expose="true" />
<type name="ValidationPropertyAttribute" expose="true"/>
<type name="WebResourceAttribute" expose="true"/>
<type name="TemplateContainerAttribute" expose="true"/>
@@ -83,6 +93,10 @@
</namespace>
<!-- Attributes in System.Xml.Serialization control obscure details of XML serialization. Don't show them.-->
<namespace name="System.Xml.Serialization" expose="false" />
+ <!-- The GeneratedCodeAttribute is useful only to tools, and should be hidden from end users.-->
+ <namespace name="System.CodeDom.Compiler" expose="true">
+ <type name="GeneratedCodeAttribute" expose="false" />
+ </namespace>
</attributeFilter>
</dduetools>
</configuration>
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs
new file mode 100644
index 0000000..895d799
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.cs
@@ -0,0 +1,339 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using System.Xml.Xsl;
+
+using System.Compiler;
+using Microsoft.Ddue.Tools.CommandLine;
+using Microsoft.Ddue.Tools.Reflection;
+
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MRefBuilder {
+
+ public static int Main(string[] args) {
+
+ // write banner
+ ConsoleApplication.WriteBanner();
+
+ // specify options
+ OptionCollection options = new OptionCollection();
+ options.Add(new SwitchOption("?", "Show this help page."));
+ options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath"));
+ options.Add(new StringOption("config", "Specify a configuration file. If unspecified, MRefBuilder.config is used", "configFilePath"));
+ options.Add(new ListOption("dep", "Speficy assemblies to load for dependencies.", "dependencyAssembly"));
+ // options.Add( new BooleanOption("namespaces", "Control whether information on namespaces in provided.") );
+ options.Add(new BooleanOption("internal", "Specify whether to document internal as well as externally exposed APIs."));
+
+ // process options
+ ParseArgumentsResult results = options.ParseArguments(args);
+ if (results.Options["?"].IsPresent) {
+ Console.WriteLine("MRefBuilder [options] assemblies");
+ options.WriteOptionSummary(Console.Out);
+ return (0);
+ }
+
+ // check for invalid options
+ if (!results.Success) {
+ results.WriteParseErrors(Console.Out);
+ return (1);
+ }
+
+ // check for missing or extra assembly directories
+ if (results.UnusedArguments.Count < 1) {
+ Console.WriteLine("Specify at least one assembly to reflect.");
+ return (1);
+ }
+
+ // load the configuration file
+ XPathDocument config;
+ string configDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ string configFile = Path.Combine(configDirectory, "MRefBuilder.config");
+ if (results.Options["config"].IsPresent) {
+ configFile = (string)results.Options["config"].Value;
+ configDirectory = Path.GetDirectoryName(configFile);
+ }
+ try {
+ config = new XPathDocument(configFile);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to read the configuration file '{0}'. The error message is: {1}", configFile, e.Message));
+ return (1);
+ } catch (XmlException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The configuration file '{0}' is not well-formed. The error message is: {1}", configFile, e.Message));
+ return (1);
+ }
+
+ // adjust the target platform
+ XPathNodeIterator platformNodes = config.CreateNavigator().Select("/configuration/dduetools/platform");
+ if (platformNodes.MoveNext()) {
+ XPathNavigator platformNode = platformNodes.Current;
+ string version = platformNode.GetAttribute("version", String.Empty);
+ string path = platformNode.GetAttribute("path", String.Empty);
+ path = Environment.ExpandEnvironmentVariables(path);
+ if (!Directory.Exists(path)) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The specifed target platform directory '{0}' does not exist.", path));
+ return (1);
+ }
+ if (version == "2.0") {
+ TargetPlatform.SetToV2(path);
+ } else if (version == "1.1") {
+ TargetPlatform.SetToV1_1(path);
+ } else if (version == "1.0") {
+ TargetPlatform.SetToV1(path);
+ } else {
+ Console.WriteLine("Unknown target platform version '{0}'.", version);
+ return (1);
+ }
+ }
+
+ // create a namer
+ ApiNamer namer = new OrcasNamer();
+ XPathNavigator namerNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/namer");
+ if (namerNode != null) {
+ string assemblyPath = namerNode.GetAttribute("assembly", String.Empty);
+ string typeName = namerNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ namer = (ApiNamer)assembly.CreateInstance(typeName);
+
+ if (namer == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+
+ // create a resolver
+ AssemblyResolver resolver = new AssemblyResolver();
+ XPathNavigator resolverNode = config.CreateNavigator().SelectSingleNode("/configuration/dduetools/resolver");
+ if (resolverNode != null) {
+ string assemblyPath = resolverNode.GetAttribute("assembly", String.Empty);
+ string typeName = resolverNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ resolver = (AssemblyResolver)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[1] { resolverNode }, null, null);
+
+ if (resolver == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the component assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The component assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type'{0}' in the component assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the component assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the component assembly '{1}' is not a component type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+ resolver.UnresolvedAssemblyReference += new EventHandler < AssemblyReferenceEventArgs >(UnresolvedAssemblyReferenceHandler);
+
+ // get a textwriter for output
+ TextWriter output = Console.Out;
+ if (results.Options["out"].IsPresent) {
+ string file = (string)results.Options["out"].Value;
+ try {
+ output = new StreamWriter(file, false, Encoding.UTF8);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message));
+ return (1);
+ } catch (UnauthorizedAccessException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create an output file. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+
+ // dependency directory
+ string[] dependencies = new string[0];
+ if (results.Options["dep"].IsPresent) dependencies = (string[])results.Options["dep"].Value;
+
+
+ try {
+ // create a builder
+ ManagedReflectionWriter builder = new ManagedReflectionWriter(output, namer);
+
+ // specify the resolver for the builder
+ builder.Resolver = resolver;
+
+ // builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+
+ // specify the filter for the builder
+
+ if (results.Options["internal"].IsPresent && (bool)results.Options["internal"].Value) {
+ builder.ApiFilter = new AllDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+ } else {
+ builder.ApiFilter = new ExternalDocumentedFilter(config.CreateNavigator().SelectSingleNode("/configuration/dduetools"));
+ }
+
+ // register add-ins to the builder
+
+ XPathNodeIterator addinNodes = config.CreateNavigator().Select("/configuration/dduetools/addins/addin");
+ foreach (XPathNavigator addinNode in addinNodes) {
+ string assemblyPath = addinNode.GetAttribute("assembly", String.Empty);
+ string typeName = addinNode.GetAttribute("type", String.Empty);
+
+ assemblyPath = Environment.ExpandEnvironmentVariables(assemblyPath);
+ if (!Path.IsPathRooted(assemblyPath)) assemblyPath = Path.Combine(configDirectory, assemblyPath);
+
+ try {
+
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ MRefBuilderAddIn addin = (MRefBuilderAddIn)assembly.CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, null, new Object[2] { builder, addinNode }, null, null);
+
+ if (namer == null) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ }
+
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("A file access error occured while attempting to load the addin assembly '{0}'. The error message is: {1}", assemblyPath, e.Message));
+ return (1);
+ } catch (BadImageFormatException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The addin assembly '{0}' is not a valid managed assembly.", assemblyPath));
+ return (1);
+ } catch (TypeLoadException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' was not found in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (MissingMethodException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("No appropriate constructor exists for the type '{0}' in the addin assembly '{1}'.", typeName, assemblyPath));
+ return (1);
+ } catch (TargetInvocationException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while initializing the type '{0}' in the addin assembly '{1}'. The error message and stack trace follows: {2}", typeName, assemblyPath, e.InnerException.ToString()));
+ return (1);
+ } catch (InvalidCastException) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The type '{0}' in the addin assembly '{1}' is not an MRefBuilderAddIn type.", typeName, assemblyPath));
+ return (1);
+ }
+
+ }
+
+ try {
+
+
+ // add a handler for unresolved assembly references
+ //builder.UnresolvedModuleHandler = new System.Compiler.Module.AssemblyReferenceResolver(AssemblyNotFound);
+
+ // load dependent bits
+ foreach (string dependency in dependencies) {
+ try {
+ builder.LoadAccessoryAssemblies(dependency);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading dependency assemblies. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+ // parse the bits
+ foreach (string dllPath in results.UnusedArguments) {
+ try {
+ builder.LoadAssemblies(dllPath);
+ } catch (IOException e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while loading assemblies for reflection. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Loaded {0} assemblies for reflection and {1} dependency assemblies.", builder.Assemblies.Length, builder.AccessoryAssemblies.Length));
+
+ // register callbacks
+
+ //builder.RegisterStartTagCallback("apis", new MRefBuilderCallback(startTestCallback));
+
+ //MRefBuilderAddIn addin = new XamlAttachedMembersAddIn(builder, null);
+
+ builder.VisitApis();
+
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Wrote information on {0} namespaces, {1} types, and {2} members", builder.Namespaces.Length, builder.Types.Length, builder.Members.Length));
+
+ } finally {
+
+ builder.Dispose();
+ }
+
+ } finally {
+
+ // output.Close();
+
+ }
+
+ return (0);
+
+ }
+
+ private static AssemblyNode AssemblyNotFound(AssemblyReference reference, System.Compiler.Module module) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Unresolved assembly reference: {0} ({1}) required by {2}", reference.Name, reference.StrongName, module.Name));
+ Environment.Exit(1);
+ return (null);
+ }
+
+ private static void UnresolvedAssemblyReferenceHandler(Object o, AssemblyReferenceEventArgs e) {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("Unresolved assembly reference: {0} ({1}) required by {2}", e.Reference.Name, e.Reference.StrongName, e.Referrer.Name));
+ Environment.Exit(1);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj
new file mode 100644
index 0000000..b62e525
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilder.csproj
@@ -0,0 +1,113 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A8DCAD75-879F-4C97-803B-C9A17F227B04}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MrefBuilder</RootNamespace>
+ <AssemblyName>MrefBuilder</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ExtensionMethodAddIn.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="MemberDictionary.cs" />
+ <Compile Include="MRefBuilder.cs" />
+ <Compile Include="MRefBuilderAddIn.cs" />
+ <Compile Include="MRefBuilderCallback.cs" />
+ <Compile Include="MRefWriter.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ResourceHelper.cs" />
+ <Compile Include="XamlAttachedMembersAddIn.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CCI\CCI.csproj">
+ <Project>{4CB332D6-976E-44F6-A320-A515A9D1D1D3}</Project>
+ <Name>CCI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Reflection\Reflection.csproj">
+ <Project>{74F5EB3F-DC99-4FBE-9495-EE378FC60F65}</Project>
+ <Name>Reflection</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="MRefBuilder.config">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs
new file mode 100644
index 0000000..975f900
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderAddIn.cs
@@ -0,0 +1,23 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MRefBuilderAddIn {
+
+ protected MRefBuilderAddIn(ManagedReflectionWriter writer, XPathNavigator configuration) { }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs
new file mode 100644
index 0000000..0331822
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefBuilderCallback.cs
@@ -0,0 +1,19 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public delegate void MRefBuilderCallback(XmlWriter writer, object information);
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs b/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs
new file mode 100644
index 0000000..33ff1dd
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MRefWriter.cs
@@ -0,0 +1,1316 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Text;
+using System.IO;
+using System.Xml;
+
+using System.Compiler;
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+
+ // Write out information gained from managed reflection
+
+ public class ManagedReflectionWriter : ApiVisitor {
+ private const string implement = "implement";
+
+ // Implementations
+
+ private const string implements = "implements";
+
+ private Dictionary < string, Object > assemblyNames = new Dictionary < string, Object >();
+
+ // Inheritence
+
+ // Keep track of descendents
+
+ private Dictionary < TypeNode, List < TypeNode > > descendentIndex = new Dictionary < TypeNode, List < TypeNode > >();
+
+ private Dictionary < string, List < MRefBuilderCallback > > endTagCallbacks = new Dictionary < string, List < MRefBuilderCallback > >();
+
+ // Keep track of interface implementors
+
+ private Dictionary < Interface, List < TypeNode > > implementorIndex = new Dictionary < Interface, List < TypeNode > >();
+
+ // private ApiFilter memberFilter = new ExternalDocumentedFilter();
+
+ private bool includeNamespaces = true;
+
+ private ApiNamer namer;
+
+ private List < Member > parsedMembers = new List < Member >();
+
+ private List < Namespace > parsedNamespaces = new List < Namespace >();
+
+ private List < TypeNode > parsedTypes = new List < TypeNode >();
+
+ // add-in callbacks
+
+ private Dictionary < string, List < MRefBuilderCallback > > startTagCallbacks = new Dictionary < string, List < MRefBuilderCallback > >();
+
+ // Stored data
+
+ private XmlWriter writer;
+
+ // Constructor
+
+ public ManagedReflectionWriter(TextWriter output) : this(output, new ExternalTopicFilter()) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiFilter filter) : this(output, filter, new OrcasNamer()) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiNamer namer) : this(output, new ExternalTopicFilter(), namer) { }
+
+ public ManagedReflectionWriter(TextWriter output, ApiFilter filter, ApiNamer namer) : base(filter) {
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ writer = XmlWriter.Create(output, settings);
+
+ this.namer = namer;
+ }
+
+ // Exposed data
+
+ public ApiNamer ApiNamer {
+ get {
+ return (namer);
+ }
+ set {
+ namer = value;
+ }
+ }
+
+ public bool IncludeNamespaces {
+ get {
+ return (includeNamespaces);
+ }
+ set {
+ includeNamespaces = value;
+ }
+ }
+
+ public Member[] Members {
+ get {
+ return (parsedMembers.ToArray());
+ }
+ }
+
+ public Namespace[] Namespaces {
+ get {
+ return (parsedNamespaces.ToArray());
+ }
+ }
+
+
+ public TypeNode[] Types {
+ get {
+ return (parsedTypes.ToArray());
+ }
+ }
+
+ // disposal
+
+ protected override void Dispose(bool disposing) {
+ if (disposing) {
+ writer.Close();
+ }
+ base.Dispose(disposing);
+ }
+
+ public void RegisterEndTagCallback(string name, MRefBuilderCallback callback) {
+ List < MRefBuilderCallback > current;
+ if (!endTagCallbacks.TryGetValue(name, out current)) {
+ current = new List < MRefBuilderCallback >();
+ endTagCallbacks.Add(name, current);
+ }
+ current.Add(callback);
+ }
+
+ public void RegisterStartTagCallback(string name, MRefBuilderCallback callback) {
+ List < MRefBuilderCallback > current;
+ if (!startTagCallbacks.TryGetValue(name, out current)) {
+ current = new List < MRefBuilderCallback >();
+ startTagCallbacks.Add(name, current);
+ }
+ current.Add(callback);
+ }
+
+ public void WriteMember(Member member) {
+ //Console.WriteLine("Write Member {0} [{1}]", member.FullName, member.DeclaringType.DeclaringModule.Name);
+ WriteMember(member, member.DeclaringType);
+ }
+
+ public void WriteMemberReference(Member member) {
+ if (member == null) throw new ArgumentNullException("member");
+ writer.WriteStartElement("member");
+ Member template = ReflectionUtilities.GetTemplateMember(member);
+ writer.WriteAttributeString("api", namer.GetMemberName(template));
+ if (!member.DeclaringType.IsStructurallyEquivalentTo(template.DeclaringType)) {
+ writer.WriteAttributeString("display-api", namer.GetMemberName(member));
+ }
+ WriteTypeReference(member.DeclaringType);
+ writer.WriteEndElement();
+ }
+
+ public void WriteTypeReference(TypeNode type) {
+ if (type == null) throw new ArgumentNullException("type");
+ WriteStartTypeReference(type);
+ writer.WriteEndElement();
+ }
+
+ protected override void VisitMember(Member member) {
+ //Console.WriteLine("Member: {0}", member.Name);
+ parsedMembers.Add(member);
+
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetMemberName(member));
+ StartElementCallbacks("api", member);
+ WriteMember(member);
+ EndElementCallbacks("api", member);
+ writer.WriteEndElement();
+ }
+
+ protected override void VisitNamespace(Namespace space) {
+ parsedNamespaces.Add(space);
+ WriteNamespace(space);
+ base.VisitNamespace(space);
+ }
+
+ // visitation logic
+
+ protected override void VisitNamespaces(NamespaceList spaces) {
+
+ // construct a sorted assembly catalog
+ foreach (AssemblyNode assembly in this.Assemblies) {
+ assemblyNames.Add(assembly.StrongName, null);
+ }
+
+ // catalog type hierarchy and interface implementors
+ for (int i = 0; i < spaces.Count; i++) {
+ TypeNodeList types = spaces[i].Types;
+ for (int j = 0; j < types.Count; j++) {
+ TypeNode type = types[j];
+ if (ApiFilter.IsExposedType(type)) {
+ if (type.NodeType == NodeType.Class) PopulateDescendentIndex(type);
+ PopulateImplementorIndex(type);
+ }
+ }
+ }
+
+ // start the document
+ writer.WriteStartDocument();
+ writer.WriteStartElement("reflection");
+
+ // write assembly info
+ writer.WriteStartElement("assemblies");
+ foreach (AssemblyNode assembly in this.Assemblies) {
+ WriteAssembly(assembly);
+ }
+ writer.WriteEndElement();
+
+ // start api info
+ writer.WriteStartElement("apis");
+ StartElementCallbacks("apis", spaces);
+
+ // write it
+ WriteNamespaces(spaces);
+ base.VisitNamespaces(spaces);
+
+ // finish api info
+ EndElementCallbacks("apis", spaces);
+ writer.WriteEndElement();
+
+ // finish document
+ writer.WriteEndElement();
+ writer.WriteEndDocument();
+
+ }
+
+ protected override void VisitType(TypeNode type) {
+ //Console.WriteLine("Type: {0}", type.FullName);
+ parsedTypes.Add(type);
+ WriteType(type);
+ base.VisitType(type);
+ }
+
+ // Attributes
+
+ protected void WriteAttributes(AttributeList attributes, SecurityAttributeList securityAttributes) {
+ AttributeNode[] exposed = GetExposedAttributes(attributes, securityAttributes);
+ if (exposed.Length == 0) return;
+ writer.WriteStartElement("attributes");
+ for (int i = 0; i < exposed.Length; i++) {
+ AttributeNode attribute = exposed[i];
+ writer.WriteStartElement("attribute");
+
+ TypeNode type = attribute.Type;
+ WriteTypeReference(attribute.Type);
+ // WriteStringAttribute("type", namer.GetApiName(attribute.Type));
+
+ ExpressionList expressions = attribute.Expressions;
+ for (int j = 0; j < expressions.Count; j++) {
+ WriteExpression(expressions[j]);
+ }
+
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ }
+
+ protected void WriteExpression(Expression expression) {
+ if (expression.NodeType == NodeType.Literal) {
+ Literal argument = (Literal)expression;
+ writer.WriteStartElement("argument");
+ WriteLiteral(argument);
+ writer.WriteEndElement();
+ } else if (expression.NodeType == NodeType.NamedArgument) {
+ NamedArgument assignment = (NamedArgument)expression;
+ Literal value = (Literal)assignment.Value;
+ writer.WriteStartElement("assignment");
+ WriteStringAttribute("name", assignment.Name.Name);
+ WriteLiteral(value);
+ writer.WriteEndElement();
+ }
+ }
+
+ private static FieldList GetAppliedFields(EnumNode enumeration, long value) {
+ // if a single field matches, return it;
+ // otherwise return all fields that are in value
+ FieldList list = new FieldList();
+ MemberList members = enumeration.Members;
+ for (int i = 0; i < members.Count; i++) {
+ if (members[i].NodeType != NodeType.Field) continue;
+ Field field = (Field)members[i];
+ if (field.DefaultValue == null) continue;
+ long fieldValue = Convert.ToInt64(field.DefaultValue.Value);
+ if (fieldValue == value) {
+ return (new FieldList(new Field[1] { field }));
+ } else if ((fieldValue & value) == fieldValue) {
+ list.Add(field);
+ }
+ }
+ return (list);
+ }
+
+ // Static utility functions
+
+ private static Namespace GetNamespace(TypeNode type) {
+ if (type.DeclaringType != null) {
+ return (GetNamespace(type.DeclaringType));
+ } else {
+ return (new Namespace(type.Namespace));
+ }
+ }
+
+ private static string GetVisibility(Member api) {
+ if (api == null) throw new ArgumentNullException("api");
+ if (api.IsPublic) {
+ return ("public");
+ } else if (api.IsAssembly) {
+ return ("assembly");
+ } else if (api.IsFamilyOrAssembly) {
+ return ("family or assembly");
+ } else if (api.IsFamily) {
+ return ("family");
+ } else if (api.IsFamilyAndAssembly) {
+ return ("family and assembly");
+ } else if (api.IsPrivate) {
+ return ("private");
+ } else {
+ throw new InvalidOperationException(String.Format("Unknown access level for {0}", api.FullName));
+ }
+ }
+
+ private static bool IsValidXmlChar(char c) {
+ if (c < 0x20) {
+ return ((c == 0x9) || (c == 0xa));
+ } else {
+ return ((c <= 0xd7ff) || ((0xe000 <= c) && (c <= 0xfffd)));
+ }
+ }
+
+ private static bool IsValidXmlText(string text) {
+ foreach (char c in text) {
+ if (!IsValidXmlChar(c)) return (false);
+ }
+ return (true);
+ }
+
+ private void EndElementCallbacks(string name, Object info) {
+ List < MRefBuilderCallback > callbacks;
+ if (endTagCallbacks.TryGetValue(name, out callbacks)) {
+ foreach (MRefBuilderCallback callback in callbacks) callback.Invoke(writer, info);
+ }
+ }
+
+ private AttributeNode[] GetExposedAttributes(AttributeList attributes, SecurityAttributeList securityAttributes) {
+ if (attributes == null) Console.WriteLine("null attribute list");
+ if (securityAttributes == null) Console.WriteLine("null security attribute list");
+ List < AttributeNode > exposedAttributes = new List < AttributeNode >();
+ for (int i = 0; i < attributes.Count; i++) {
+ AttributeNode attribute = attributes[i];
+ if (attribute == null) Console.WriteLine("null attribute");
+ if (this.ApiFilter.IsExposedAttribute(attribute)) exposedAttributes.Add(attribute);
+ }
+ for (int i = 0; i < securityAttributes.Count; i++) {
+ SecurityAttribute securityAttribute = securityAttributes[i];
+ if (securityAttribute == null) Console.WriteLine("null security attribute");
+ AttributeList permissionAttributes = securityAttribute.PermissionAttributes;
+ //if (permissionAttributes == null) Console.WriteLine("null permission attribute list");
+ if (permissionAttributes == null) continue;
+ for (int j = 0; j < permissionAttributes.Count; j++) {
+ AttributeNode permissionAttribute = permissionAttributes[j];
+ //if (permissionAttribute == null) Console.WriteLine("null permission attribute");
+ // saw an example where this was null; ildasm shows no permission attribute, so skip it
+ if (permissionAttribute == null) continue;
+ if (this.ApiFilter.IsExposedAttribute(permissionAttribute)) exposedAttributes.Add(permissionAttribute);
+ }
+ }
+ return (exposedAttributes.ToArray());
+ }
+
+ private Member[] GetExposedImplementedMembers(IEnumerable < Member > members) {
+ List < Member > exposedImplementedMembers = new List < Member >();
+ foreach (Member member in members) {
+ if (this.ApiFilter.IsExposedMember(member)) {
+ exposedImplementedMembers.Add(member);
+ }
+ }
+ return (exposedImplementedMembers.ToArray());
+ }
+
+ private Interface[] GetExposedInterfaces(InterfaceList contracts) {
+ List < Interface > exposedContracts = new List < Interface >();
+ for (int i = 0; i < contracts.Count; i++) {
+ Interface contract = contracts[i];
+ if (this.ApiFilter.IsExposedType(contract)) {
+ // if generic, check whether specialization types are exposed
+ exposedContracts.Add(contract);
+ }
+ }
+ return (exposedContracts.ToArray());
+ }
+
+ private AttributeNode GetParamArrayAttribute(Parameter param)
+ {
+ AttributeList attributes = param.Attributes;
+ for (int i = 0, n = attributes == null ? 0 : attributes.Count; i < n; i++)
+ {
+ AttributeNode attr = attributes[i];
+ if (attr == null) continue;
+ if (attr.Type.FullName == "System.ParamArrayAttribute")
+ return attr;
+ }
+ return null;
+ }
+
+ private void PopulateDescendentIndex(TypeNode child) {
+
+ // get the parent of the type in question
+ TypeNode parent = child.BaseType;
+ if (parent == null) return;
+
+ // un-specialize the parent so we see specialized types as children
+ parent = ReflectionUtilities.GetTemplateType(parent);
+
+ // get the list of children for that parent (i.e. the sibling list)
+ List < TypeNode > siblings;
+ if (!descendentIndex.TryGetValue(parent, out siblings)) {
+ siblings = new List < TypeNode >();
+ descendentIndex[parent] = siblings;
+ }
+
+ // add the type in question to the sibling list
+ siblings.Add(child);
+
+ }
+
+ private void PopulateImplementorIndex(TypeNode type) {
+
+ // get the list of interfaces exposed by the type
+ Interface[] contracts = GetExposedInterfaces(type.Interfaces);
+
+ // for each implemented interface...
+ for (int i = 0; i < contracts.Length; i++) {
+
+ // get the unspecialized form of the interface
+ Interface contract = contracts[i];
+ if (contract.IsGeneric) contract = (Interface)ReflectionUtilities.GetTemplateType(contract);
+
+ // get the list of implementors
+ List < TypeNode > implementors;
+ if (!implementorIndex.TryGetValue(contract, out implementors)) {
+ implementors = new List < TypeNode >();
+ implementorIndex[contract] = implementors;
+ }
+
+ // and add the type to it
+ implementors.Add(type);
+ }
+ }
+
+ private void StartElementCallbacks(string name, Object info) {
+ List < MRefBuilderCallback > callbacks;
+ if (startTagCallbacks.TryGetValue(name, out callbacks)) {
+ foreach (MRefBuilderCallback callback in callbacks) callback.Invoke(writer, info);
+ }
+ }
+
+
+ // API data for all entities
+
+ private void WriteApiData(Member api) {
+ writer.WriteStartElement("apidata");
+
+ string name = api.Name.Name;
+
+ string group = null;
+ string subgroup = null;
+ string subsubgroup = null;
+
+ if (api.NodeType == NodeType.Namespace) {
+ group = "namespace";
+ } else if (api is TypeNode) {
+ group = "type";
+
+ TypeNode type = (TypeNode)api;
+ name = type.GetUnmangledNameWithoutTypeParameters();
+
+ switch (api.NodeType) {
+ case NodeType.Class:
+ subgroup = "class";
+ break;
+ case NodeType.Struct:
+ subgroup = "structure";
+ break;
+ case NodeType.Interface:
+ subgroup = "interface";
+ break;
+ case NodeType.EnumNode:
+ subgroup = "enumeration";
+ break;
+ case NodeType.DelegateNode:
+ subgroup = "delegate";
+ break;
+ }
+ } else {
+ group = "member";
+
+ switch (api.NodeType) {
+ case NodeType.Field:
+ subgroup = "field";
+ break;
+ case NodeType.Property:
+ subgroup = "property";
+ break;
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ subgroup = "constructor";
+ // name = api.DeclaringType.GetUnmangledNameWithoutTypeParameters();
+ break;
+ case NodeType.Method:
+ subgroup = "method";
+ if ((api.IsSpecialName) && (name.StartsWith("op_"))) {
+ subsubgroup = "operator";
+ name = name.Substring(3);
+ }
+ break;
+ case NodeType.Event:
+ subgroup = "event";
+ break;
+ }
+
+ // Name of EIIs is just interface member name
+ int dotIndex = name.LastIndexOf(".");
+ if (dotIndex > 0) name = name.Substring(dotIndex + 1);
+
+ }
+
+
+ WriteStringAttribute("name", name);
+ WriteStringAttribute("group", group);
+ if (subgroup != null) WriteStringAttribute("subgroup", subgroup);
+ if (subsubgroup != null) WriteStringAttribute("subsubgroup", subsubgroup);
+
+ StartElementCallbacks("apidata", api);
+
+ // WriteStringAttribute("file", GetGuid(namer.GetApiName(api)).ToString());
+
+ EndElementCallbacks("apidata", api);
+ writer.WriteEndElement();
+ }
+
+ // writing logic
+
+ private void WriteAssembly(AssemblyNode assembly) {
+ // if (assembly == null) Console.WriteLine("null assembly");
+ // Console.WriteLine("assembly: {0}", assembly.Name);
+ writer.WriteStartElement("assembly");
+ // if (assembly.Name == null) Console.WriteLine("null assembly name");
+ WriteStringAttribute("name", assembly.Name);
+ // if (assembly.Version == null) Console.WriteLine("null assembly version");
+
+ // basic assembly data
+ writer.WriteStartElement("assemblydata");
+ WriteStringAttribute("version", assembly.Version.ToString());
+ WriteStringAttribute("culture", assembly.Culture.ToString());
+ byte[] key = assembly.PublicKeyOrToken;
+ writer.WriteStartAttribute("key");
+ writer.WriteBinHex(key, 0, key.Length);
+ writer.WriteEndAttribute();
+ WriteStringAttribute("hash", assembly.HashAlgorithm.ToString());
+ writer.WriteEndElement();
+
+ // assembly attribute data
+ WriteAttributes(assembly.Attributes, assembly.SecurityAttributes);
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteAssignment(NamedArgument assignment) {
+ string name = assignment.Name.Name;
+ Literal value = (Literal)assignment.Value;
+ writer.WriteStartElement("assignment");
+ WriteStringAttribute("name", name);
+ WriteLiteral(value);
+ writer.WriteEndElement();
+ }
+
+ // utilities used to write attributes
+
+ private void WriteBooleanAttribute(string attribute, bool value) {
+ if (value) {
+ writer.WriteAttributeString(attribute, "true");
+ } else {
+ writer.WriteAttributeString(attribute, "false");
+ }
+ }
+
+ private void WriteBooleanAttribute(string attribute, bool value, bool defaultValue) {
+ if (value != defaultValue) {
+ WriteBooleanAttribute(attribute, value);
+ }
+ }
+
+ private void WriteEnumerationData(EnumNode enumeration) {
+ TypeNode underlying = enumeration.UnderlyingType;
+ if (underlying.FullName != "System.Int32") {
+ writer.WriteStartElement("enumerationbase");
+ WriteTypeReference(enumeration.UnderlyingType);
+ writer.WriteEndElement();
+ }
+ }
+
+ private void WriteEventData(Event trigger) {
+
+ Method adder = trigger.HandlerAdder;
+ Method remover = trigger.HandlerRemover;
+ Method caller = trigger.HandlerCaller;
+
+ WriteProcedureData(adder, trigger.OverriddenMember);
+
+ writer.WriteStartElement("eventdata");
+ if (adder != null) WriteBooleanAttribute("add", true);
+ if (remover != null) WriteBooleanAttribute("remove", true);
+ if (caller != null) WriteBooleanAttribute("call", true);
+ writer.WriteEndElement();
+
+ if (adder != null)
+ {
+ writer.WriteStartElement("adder");
+ WriteStringAttribute("name", string.Format("add_{0}", trigger.Name.Name));
+
+ WriteAttributes(adder.Attributes, adder.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ if (remover != null)
+ {
+ writer.WriteStartElement("remover");
+ WriteStringAttribute("name", string.Format("remove_{0}", trigger.Name.Name));
+
+ WriteAttributes(remover.Attributes, remover.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteStartElement("eventhandler");
+ WriteTypeReference(trigger.HandlerType);
+ writer.WriteEndElement();
+
+ // handlers should always be elegates, but I have seen a case where one is not, so check for this
+ DelegateNode handler = trigger.HandlerType as DelegateNode;
+ if (handler != null) {
+ ParameterList parameters = handler.Parameters;
+
+ if ((parameters != null) && (parameters.Count == 2) && (parameters[0].Type.FullName == "System.Object")) {
+ writer.WriteStartElement("eventargs");
+ WriteTypeReference(parameters[1].Type);
+ writer.WriteEndElement();
+ }
+ }
+
+ }
+
+
+ private void WriteFieldData(Field field) {
+ writer.WriteStartElement("fielddata");
+ WriteBooleanAttribute("literal", field.IsLiteral);
+ WriteBooleanAttribute("initonly", field.IsInitOnly);
+ WriteBooleanAttribute("volatile", field.IsVolatile, false);
+ WriteBooleanAttribute("serialized", (field.Flags & FieldFlags.NotSerialized) == 0);
+ writer.WriteEndElement();
+ }
+
+ private void WriteGenericParameter(TypeNode templateParameter)
+ {
+
+ ITypeParameter itp = (ITypeParameter)templateParameter;
+
+ writer.WriteStartElement("template");
+ writer.WriteAttributeString("name", templateParameter.Name.Name);
+
+ // evaluate constraints
+ bool reference = ((itp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) > 0);
+ bool value = ((itp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) > 0);
+ bool constructor = ((itp.TypeParameterFlags & TypeParameterFlags.DefaultConstructorConstraint) > 0);
+ bool contravariant = ((itp.TypeParameterFlags & TypeParameterFlags.Contravariant) > 0);
+ bool covariant = ((itp.TypeParameterFlags & TypeParameterFlags.Covariant) > 0);
+ InterfaceList interfaces = templateParameter.Interfaces;
+ TypeNode parent = templateParameter.BaseType;
+
+ // no need to show inheritance from ValueType if value flag is set
+ if (value && (parent != null) && (parent.FullName == "System.ValueType")) parent = null;
+
+ if ((parent != null) || (interfaces.Count > 0) || reference || value || constructor)
+ {
+ writer.WriteStartElement("constrained");
+ if (reference) WriteBooleanAttribute("ref", true);
+ if (value) WriteBooleanAttribute("value", true);
+ if (constructor) WriteBooleanAttribute("ctor", true);
+ if (parent != null) WriteTypeReference(parent);
+ WriteInterfaces(interfaces);
+ writer.WriteEndElement();
+ }
+ if (covariant || contravariant)
+ {
+ writer.WriteStartElement("variance");
+ if (contravariant) WriteBooleanAttribute("contravariant", true);
+ if (covariant) WriteBooleanAttribute("covariant", true);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+ }
+
+ private void WriteSpecializedTemplateArguments(TypeNodeList templateArguments)
+ {
+ if (templateArguments == null) return;
+ if (templateArguments.Count == 0) return;
+ writer.WriteStartElement("templates");
+ for (int i = 0; i < templateArguments.Count; i++)
+ {
+ WriteTypeReference(templateArguments[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ // Generic Parameters
+
+ private void WriteGenericParameters(TypeNodeList templateParameters)
+ {
+ if (templateParameters == null) return;
+ if (templateParameters.Count == 0) return;
+ writer.WriteStartElement("templates");
+ for (int i = 0; i < templateParameters.Count; i++)
+ {
+ WriteGenericParameter(templateParameters[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteHierarchy(TypeNode type) {
+
+ writer.WriteStartElement("family");
+
+ // write ancestors
+ writer.WriteStartElement("ancestors");
+ for (TypeNode ancestor = type.BaseType; ancestor != null; ancestor = ancestor.BaseType) {
+ WriteTypeReference(ancestor);
+ }
+ writer.WriteEndElement();
+
+ // write descendents
+ if (descendentIndex.ContainsKey(type)) {
+ List < TypeNode > descendents = descendentIndex[type];
+ writer.WriteStartElement("descendents");
+ foreach (TypeNode descendent in descendents) WriteTypeReference(descendent);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+
+ }
+
+ private void WriteImplementedMembers(Member[] members) {
+ if ((members == null) || (members.Length == 0)) return;
+ Member[] exposedMembers = GetExposedImplementedMembers(members);
+ if ((exposedMembers == null) || (exposedMembers.Length == 0)) return;
+ writer.WriteStartElement(implements);
+ for (int i = 0; i < exposedMembers.Length; i++) {
+ Member member = exposedMembers[i];
+ //TypeNode type = member.DeclaringType;
+
+ WriteMemberReference(member);
+
+ }
+ writer.WriteEndElement();
+ }
+
+ // Interfaces
+
+ private void WriteImplementors(Interface contract) {
+ List < TypeNode > implementors;
+ if (!implementorIndex.TryGetValue(contract, out implementors)) return;
+ if ((implementors == null) || (implementors.Count == 0)) return;
+ writer.WriteStartElement("implementors");
+ StartElementCallbacks("implementors", implementors);
+ foreach (TypeNode implementor in implementors) {
+ WriteTypeReference(implementor);
+ }
+ writer.WriteEndElement();
+ EndElementCallbacks("implementors", implementors);
+ }
+
+ private void WriteInterface(Interface contract) {
+ // writer.WriteStartElement("implement");
+ WriteTypeReference(contract);
+ // writer.WriteAttributeString("interface", namer.GetTypeName(contract));
+ // writer.WriteEndElement();
+ }
+
+ private void WriteInterfaces(InterfaceList contracts) {
+ Interface[] implementedContracts = GetExposedInterfaces(contracts);
+ if (implementedContracts.Length == 0) return;
+ writer.WriteStartElement("implements");
+ StartElementCallbacks("implements", implementedContracts);
+ for (int i = 0; i < implementedContracts.Length; i++) {
+ WriteInterface(implementedContracts[i]);
+ }
+ writer.WriteEndElement();
+ EndElementCallbacks("implements", implementedContracts);
+ }
+
+ private void WriteLibraryReference(Module module) {
+ AssemblyNode assembly = module.ContainingAssembly;
+ writer.WriteStartElement("library");
+ WriteStringAttribute("assembly", assembly.Name);
+ WriteStringAttribute("module", module.Name);
+ WriteStringAttribute("kind", module.Kind.ToString());
+ writer.WriteEndElement();
+ }
+
+ private void WriteLiteral(Literal literal) {
+ WriteLiteral(literal, true);
+ }
+
+ private void WriteLiteral(Literal literal, bool showType) {
+ TypeNode type = literal.Type;
+ Object value = literal.Value;
+ if (showType) WriteTypeReference(type);
+ if (value == null) {
+ writer.WriteElementString("nullValue", String.Empty);
+ } else {
+ if (type.NodeType == NodeType.EnumNode) {
+ EnumNode enumeration = (EnumNode)type;
+ FieldList fields = GetAppliedFields(enumeration, Convert.ToInt64(value));
+ writer.WriteStartElement("enumValue");
+ for (int i = 0; i < fields.Count; i++) {
+ writer.WriteStartElement("field");
+ writer.WriteAttributeString("name", fields[i].Name.Name);
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ } else if (type.FullName == "System.Type") {
+ writer.WriteStartElement("typeValue");
+ WriteTypeReference((TypeNode)value);
+ writer.WriteEndElement();
+ } else {
+ string text = value.ToString();
+ if (!IsValidXmlText(text)) text = String.Empty;
+ writer.WriteElementString("value", text);
+ }
+ }
+ }
+
+
+ private void WriteMember(Member member, TypeNode type) {
+ //writer.WriteStartElement("api");
+ //writer.WriteAttributeString("id", namer.GetMemberName(member));
+ //Console.WriteLine("member: {0}", namer.GetMemberName(member));
+
+ WriteApiData(member);
+ WriteMemberData(member);
+
+ SecurityAttributeList securityAttributes = new SecurityAttributeList();
+ switch (member.NodeType) {
+ case NodeType.Field:
+ Field field = (Field)member;
+ WriteFieldData(field);
+ WriteValue(field.Type);
+ // write enumeration field values; expand later to all literal field values?
+ if (field.DeclaringType.NodeType == NodeType.EnumNode) {
+ WriteLiteral(new Literal(field.DefaultValue.Value, ((EnumNode)field.DeclaringType).UnderlyingType), false);
+ }
+ break;
+ case NodeType.Method:
+ Method method = (Method)member;
+ WriteMethodData(method);
+
+ // write the templates node with either the generic template params or the specialized template arguments
+ if (method.TemplateArguments != null)
+ WriteSpecializedTemplateArguments(method.TemplateArguments);
+ else
+ WriteGenericParameters(method.TemplateParameters);
+
+ WriteParameters(method.Parameters);
+ WriteValue(method.ReturnType);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedMethods(method));
+
+ if (method.SecurityAttributes != null) securityAttributes = method.SecurityAttributes;
+ break;
+ case NodeType.Property:
+ Property property = (Property)member;
+ WritePropertyData(property);
+ WriteParameters(property.Parameters);
+ WriteValue(property.Type);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedProperties(property));
+ break;
+ case NodeType.Event:
+ Event trigger = (Event)member;
+ WriteEventData(trigger);
+ WriteImplementedMembers(ReflectionUtilities.GetImplementedEvents(trigger));
+ break;
+ case NodeType.InstanceInitializer:
+ case NodeType.StaticInitializer:
+ Method constructor = (Method)member;
+ WriteParameters(constructor.Parameters);
+ break;
+
+ }
+
+ WriteMemberContainers(member, type);
+
+ WriteAttributes(member.Attributes, securityAttributes);
+
+ //writer.WriteEndElement();
+ }
+
+ private void WriteMemberContainers(Member member, TypeNode type) {
+ writer.WriteStartElement("containers");
+ WriteLibraryReference(type.DeclaringModule);
+ WriteNamespaceReference(GetNamespace(type));
+ WriteTypeReference(type);
+ writer.WriteEndElement();
+ }
+
+ // Member data
+
+ private void WriteMemberData(Member member) {
+
+ writer.WriteStartElement("memberdata");
+
+ WriteStringAttribute("visibility", GetVisibility(member));
+ WriteBooleanAttribute("static", member.IsStatic, false);
+ WriteBooleanAttribute("special", member.IsSpecialName, false);
+
+ // check overload status
+ // don't do this anymore: overload is a doc model concept and may be need to be tweaked afer versioning
+
+ WriteBooleanAttribute("default", ReflectionUtilities.IsDefaultMember(member), false);
+
+ StartElementCallbacks("memberdata", member);
+
+ EndElementCallbacks("memberdata", member);
+ writer.WriteEndElement();
+ }
+
+ private void WriteMethodData(Method method) {
+
+ WriteProcedureData(method, method.OverriddenMember);
+
+ // writer.WriteStartElement("methoddata");
+ // writer.WriteEndElement();
+ }
+
+ private void WriteNamespace(Namespace space) {
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetNamespaceName(space));
+ StartElementCallbacks("api", space);
+
+ WriteApiData(space);
+ WriteNamespaceElements(space);
+
+ EndElementCallbacks("api", space);
+ writer.WriteEndElement();
+ }
+
+ // Members
+
+ private void WriteNamespaceElements(Namespace space) {
+ TypeNodeList types = space.Types;
+ if (types.Count == 0) return;
+ writer.WriteStartElement("elements");
+ for (int i = 0; i < types.Count; i++) {
+ TypeNode type = types[i];
+ //skip hidden types, but if a type is not exposed and has exposed members we must add it
+ if (!ApiFilter.IsExposedType(type) && !ApiFilter.HasExposedMembers(type)) continue;
+ writer.WriteStartElement("element");
+ writer.WriteAttributeString("api", namer.GetTypeName(type));
+ writer.WriteEndElement();
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteNamespaceReference(Namespace space) {
+ writer.WriteStartElement("namespace");
+ writer.WriteAttributeString("api", namer.GetNamespaceName(space));
+ writer.WriteEndElement();
+ }
+
+ private void WriteNamespaces(NamespaceList spaces) {
+ // This is a part of the doc model; don't do this anymore
+ }
+
+ private void WriteParameter(Parameter parameter) {
+ writer.WriteStartElement("parameter");
+ writer.WriteAttributeString("name", parameter.Name.Name);
+ // writer.WriteAttributeString("type", namer.GetTypeName(parameter.Type));
+ if (parameter.IsIn) WriteBooleanAttribute("in", true);
+ if (parameter.IsOut) WriteBooleanAttribute("out", true);
+ if (GetParamArrayAttribute(parameter) != null) WriteBooleanAttribute("params", true);
+ WriteTypeReference(parameter.Type);
+ if (parameter.IsOptional && parameter.DefaultValue != null) WriteExpression(parameter.DefaultValue);
+ writer.WriteEndElement();
+ }
+
+ // Parameters
+
+ private void WriteParameters(ParameterList parameters) {
+ if (parameters.Count == 0) return;
+ writer.WriteStartElement("parameters");
+ for (int i = 0; i < parameters.Count; i++) {
+ WriteParameter(parameters[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ private void WriteProcedureData(Method method, Member overrides) {
+ writer.WriteStartElement("proceduredata");
+
+ WriteBooleanAttribute("abstract", method.IsAbstract, false);
+ WriteBooleanAttribute("virtual", method.IsVirtual);
+ WriteBooleanAttribute("final", method.IsFinal, false);
+
+ if (method.IsPrivate && method.IsVirtual) WriteBooleanAttribute("eii", true);
+
+ writer.WriteEndElement();
+
+ if (overrides != null) {
+ writer.WriteStartElement("overrides");
+ WriteMemberReference(overrides);
+ // WriteStringAttribute("overrides", namer.GetMemberName(overrides));
+ writer.WriteEndElement();
+ }
+
+ }
+
+ private void WritePropertyData(Property property) {
+
+ string property_visibility = GetVisibility(property);
+
+ Method getter = property.Getter;
+ Method setter = property.Setter;
+
+ Method accessor = getter;
+ if (accessor == null) accessor = setter;
+
+ // procedure data
+ WriteProcedureData(accessor, property.OverriddenMember);
+
+ // property data
+ writer.WriteStartElement("propertydata");
+ if (getter != null) {
+ WriteBooleanAttribute("get", true);
+ string getter_visibility = GetVisibility(getter);
+
+ if (getter_visibility != property_visibility) WriteStringAttribute("get-visibility", getter_visibility);
+ }
+ if (setter != null) {
+ WriteBooleanAttribute("set", true);
+ string setter_visibility = GetVisibility(setter);
+ if (setter_visibility != property_visibility) WriteStringAttribute("set-visibility", setter_visibility);
+ }
+ writer.WriteEndElement();
+
+ if (getter != null)
+ {
+ writer.WriteStartElement("getter");
+ WriteStringAttribute("name", string.Format("get_{0}", property.Name.Name));
+
+ WriteAttributes(getter.Attributes, getter.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ if (setter != null)
+ {
+ writer.WriteStartElement("setter");
+ WriteStringAttribute("name", string.Format("set_{0}", property.Name.Name.ToString()));
+
+ WriteAttributes(setter.Attributes, setter.SecurityAttributes);
+ writer.WriteEndElement();
+ }
+ }
+
+ private void WriteStartTypeReference(TypeNode type) {
+ switch (type.NodeType) {
+ case NodeType.ArrayType:
+ ArrayType array = type as ArrayType;
+ writer.WriteStartElement("arrayOf");
+ writer.WriteAttributeString("rank", array.Rank.ToString());
+ WriteTypeReference(array.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.Reference:
+ Reference reference = type as Reference;
+ writer.WriteStartElement("referenceTo");
+ WriteTypeReference(reference.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.Pointer:
+ Pointer pointer = type as Pointer;
+ writer.WriteStartElement("pointerTo");
+ WriteTypeReference(pointer.ElementType);
+ // writer.WriteEndElement();
+ break;
+ case NodeType.OptionalModifier:
+ TypeModifier optionalModifierClause = type as TypeModifier;
+ WriteStartTypeReference(optionalModifierClause.ModifiedType);
+ writer.WriteStartElement("optionalModifier");
+ WriteTypeReference(optionalModifierClause.Modifier);
+ writer.WriteEndElement();
+ break;
+ case NodeType.RequiredModifier:
+ TypeModifier requiredModifierClause = type as TypeModifier;
+ WriteStartTypeReference(requiredModifierClause.ModifiedType);
+ writer.WriteStartElement("requiredModifier");
+ WriteTypeReference(requiredModifierClause.Modifier);
+ writer.WriteEndElement();
+ break;
+ default:
+ if (type.IsTemplateParameter) {
+ ITypeParameter gtp = (ITypeParameter)type;
+ writer.WriteStartElement("template");
+ writer.WriteAttributeString("name", type.Name.Name);
+ writer.WriteAttributeString("index", gtp.ParameterListIndex.ToString());
+ writer.WriteAttributeString("api", namer.GetApiName(gtp.DeclaringMember));
+ // writer.WriteEndElement();
+ } else {
+ writer.WriteStartElement("type");
+
+ if (type.IsGeneric) {
+ TypeNode template = ReflectionUtilities.GetTemplateType(type);
+ writer.WriteAttributeString("api", namer.GetTypeName(template));
+ WriteBooleanAttribute("ref", !template.IsValueType);
+
+ // record specialization
+ TypeNodeList arguments = type.TemplateArguments;
+ if ((arguments != null) && (arguments.Count > 0)) {
+ writer.WriteStartElement("specialization");
+ // writer.WriteAttributeString("of", namer.GetTypeName(currentTemplate));
+ for (int i = 0; i < arguments.Count; i++) {
+ WriteTypeReference(arguments[i]);
+ }
+ writer.WriteEndElement();
+ }
+
+ } else {
+ writer.WriteAttributeString("api", namer.GetTypeName(type));
+ WriteBooleanAttribute("ref", !type.IsValueType);
+ }
+
+ // record outer types (because they may be specialized, and otherwise that information is lost)
+ if (type.DeclaringType != null) WriteTypeReference(type.DeclaringType);
+
+ }
+ break;
+ }
+ }
+
+ private void WriteStringAttribute(string attribute, string value) {
+ writer.WriteAttributeString(attribute, value);
+ }
+
+ private void WriteType(TypeNode type) {
+ writer.WriteStartElement("api");
+ writer.WriteAttributeString("id", namer.GetTypeName(type));
+ StartElementCallbacks("api", type);
+
+ WriteApiData(type);
+ WriteTypeData(type);
+
+ switch (type.NodeType) {
+ case NodeType.Class:
+ case NodeType.Struct:
+ WriteGenericParameters(type.TemplateParameters);
+ WriteInterfaces(type.Interfaces);
+ WriteTypeElements(type);
+ break;
+ case NodeType.Interface:
+ WriteGenericParameters(type.TemplateParameters);
+ WriteInterfaces(type.Interfaces);
+ WriteImplementors((Interface)type);
+ WriteTypeElements(type);
+ break;
+ case NodeType.DelegateNode:
+ DelegateNode handler = (DelegateNode)type;
+ WriteGenericParameters(handler.TemplateParameters);
+ WriteParameters(handler.Parameters);
+ WriteValue(handler.ReturnType);
+ break;
+ case NodeType.EnumNode:
+ WriteEnumerationData((EnumNode)type);
+ WriteTypeElements(type);
+ break;
+ }
+
+ WriteTypeContainers(type);
+
+ WriteAttributes(type.Attributes, type.SecurityAttributes);
+
+ EndElementCallbacks("api", type);
+ writer.WriteEndElement();
+
+ }
+
+ private void WriteTypeContainers(TypeNode type) {
+
+ writer.WriteStartElement("containers");
+ WriteLibraryReference(type.DeclaringModule);
+ WriteNamespaceReference(GetNamespace(type));
+
+ // for nested types, record outer types
+ TypeNode outer = type.DeclaringType;
+ if (outer != null) WriteTypeReference(outer);
+
+ writer.WriteEndElement();
+
+ }
+
+ // Type data
+
+ private void WriteTypeData(TypeNode type) {
+ writer.WriteStartElement("typedata");
+
+ // data for all types
+ WriteStringAttribute("visibility", GetVisibility(type));
+ WriteBooleanAttribute("abstract", type.IsAbstract, false);
+ WriteBooleanAttribute("sealed", type.IsSealed, false);
+ WriteBooleanAttribute("serializable", (type.Flags & TypeFlags.Serializable) != 0);
+
+ // interop data
+ TypeFlags layout = type.Flags & TypeFlags.LayoutMask;
+ switch (layout) {
+ case TypeFlags.AutoLayout:
+ WriteStringAttribute("layout", "auto");
+ break;
+ case TypeFlags.SequentialLayout:
+ WriteStringAttribute("layout", "sequential");
+ break;
+ case TypeFlags.ExplicitLayout:
+ WriteStringAttribute("layout", "explicit");
+ break;
+ }
+ TypeFlags format = type.Flags & TypeFlags.StringFormatMask;
+ switch (format) {
+ case TypeFlags.AnsiClass:
+ WriteStringAttribute("format", "ansi");
+ break;
+ case TypeFlags.UnicodeClass:
+ WriteStringAttribute("format", "unicode");
+ break;
+ case TypeFlags.AutoClass:
+ WriteStringAttribute("format", "auto");
+ break;
+ }
+ // also import
+
+ StartElementCallbacks("typedata", type);
+
+
+ EndElementCallbacks("typedata", type);
+ writer.WriteEndElement();
+
+ // for classes, recored base type
+ if (type is Class) {
+ WriteHierarchy(type);
+ // TypeNode parent = type.BaseType;
+ // if (parent != null) WriteStringAttribute("parent", namer.GetTypeName(parent));
+ }
+
+ }
+
+ private void WriteTypeElements(TypeNode type) {
+
+ // collect members
+ MemberDictionary members = new MemberDictionary(type, this.ApiFilter);
+ if (members.Count == 0) return;
+
+ writer.WriteStartElement("elements");
+ StartElementCallbacks("elements", members);
+
+ foreach (Member member in members) {
+ writer.WriteStartElement("element");
+
+ Member template = ReflectionUtilities.GetTemplateMember(member);
+ writer.WriteAttributeString("api", namer.GetMemberName(template));
+
+ bool write = false;
+
+ // inherited, specialized generics get a displayed target different from the target
+ // we also write out their info, since it can't be looked up anywhere
+ if (!member.DeclaringType.IsStructurallyEquivalentTo(template.DeclaringType)) {
+ writer.WriteAttributeString("display-api", namer.GetMemberName(member));
+ write = true;
+ }
+
+ // if a member is from a type in a dependency assembly, write out its info, since it can't be looked up in this file
+ if (!assemblyNames.ContainsKey(member.DeclaringType.DeclaringModule.ContainingAssembly.StrongName)) write = true;
+ // if (Array.BinarySearch(assemblyNames, member.DeclaringType.DeclaringModule.ContainingAssembly.Name) < 0) write = true;
+
+ if (write) WriteMember(member);
+
+ writer.WriteEndElement();
+ }
+
+ EndElementCallbacks("elements", members);
+ writer.WriteEndElement();
+
+ }
+
+ // Return value or property value or field value
+
+ private void WriteValue(TypeNode type) {
+ if (type.FullName == "System.Void") return;
+ writer.WriteStartElement("returns");
+ WriteTypeReference(type);
+ // writer.WriteAttributeString("type", namer.GetTypeName(type));
+ writer.WriteEndElement();
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs b/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs
new file mode 100644
index 0000000..4c40c54
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/MemberDictionary.cs
@@ -0,0 +1,273 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ public class MemberDictionary : ICollection < Member > {
+
+ private Dictionary < string, List < Member > > index = new Dictionary < string, List < Member > >();
+
+ private TypeNode type;
+
+ // construct the dictionary
+
+ public MemberDictionary(TypeNode type, ApiFilter filter) {
+
+ this.type = type;
+
+ bool isSealed = type.IsSealed;
+
+ // add all member of the type that the filter allows
+ MemberList members = type.Members;
+ for (int i = 0; i < members.Count; i++) {
+ Member member = members[i];
+
+ // don't add nested types
+ if (member is TypeNode) continue;
+
+ // if our type is sealed, don't add protected members (is this check even necessary?)
+ // if (isSealed && (member.IsFamily || member.IsFamilyAndAssembly)) continue;
+
+ // don't add members that the filter rejects
+ if (!filter.IsExposedMember(member)) continue;
+
+ // okay, add the member
+ AddMember(member);
+ }
+
+ // for enumerations, don't list inherited members
+ if (type is EnumNode) return;
+
+ // for interfaces, list members of inherited interfaces
+ if (type is Interface) {
+
+ InterfaceList contracts = type.Interfaces;
+ for (int i = 0; i < contracts.Count; i++) {
+
+ Interface contract = contracts[i];
+
+ // members of hidden interfaces don't count
+ if (!filter.IsExposedType(contract)) continue;
+
+ // otherwise, add inherited interface members
+ MemberList contractMembers = contract.Members;
+ for (int j = 0; j < contractMembers.Count; j++) {
+ Member contractMember = contractMembers[j];
+
+ // check for exposure; this is necessary to remove accessor methods
+ if (!filter.IsExposedMember(contractMember)) continue;
+
+ AddMember(contractMember);
+ }
+
+
+ }
+
+ return;
+ }
+
+ // don't list inherited memers for static classes
+ if (type.IsAbstract && type.IsSealed) return;
+
+ // now interate up through the type hierarchy
+ for (TypeNode parentType = type.BaseType; parentType != null; parentType = parentType.BaseType) {
+
+ // iterate through the members of each type
+ MemberList parentMembers = parentType.Members;
+ for (int i = 0; i < parentMembers.Count; i++) {
+ Member parentMember = parentMembers[i];
+
+ // don't add constructors
+ if ((parentMember.NodeType == NodeType.InstanceInitializer) || (parentMember.NodeType == NodeType.StaticInitializer)) continue;
+
+ // don't add inherited static members
+ if (parentMember.IsStatic) continue;
+
+ // don't add nested types
+ if (parentMember is TypeNode) continue;
+
+ // if our type is sealed, don't add protected members
+ // if (isSealed && (parentMember.IsFamily || parentMember.IsFamilyAndAssembly)) continue;
+
+ // don't add members that the filter rejects
+ if (!filter.IsExposedMember(parentMember)) continue;
+
+ // don't add members we have overridden
+ if (this.Contains(parentMember)) continue;
+
+ // otherwise, add the member
+ AddMember(parentMember);
+
+ }
+
+ }
+
+ }
+
+ public List < Member > AllMembers {
+ get {
+ List < Member > list = new List < Member >();
+ foreach (List < Member > entries in index.Values) {
+ list.AddRange(entries);
+ }
+ return (list);
+ }
+ }
+
+ public int Count {
+ get {
+ int count = 0;
+ foreach (List < Member > entries in index.Values) {
+ count += entries.Count;
+ }
+ return (count);
+ }
+ }
+
+ public IList < string > MemberNames {
+ get {
+ return (new List < string >(index.Keys));
+ }
+ }
+
+ // access the data
+
+ public TypeNode Type {
+ get {
+ return (type);
+ }
+ }
+
+ bool ICollection < Member >.IsReadOnly {
+ get {
+ return (true);
+ }
+ }
+
+ public List < Member > this[string name] {
+ get {
+ List < Member > members;
+ index.TryGetValue(name, out members);
+ return (members);
+ }
+ }
+
+ public void Clear() {
+ throw new InvalidOperationException();
+ }
+
+ public bool Contains(Member member) {
+
+ // get candidate members with the same name
+ List < Member > candidates;
+ bool found = index.TryGetValue(member.Name.Name, out candidates);
+
+ // if no candidates were found, we don't have the member
+ if (!found) return (false);
+
+ // iterate over the candidates, looking for one of the same type with the same parameters
+ ParameterList parameters = GetParameters(member);
+ foreach (Member candidate in candidates) {
+
+ // candidates must be of the same type
+ if (candidate.NodeType != member.NodeType) continue;
+
+ // get candidate parameters
+ ParameterList candidateParameters = GetParameters(candidate);
+
+ // number of parameters must match
+ if (parameters.Count != candidateParameters.Count) continue;
+
+ // each parameter type must match
+ bool parameterMismatch = false;
+ for (int i = 0; i < parameters.Count; i++) {
+ if (parameters[i].Type != candidateParameters[i].Type) parameterMismatch = true;
+ }
+ // if the parameters match, we have the member
+ if (!parameterMismatch) return (true);
+
+ }
+
+ // no candidates matched
+ return (false);
+
+ }
+
+ // methods to complete ICollection<Member>
+
+ public void CopyTo(Member[] array, int index) {
+ throw new NotImplementedException();
+ }
+
+ void ICollection < Member >.Add(Member member) {
+ throw new InvalidOperationException();
+ }
+
+ IEnumerator < Member > IEnumerable < Member >.GetEnumerator() {
+ return (GetEnumerator());
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() {
+ return (GetEnumerator());
+ }
+
+ public bool Remove(Member member) {
+ throw new InvalidOperationException();
+ }
+
+ private static ParameterList GetParameters(Member member) {
+
+ // if the member is a method, get it's parameter list
+ Method method = member as Method;
+ if (method != null) {
+ return (method.Parameters);
+ }
+
+ // if the member is a property, get it's parameter list
+ Property property = member as Property;
+ if (property != null) {
+ return (property.Parameters);
+ }
+
+ // member is neither a method nor a property
+ return (new ParameterList());
+ //return(null);
+
+ }
+
+ private void AddMember(Member member) {
+
+ // get the member name
+ string name = member.Name.Name;
+
+ // look up the member list for that name
+ List < Member > members;
+ if (!index.TryGetValue(name, out members)) {
+ // if there isn't one already, make one
+ members = new List < Member >();
+ index.Add(name, members);
+ }
+ // add the member to the list
+ members.Add(member);
+
+ }
+
+ // enumerator stuff
+
+ private IEnumerator < Member > GetEnumerator() {
+ return (AllMembers.GetEnumerator());
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..91fb255
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MrefBuilder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("MrefBuilder")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(false)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e6670ce1-be5e-4bed-a4af-13d741b7b007")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs b/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs
new file mode 100644
index 0000000..ba2a149
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/ResourceHelper.cs
@@ -0,0 +1,28 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.IO;
+using System.Reflection;
+using System.Resources;
+
+namespace Microsoft.Ddue.Tools.DxCoach {
+
+ internal sealed class ResourceHelper {
+
+ private static ResourceManager manager = new ResourceManager("TextStrings", Assembly.GetExecutingAssembly());
+
+ private ResourceHelper() { }
+
+ public static Stream GetStream(string file) {
+ return (Assembly.GetExecutingAssembly().GetManifestResourceStream(file));
+ }
+
+ public static string GetString(string key) {
+ return (manager.GetString(key));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt b/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt
new file mode 100644
index 0000000..b13b4e8
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/TextStrings.txt
@@ -0,0 +1,4 @@
+HelpOption = Show this help page.
+OutputOption = Specifies an output file.
+ConfigOption = Specifies a configuration file.
+DependencyOption = Specify assemblies on which the reflected assemblies depend.
diff --git a/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs b/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs
new file mode 100644
index 0000000..79c7c76
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/XamlAttachedMembersAddIn.cs
@@ -0,0 +1,243 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+using Microsoft.Ddue.Tools.Reflection;
+
+namespace Microsoft.Ddue.Tools {
+
+ // XAML add in
+
+ public class XamlAttachedMembersAddIn : MRefBuilderAddIn {
+
+ private Dictionary < Object, Field > attachedMembers = new Dictionary < Object, Field >();
+
+ private Dictionary < TypeNode, Property > contentProperties = new Dictionary < TypeNode, Property >();
+
+ private ManagedReflectionWriter mrw;
+
+ public XamlAttachedMembersAddIn(ManagedReflectionWriter writer, XPathNavigator configuration) : base(writer, configuration) {
+ // keep track of the writer
+ mrw = writer;
+
+ // register processors as callbacks
+ writer.RegisterStartTagCallback("apis", new MRefBuilderCallback(AddAttachedMembers));
+ writer.RegisterStartTagCallback("apidata", new MRefBuilderCallback(WriteAttachedMember));
+ writer.RegisterStartTagCallback("typedata", new MRefBuilderCallback(WriteContentPropertyData));
+ writer.RegisterEndTagCallback("api", new MRefBuilderCallback(WriteAttachmentData));
+ }
+
+ private void AddAttachedMembers(XmlWriter writer, object info) {
+ NamespaceList spaces = (NamespaceList)info;
+ foreach (Namespace space in spaces) {
+ TypeNodeList types = space.Types;
+ foreach (TypeNode type in types) {
+
+ MemberList members = type.Members;
+
+ // go through the members, looking for fields signaling attached properties
+ foreach (Member member in members) {
+
+ // we need a visible, static, field...
+ if (!member.IsStatic || !member.IsVisibleOutsideAssembly || member.NodeType != NodeType.Field) continue;
+ Field field = (Field)member;
+
+ // of type dependency property....
+ if (field.Type.FullName != "System.Windows.DependencyProperty") continue;
+
+ // with a name ending in "Property"...
+ string name = field.Name.Name;
+ if (!name.EndsWith("Property")) continue;
+ name = name.Substring(0, name.Length - 8);
+
+ // look for a getter and/or a setter
+
+ Method getter = null;
+ MemberList candidateGetters = type.GetMembersNamed(new Identifier("Get" + name));
+ for (int i = 0; i < candidateGetters.Count; i++) {
+ Member candidateGetter = candidateGetters[i];
+ if ((candidateGetter.NodeType == NodeType.Method) && candidateGetter.IsStatic && candidateGetter.IsVisibleOutsideAssembly) getter = (Method)candidateGetter;
+ }
+
+ Method setter = null;
+ MemberList candidateSetters = type.GetMembersNamed(new Identifier("Set" + name));
+ for (int i = 0; i < candidateSetters.Count; i++) {
+ Member candidateSetter = candidateSetters[i];
+ if ((candidateSetter.NodeType == NodeType.Method) && candidateSetter.IsStatic && candidateSetter.IsVisibleOutsideAssembly) setter = (Method)candidateSetter;
+ }
+
+ if ((getter == null) && (setter == null)) continue;
+
+ // make sure there isn't already such a property
+
+ Property existingProperty = type.GetProperty(new Identifier(name), new TypeNode[0]);
+ if (existingProperty != null) continue;
+
+ // okay, this really is an indication of an attached property, so create one
+
+ Property attachedProperty = new Property(type, null, PropertyFlags.None, new Identifier(name), getter, setter);
+ // attached properties have no parameters
+ attachedProperty.Parameters = ParameterList.Empty;
+ // attached properties are instance properties
+ // somehow mark as attached?
+ type.Members.Add(attachedProperty);
+ attachedMembers.Add(attachedProperty, field);
+
+ }
+
+ // go through the members, looking for fields signaling attached events
+ foreach (Member member in members) {
+
+ if (!member.IsStatic || !member.IsVisibleOutsideAssembly) continue;
+
+ if (member.NodeType != NodeType.Field) continue;
+ Field field = (Field)member;
+
+ if (field.Type.FullName != "System.Windows.RoutedEvent") continue;
+
+ string name = field.Name.Name;
+ if (!name.EndsWith("Event")) continue;
+ name = name.Substring(0, name.Length - 5);
+
+ Method adder = null;
+ MemberList candidateAdders = type.GetMembersNamed(new Identifier("Add" + name + "Handler"));
+ for (int i = 0; i < candidateAdders.Count; i++) {
+ Member candidateAdder = candidateAdders[i];
+ if ((candidateAdder.NodeType == NodeType.Method) && candidateAdder.IsStatic) adder = (Method)candidateAdder;
+ }
+
+ Method remover = null;
+ MemberList candidateRemovers = type.GetMembersNamed(new Identifier("Remove" + name + "Handler"));
+ for (int i = 0; i < candidateRemovers.Count; i++) {
+ Member candidateRemover = candidateRemovers[i];
+ if ((candidateRemover.NodeType == NodeType.Method) && candidateRemover.IsStatic) remover = (Method)candidateRemover;
+ }
+
+ if ((adder == null) || (remover == null)) continue;
+
+ // make sure there isn't already such an event
+
+ Event existingEvent = type.GetEvent(new Identifier(name));
+ if (existingEvent != null) continue;
+
+ // okay, this really is an indication of an attached event, so create one
+
+ TypeNode handler = adder.Parameters[1].Type;
+ Event attachedEvent = new Event(type, null, EventFlags.None, new Identifier(name), adder, null, remover, handler);
+ attachedEvent.HandlerFlags = adder.Flags;
+ // attached events are instance events
+ // mark as attached?
+
+ type.Members.Add(attachedEvent);
+ attachedMembers.Add(attachedEvent, field);
+
+ }
+
+ }
+ }
+
+ }
+
+ private Property GetContentProperty(TypeNode type) {
+ return (null);
+ }
+
+ private void WriteAttachedMember(XmlWriter writer, object info) {
+
+ if (attachedMembers.ContainsKey(info)) {
+ if (info is Property) {
+ writer.WriteAttributeString("subsubgroup", "attachedProperty");
+ } else if (info is Event) {
+ writer.WriteAttributeString("subsubgroup", "attachedEvent");
+ }
+ }
+
+ }
+
+ private void WriteAttachmentData(XmlWriter writer, object info) {
+
+ if (attachedMembers.ContainsKey(info)) {
+
+ Member attachedMember = (Member)info;
+ if (attachedMember.NodeType == NodeType.Property) {
+
+ Property attachedProperty = (Property)attachedMember;
+
+ writer.WriteStartElement("attachedpropertydata");
+
+ string fieldName = attachedMember.Name + "Property";
+ Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
+ writer.WriteStartElement("field");
+ mrw.WriteMemberReference(field);
+ writer.WriteEndElement();
+
+ Method getter = attachedProperty.Getter;
+ if (getter != null) {
+ writer.WriteStartElement("getter");
+ mrw.WriteMemberReference(getter);
+ writer.WriteEndElement();
+ }
+
+ Method setter = attachedProperty.Setter;
+ if (setter != null) {
+ writer.WriteStartElement("setter");
+ mrw.WriteMemberReference(setter);
+ writer.WriteEndElement();
+ }
+
+ writer.WriteEndElement();
+
+ } else if (attachedMember.NodeType == NodeType.Event) {
+
+ Event attachedEvent = (Event)attachedMember;
+
+ writer.WriteStartElement("attachedeventdata");
+
+ string fieldName = attachedMember.Name + "Event";
+ Field field = attachedMember.DeclaringType.GetField(new Identifier(fieldName));
+ writer.WriteStartElement("field");
+ mrw.WriteMemberReference(field);
+ writer.WriteEndElement();
+
+ Method adder = attachedEvent.HandlerAdder;
+ writer.WriteStartElement("adder");
+ mrw.WriteMemberReference(adder);
+ writer.WriteEndElement();
+
+ Method remover = attachedEvent.HandlerRemover;
+ writer.WriteStartElement("remover");
+ mrw.WriteMemberReference(remover);
+ writer.WriteEndElement();
+
+ writer.WriteEndElement();
+
+ }
+
+ }
+
+ }
+
+ private void WriteContentPropertyData(XmlWriter writer, object info) {
+ TypeNode type = (TypeNode)info;
+ if (contentProperties.ContainsKey(type)) {
+
+ // get default constructors
+ InstanceInitializer constructor = type.GetConstructor(new TypeNode[0]);
+ if ((constructor != null) && (!constructor.IsPublic)) constructor = null;
+
+ if (constructor != null) writer.WriteAttributeString("defaultConstructor", mrw.ApiNamer.GetMemberName(constructor));
+
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/MRefBuilder/reflection.xsd b/tools/Sandcastle/Source/MRefBuilder/reflection.xsd
new file mode 100644
index 0000000..f551aed
--- /dev/null
+++ b/tools/Sandcastle/Source/MRefBuilder/reflection.xsd
@@ -0,0 +1,686 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
+
+ <!-- Api elements -->
+
+ <xsd:element name="reflection">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assemblies" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="apis" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Assembly data -->
+
+ <xsd:element name="assemblies">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assembly" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="assemblydata" />
+ <xsd:element ref="attributes" />
+ </xsd:sequence>
+ <xsd:attribute name="name" />
+ <xsd:attribute name="version" />
+ <xsd:attribute name="culture" />
+ <xsd:attribute name="key" />
+ <xsd:attribute name="hash" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assemblydata">
+ <xsd:complexType>
+ <xsd:attribute name="version" />
+ <xsd:attribute name="culture" />
+ <xsd:attribute name="key" />
+ <xsd:attribute name="hash" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Api data -->
+
+ <xsd:element name="apis">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="api" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- uniqueness constraint can only be applied if duplicates are merged -->
+ <!--
+ <xsd:unique name="uniqueId">
+ <xsd:selector xpath="api" />
+ <xsd:field xpath="@id" />
+ </xsd:unique>
+-->
+ </xsd:element>
+
+ <xsd:element name="api">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="apidata" minOccurs="1" maxOccurs="1" />
+ <xsd:choice>
+ <!-- namespace -->
+ <xsd:sequence>
+ <xsd:element ref="elements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- type -->
+ <xsd:sequence>
+ <xsd:element ref="typedata" minOccurs="1" />
+ <xsd:element ref="enumerationbase" minOccurs="0" />
+ <xsd:element ref="family" minOccurs="0" />
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ <xsd:element ref="implements" minOccurs="0" />
+ <xsd:element ref="implementors" minOccurs="0" />
+ <xsd:element ref="elements" minOccurs="0" />
+ <xsd:element ref="containers" minOccurs="1" />
+ </xsd:sequence>
+ <!-- member -->
+ <xsd:sequence>
+ <xsd:element ref="memberdata" minOccurs="1" />
+ <xsd:choice>
+ <!-- field -->
+ <xsd:sequence>
+ <xsd:element name="fielddata" minOccurs="1" />
+ <xsd:element ref="returns" minOccurs="1" />
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <!-- procedure-->
+ <xsd:sequence>
+ <xsd:element name="proceduredata" minOccurs="1" />
+ <xsd:element ref="overrides" minOccurs="0" />
+ <xsd:choice>
+ <!-- method -->
+ <xsd:sequence>
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ </xsd:sequence>
+ <!-- property -->
+ <xsd:sequence>
+ <xsd:element ref="propertydata" minOccurs="1" />
+ <xsd:element ref="getter" minOccurs="0" />
+ <xsd:element ref="setter" minOccurs="0"/>
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="1" />
+ </xsd:sequence>
+ <!-- event -->
+ <xsd:sequence>
+ <xsd:element ref="eventdata" minOccurs="1" />
+ <xsd:element ref="adder" minOccurs="0" />
+ <xsd:element ref="remover" minOccurs="0"/>
+ <xsd:element ref="eventhandler" minOccurs="1" />
+ <xsd:element ref="eventargs" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="implements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- constructor -->
+ <xsd:sequence>
+ <xsd:element ref="parameters" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="containers" minOccurs="1" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="id" type="apiId" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:group name="memberContent">
+ <xsd:sequence>
+ <xsd:element name="apidata" minOccurs="1" />
+ <xsd:element ref="memberdata" minOccurs="1" />
+ <xsd:choice>
+ <!-- field -->
+ <xsd:sequence>
+ <xsd:element name="fielddata" minOccurs="1" />
+ <xsd:element ref="returns" minOccurs="1" />
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <!-- procedure-->
+ <xsd:sequence>
+ <xsd:element name="proceduredata" minOccurs="1" />
+ <xsd:element ref="overrides" minOccurs="0" />
+ <xsd:choice>
+ <!-- method -->
+ <xsd:sequence>
+ <xsd:element ref="templates" minOccurs="0" />
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="0" />
+ </xsd:sequence>
+ <!-- property -->
+ <xsd:sequence>
+ <xsd:element ref="propertydata" minOccurs="1" />
+ <xsd:element ref="getter" minOccurs="0" />
+ <xsd:element ref="setter" minOccurs="0"/>
+ <xsd:element ref="parameters" minOccurs="0" />
+ <xsd:element ref="returns" minOccurs="1" />
+ </xsd:sequence>
+ <!-- event -->
+ <xsd:sequence>
+ <xsd:element ref="eventdata" minOccurs="1" />
+ <xsd:element ref="adder" minOccurs="0" />
+ <xsd:element ref="remover" minOccurs="0"/>
+ <xsd:element ref="eventhandler" minOccurs="1" />
+ <xsd:element ref="eventargs" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="implements" minOccurs="0" />
+ </xsd:sequence>
+ <!-- constructor -->
+ <xsd:sequence>
+ <xsd:element ref="parameters" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element ref="containers" minOccurs="1" />
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="optionalApiInformation">
+ <xsd:choice minOccurs="0">
+ <xsd:group ref="memberContent" />
+ </xsd:choice>
+ </xsd:complexType>
+
+ <!-- Identity and information elements -->
+
+ <xsd:element name="apidata">
+ <xsd:complexType>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="group" type="apiGroupType" use="required" />
+ <xsd:attribute name="subgroup" type="apiSubgroupType" use="optional" />
+ <xsd:attribute name="subsubgroup" type="apiSubsubgroupType" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="typedata">
+ <xsd:complexType>
+ <xsd:attribute name="visibility" type="visibilityType" use="required" />
+ <xsd:attribute name="abstract" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="sealed" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="serializable" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="layout" type="xsd:string" use="optional" />
+ <xsd:attribute name="format" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="fielddata">
+ <xsd:complexType>
+ <xsd:attribute name="literal" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="initonly" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="volatile" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="serialized" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="memberdata">
+ <xsd:complexType>
+ <xsd:attribute name="visibility" type="visibilityType" />
+ <xsd:attribute name="static" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="special" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="default" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="proceduredata">
+ <xsd:complexType>
+ <xsd:attribute name="abstract" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="virtual" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="final" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="overrides">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="member" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="propertydata">
+ <xsd:complexType>
+ <xsd:attribute name="get" type="xsd:boolean" />
+ <xsd:attribute name="set" type="xsd:boolean" />
+ <xsd:attribute name="get-visibility" type="visibilityType" use="optional" />
+ <xsd:attribute name="set-visibility" type="visibilityType" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="getter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="setter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="eventdata">
+ <xsd:complexType>
+ <xsd:attribute name="add" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="remove" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="call" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="adder">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="remover">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attributes" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="enumerationbase" type="typeReference" />
+
+ <xsd:element name="eventhandler" type="typeReference" />
+
+ <xsd:element name="eventargs" type="typeReference" />
+
+ <!-- Generic template parameters -->
+
+ <xsd:element name="templates">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="template" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="template">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="constrained" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="api" type="xsd:string" use="optional" />
+ <xsd:attribute name="index" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="constrained">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ <xsd:element ref="implements" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="ref" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="value" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="ctor" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <!-- Parameters and return values -->
+
+ <xsd:element name="parameters">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="parameter" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="parameter">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="in" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="out" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="params" type="xsd:boolean" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="returns" type="typeReference" />
+
+ <!-- Interface implementations -->
+
+ <xsd:element name="implements">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:element ref="member" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="implementors" type="typeReferenceList" />
+
+ <!-- Inheritance -->
+
+ <xsd:element name="family">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="ancestors" minOccurs="0" />
+ <xsd:element ref="descendents" minOccurs="0" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="ancestors">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="descendents">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Attributes -->
+
+ <xsd:element name="attributes">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="attribute">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:sequence>
+ <xsd:element ref="argument" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="assignment" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="argument">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="assignment">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:group ref="typeReferenceElements" minOccurs="1" />
+ <xsd:group ref="valueReferenceElements" minOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- Containers -->
+
+ <xsd:element name="containers">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="typeContainers">
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="memberContainers">
+ <xsd:sequence>
+ <xsd:element ref="library" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="namespace" minOccurs="1" maxOccurs="1" />
+ <xsd:element ref="type" minOccurs="1" maxOccurs="1" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="library">
+ <xsd:complexType>
+ <xsd:attribute name="assembly" type="xsd:string" />
+ <xsd:attribute name="module" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="outer" type="typeReferenceList" />
+
+ <!-- Elements -->
+
+ <xsd:element name="elements">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="element" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="element">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="optionalApiInformation">
+ <xsd:attribute name="api" type="apiId" use="optional" />
+ <xsd:attribute name="target-api" type="apiId" use="optional" />
+ <xsd:attribute name="display-api" type="apiId" use="optional" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- references -->
+
+ <xsd:element name="namespace">
+ <xsd:complexType>
+ <xsd:attribute name="api" type="namespaceId" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:group name="typeReferenceElements">
+ <xsd:choice>
+ <xsd:element ref="arrayOf" />
+ <xsd:element name="pointerTo" type="typeReference" />
+ <xsd:element name="referenceTo" type="typeReference" />
+ <xsd:element ref="type" />
+ <xsd:element ref="template" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="typeReference">
+ <xsd:group ref="typeReferenceElements" />
+ </xsd:complexType>
+
+ <xsd:complexType name="typeReferenceList">
+ <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+ <xsd:group ref="typeReferenceElements" />
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="arrayOf">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:attribute name="rank" type="xsd:positiveInteger" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="type">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="optionalModifier" type="typeReference" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="requiredModifier" type="typeReference" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="specialization" type="typeReferenceList" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="api" type="typeId" use="required" />
+ <xsd:attribute name="ref" type="xsd:boolean" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- <xsd:element name="specialization" type="typeReferenceList" /> -->
+
+ <xsd:element name="member">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="type" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="optional" />
+ <xsd:attribute name="api" type="xsd:string" use="optional" />
+ <xsd:attribute name="target-api" type="xsd:string" use="optional" />
+ <xsd:attribute name="display-api" type="xsd:string" use="optional" />
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="valueReference">
+ <xsd:complexContent>
+ <xsd:extension base="typeReference">
+ <xsd:choice>
+ <xsd:element name="value" type="xsd:string" />
+ <xsd:element name="typeValue" type="typeReference" />
+ <xsd:element name="enumValue" />
+ <xsd:element name="nullValue" />
+ </xsd:choice>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:group name="valueReferenceElements">
+ <xsd:choice>
+ <xsd:element name="value" type="xsd:string" />
+ <xsd:element name="typeValue" type="typeReference" />
+ <xsd:element name="enumValue" />
+ <xsd:element name="nullValue" />
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:simpleType name="rootId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="R:[_\w\.]+" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="namespaceId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="N:([_\w]+\.)*[_\w]*" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="typeId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="T:.+" />
+ <!-- <xsd:pattern value="T:([_\w]+\.)*[_\w]+(\{.+\})?(@|\*|(\[\]))*" /> -->
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="fieldReference">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="F:(\w+\.)*[_\w]+(\{.+\})?\.\w+" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="memberId">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="[FMPE]:.+" />
+ <!-- <xsd:pattern value="[FMPE]:(\w+\.)*[_\w]+(\{.+\})?\.([_\.\w&lt;&gt;,]+|#ctor)(\(.+\))?(~(\w+\.)*[_\w]+(\{.+\})?(@|\*|(\[\]))*)?" /> -->
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiId">
+ <xsd:union memberTypes="rootId namespaceId typeId memberId" />
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiGroupType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="namespace" />
+ <xsd:enumeration value="type" />
+ <xsd:enumeration value="member" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiSubgroupType">
+ <xsd:restriction base="xsd:string">
+ <!-- type subgroups -->
+ <xsd:enumeration value="class" />
+ <xsd:enumeration value="structure" />
+ <xsd:enumeration value="interface" />
+ <xsd:enumeration value="enumeration" />
+ <xsd:enumeration value="delegate" />
+ <!-- member subgroups -->
+ <xsd:enumeration value="constructor" />
+ <xsd:enumeration value="method" />
+ <xsd:enumeration value="property" />
+ <xsd:enumeration value="field" />
+ <xsd:enumeration value="event" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="apiSubsubgroupType">
+ <xsd:restriction base="xsd:string">
+ <!-- method subsubgroups -->
+ <xsd:enumeration value="operator" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:simpleType name="visibilityType">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="public" />
+ <xsd:enumeration value="family" />
+ <xsd:enumeration value="assembly" />
+ <xsd:enumeration value="family or assembly" />
+ <xsd:enumeration value="family and assembly" />
+ <xsd:enumeration value="private" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- format, layout -->
+
+</xsd:schema>
diff --git a/tools/Sandcastle/Source/Reflection/AllDocumentedFilter.cs b/tools/Sandcastle/Source/Reflection/AllDocumentedFilter.cs
new file mode 100644
index 0000000..a171b52
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/AllDocumentedFilter.cs
@@ -0,0 +1,90 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+//using System;
+using System.Compiler;
+using System.Xml.XPath;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ // exposes all apis, including internal apis, for which documentation is written
+
+ // this includes all members except for property and event accessors (e.g. get_ methods) and delegate members (e.g. Invoke).
+
+ // enumeration members are included
+
+ public class AllDocumentedFilter : ApiFilter {
+
+ public AllDocumentedFilter() : base() { }
+
+ public AllDocumentedFilter(XPathNavigator configuration) : base(configuration) { }
+
+
+
+ public override bool IsExposedMember(Member member) {
+
+ // member of delegates are not exposed
+ TypeNode type = member.DeclaringType;
+ if (type.NodeType == NodeType.DelegateNode) return (false);
+
+ // accessor methods for properties and events are not exposed
+ if (member.IsSpecialName && (member.NodeType == NodeType.Method)) {
+ string name = member.Name.Name;
+ if (NameContains(name, "get_")) return (false);
+ if (NameContains(name, "set_")) return (false);
+ if (NameContains(name, "add_")) return (false);
+ if (NameContains(name, "remove_")) return (false);
+ if (NameContains(name, "raise_")) return (false);
+ }
+
+ // the value field of enumerations is not exposed
+ if (member.IsSpecialName && (type.NodeType == NodeType.EnumNode) && (member.NodeType == NodeType.Field)) {
+ string name = member.Name.Name;
+ if (name == "value__") return (false);
+ }
+
+ // members marked as compiler-generated are not exposed
+ if (ListContainsAttribute(member.Attributes, "System.Runtime.CompilerServices.CompilerGeneratedAttribute")) {
+ return (false);
+ }
+
+ // okay, passed all tests, so member is exposed
+ return (base.IsExposedMember(member));
+
+ }
+
+ // all namespace and all types are exposed
+
+ /** <summary>Check the given type and all parent types for compiler attributes.
+ * If none are found look for any filters to determine if it is exposed.</summary> */
+ public override bool IsExposedType(TypeNode type) {
+
+ // don't include compiler-generated types
+ // check this and all parents for compiler attributes
+ TypeNode curType = type; //cursor
+ while (curType != null)
+ {
+ if (ListContainsAttribute(curType.Attributes, "System.Runtime.CompilerServices.CompilerGeneratedAttribute"))
+ return false;
+
+ curType = curType.DeclaringType; //check the next parent
+ }
+
+ //continue on with checking if the type is exposed
+ return base.IsExposedType(type);
+ }
+
+ private static bool ListContainsAttribute(AttributeList attributes, string name) {
+ for (int i = 0; i < attributes.Count; i++) {
+ if (attributes[i].Type.FullName == name) return (true);
+ }
+ return (false);
+ }
+
+ private static bool NameContains(string name, string substring) {
+ return (name.Contains(substring));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/AllTopicFilter.cs b/tools/Sandcastle/Source/Reflection/AllTopicFilter.cs
new file mode 100644
index 0000000..b92bba6
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/AllTopicFilter.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ // exposes all apis for which a topic exists
+ // this includes all documented members (see DocumentFilter) except for enumeration members
+
+ public class AllTopicFilter : AllDocumentedFilter {
+
+ public override bool IsExposedMember(Member member) {
+ // don't expose members of enumerations
+ if (member.DeclaringType.NodeType == NodeType.EnumNode) return (false);
+ // otherwise, agree with DocumentedFilter
+ return (base.IsExposedMember(member));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ApiFilter.cs b/tools/Sandcastle/Source/Reflection/ApiFilter.cs
new file mode 100644
index 0000000..201878f
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ApiFilter.cs
@@ -0,0 +1,208 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class ApiFilter {
+
+#region Member Variables
+
+ private RootFilter apiFilter = new RootFilter(true);
+
+ private RootFilter attributeFilter = new RootFilter(true);
+
+ private Dictionary < string, bool > namespaceCache = new Dictionary < string, bool >();
+
+#endregion
+
+#region Constructors
+
+ // stored filters
+
+ public ApiFilter() {
+ // apiFilters.Add(new UserFilter("System.Reflection", "", "", true));
+ // apiFilters.Add(new UserFilter("System", "Object", "", true));
+ // apiFilters.Add(new UserFilter("", "", "", false));
+
+ // attributeFilters.Add(new UserFilter("System.Runtime.InteropServices", "ComVisibleAttribute", "", false));
+ }
+
+ public ApiFilter(XPathNavigator configuration) {
+
+ if (configuration == null) throw new ArgumentNullException("configuration");
+
+ // API filter nodes
+ XPathNavigator apiFilterNode = configuration.SelectSingleNode("apiFilter");
+ if (apiFilterNode != null) {
+ XmlReader configurationReader = apiFilterNode.ReadSubtree();
+ configurationReader.MoveToContent();
+ apiFilter = new RootFilter(configurationReader);
+ configurationReader.Close();
+ }
+
+ // Attribute filter nodes
+ XPathNavigator attributeFilterNode = configuration.SelectSingleNode("attributeFilter");
+ if (attributeFilterNode != null) {
+ XmlReader configurationReader = attributeFilterNode.ReadSubtree();
+ configurationReader.MoveToContent();
+ attributeFilter = new RootFilter(configurationReader);
+ configurationReader.Close();
+ }
+
+ }
+
+#endregion
+
+#region Public API
+
+ public virtual bool HasExposedMembers(TypeNode type)
+ {
+ if (type == null) throw new ArgumentNullException("type");
+ return (apiFilter.HasExposedMembers(type));
+ }
+
+ // exposure logic for artibrary APIs
+ // call the appropriate particular exposure logic
+
+ public virtual bool IsExposedApi(Member api) {
+
+ Namespace space = api as Namespace;
+ if (space != null) return (IsExposedNamespace(space));
+
+ TypeNode type = api as TypeNode;
+ if (type != null) return (IsExposedType(type));
+
+ return (IsExposedMember(api));
+ }
+
+ public virtual bool IsExposedAttribute(AttributeNode attribute) {
+ if (attribute == null) throw new ArgumentNullException("attribute");
+
+ // check whether attribte type is exposed
+ TypeNode attributeType = attribute.Type;
+ if (!IsExposedType(attributeType)) return (false);
+
+ // check whether expressions used to instantiate attribute are exposed
+ ExpressionList expressions = attribute.Expressions;
+ for (int i = 0; i < expressions.Count; i++) {
+ if (!IsExposedExpression(expressions[i])) return (false);
+ }
+
+ // apply user filters to attribute
+ return (attributeFilter.IsExposedType(attributeType));
+ }
+
+ public virtual bool IsExposedMember(Member member) {
+ if (member == null) throw new ArgumentNullException("member");
+ return (apiFilter.IsExposedMember(member));
+ }
+
+ // namespce logic
+ // a namespace is exposed if any type in it is exposed
+
+ public virtual bool IsExposedNamespace(Namespace space) {
+ if (space == null) throw new ArgumentNullException("space");
+ string name = space.Name.Name;
+
+ // look in cache to see if namespace exposure is already determined
+ bool exposed;
+ if (!namespaceCache.TryGetValue(name, out exposed)) {
+ // it is not; determine exposure now
+
+ // the namespace is exposed if any types in it are exposed
+ exposed = NamespaceContainesExposedTypes(space) ?? false;
+
+ // the namespace is also exposed if it contains exposed members, even if all types are hidden
+ if (!exposed)
+ {
+ exposed = NamespaceContainsExposedMembers(space);
+ }
+
+ // cache the result
+ namespaceCache.Add(name, exposed);
+
+ }
+ return (exposed);
+ }
+
+ // type and member logic
+ // by default, types and members are exposed if a user filter says it, or if no user filter forbids it
+
+ public virtual bool IsExposedType(TypeNode type) {
+ if (type == null) throw new ArgumentNullException("type");
+ return (apiFilter.IsExposedType(type));
+ }
+
+#endregion
+
+#region Implementation
+
+ private bool IsExposedExpression(Expression expression) {
+ if (expression.NodeType == NodeType.Literal) {
+ Literal literal = (Literal)expression;
+ TypeNode type = literal.Type;
+ if (!IsExposedType(type)) return (false);
+ if (type.FullName == "System.Type") {
+ // if the value is itself a type, we need to test whether that type is visible
+ TypeNode value = literal.Value as TypeNode;
+ if ((value != null) && !IsExposedType(value)) return (false);
+ }
+ return (true);
+ } else if (expression.NodeType == NodeType.NamedArgument) {
+ NamedArgument assignment = (NamedArgument)expression;
+ return (IsExposedExpression(assignment.Value));
+ } else {
+ throw new InvalidOperationException("Encountered unrecognized expression");
+ }
+ }
+
+ private bool? NamespaceContainesExposedTypes(Namespace space)
+ {
+ TypeNodeList types = space.Types;
+
+ for (int i = 0; i < types.Count; i++)
+ {
+ TypeNode type = types[i];
+ if (IsExposedType(type)) return (true);
+ }
+
+ if (apiFilter.NamespaceFilterCount < 1)
+ {
+ return null; //this apiFilter does not contain any namespaces
+ }
+
+ return (false);
+ }
+
+
+ /** <summary>Check for any exposed members in any of the types.
+ * Returns true if the type has an exposed memeber filter and
+ * it is matched. This is used to determine if the namespace
+ * should be visited if the namespace and all types are set to
+ * false for exposed, we still want to visit them if any members
+ * are set to true.
+ * </summary> */
+ private bool NamespaceContainsExposedMembers(Namespace space)
+ {
+ TypeNodeList types = space.Types;
+ for (int i = 0; i < types.Count; i++)
+ {
+ TypeNode type = types[i];
+
+ if (HasExposedMembers(type)) return true;
+ }
+ return (false);
+ }
+
+#endregion
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ApiNamer.cs b/tools/Sandcastle/Source/Reflection/ApiNamer.cs
new file mode 100644
index 0000000..ade218f
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ApiNamer.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public abstract class ApiNamer {
+
+ public virtual string GetApiName(Member api) {
+
+ Namespace space = api as Namespace;
+ if (space != null) return (GetNamespaceName(space));
+
+ TypeNode type = api as TypeNode;
+ if (type != null) return (GetTypeName(type));
+
+ return (GetMemberName(api));
+
+ }
+
+ public abstract string GetMemberName(Member member);
+
+ public abstract string GetNamespaceName(Namespace space);
+
+ public abstract string GetTypeName(TypeNode type);
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ApiVisitor.cs b/tools/Sandcastle/Source/Reflection/ApiVisitor.cs
new file mode 100644
index 0000000..7b5d9af
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ApiVisitor.cs
@@ -0,0 +1,339 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+
+using System.Compiler;
+
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class ApiVisitor : IDisposable {
+
+ private static Comparison < Member > memberComparison = new Comparison < Member >(CompareMembers);
+
+ // Sorting logic
+
+ private static Comparison < Namespace > namespaceComparison = new Comparison < Namespace >(CompareMembers);
+
+ private static Comparison < TypeNode > typeComparison = new Comparison < TypeNode >(CompareMembers);
+
+ private List < AssemblyNode > accessoryAssemblies = new List < AssemblyNode >();
+
+ // Disposal logic
+
+ private List < AssemblyNode > assemblies = new List < AssemblyNode >();
+
+ // object model store
+
+ private Dictionary < string, Namespace > catalog = new Dictionary < string, Namespace >();
+
+ private ApiFilter filter;
+
+ // Keep track of any metadata load errors
+
+ private Dictionary < string, Exception > loadErrors = new Dictionary < string, Exception >();
+
+ // Revised assembly storage
+
+ private AssemblyResolver resolver = new AssemblyResolver();
+
+ protected ApiVisitor(ApiFilter filter) {
+ this.filter = filter;
+ }
+
+ protected ApiVisitor() : this(new NoFilter()) { }
+
+ public AssemblyNode[] AccessoryAssemblies {
+ get {
+ return (accessoryAssemblies.ToArray());
+ }
+ }
+
+ public ApiFilter ApiFilter {
+ get {
+ return (filter);
+ }
+ set {
+ filter = value;
+ }
+ }
+
+ public AssemblyNode[] Assemblies {
+ get {
+ return (assemblies.ToArray());
+ }
+ }
+
+ public Dictionary < string, Exception > LoadErrors {
+ get {
+ return (loadErrors);
+ }
+ }
+
+ public AssemblyResolver Resolver {
+ get {
+ return (resolver);
+ }
+ set {
+ resolver = value;
+ }
+ }
+
+ public void Dispose() {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing) {
+ if (disposing) {
+ foreach (AssemblyNode assembly in assemblies) {
+ // Console.WriteLine(loadedModule.Name);
+ assembly.Dispose();
+ }
+ foreach (AssemblyNode accessoryAssembly in accessoryAssemblies) {
+ accessoryAssembly.Dispose();
+ }
+ }
+ }
+
+ public void LoadAccessoryAssemblies(string filePattern) {
+
+ // get the full path to the relevent directory
+ string directoryPath = Path.GetDirectoryName(filePattern);
+ if ((directoryPath == null) || (directoryPath.Length == 0)) directoryPath = Environment.CurrentDirectory;
+ directoryPath = Path.GetFullPath(directoryPath);
+
+ // get the file name, which may contain wildcards
+ string filePath = Path.GetFileName(filePattern);
+
+ // look up the files and load them
+ string[] files = Directory.GetFiles(directoryPath, filePath);
+ foreach (string file in files) {
+ LoadAccessoryAssembly(file);
+ }
+ }
+
+ // Accessory modules
+
+ //private IDictionary cache = new Hashtable();
+
+ public void LoadAccessoryAssembly(string filePath) {
+ AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, null, false, false, false, false); // this causes non-classes to register as classes
+ if (assembly != null) {
+ if (assembly.Name == "mscorlib") ResetMscorlib(assembly);
+
+ resolver.Add(assembly);
+ //assembly.AssemblyReferenceResolutionAfterProbingFailed += unresolvedModuleHandler;
+ accessoryAssemblies.Add(assembly);
+ }
+ }
+
+ public void LoadAssemblies(string filePattern) {
+
+ // get the full path to the relevent directory
+ string directoryPath = Path.GetDirectoryName(filePattern);
+ if ((directoryPath == null) || (directoryPath.Length == 0)) directoryPath = Environment.CurrentDirectory;
+ directoryPath = Path.GetFullPath(directoryPath);
+
+ // get the file name, which may contain wildcards
+ string filePath = Path.GetFileName(filePattern);
+
+ // look up the files and load them
+ string[] files = Directory.GetFiles(directoryPath, filePath);
+ foreach (string file in files) {
+ LoadAssembly(file);
+ }
+
+ }
+
+ // Parsing logic
+
+ public void LoadAssembly(string filePath) {
+ //Console.WriteLine("loading {0}", filePath);
+ //AssemblyNode assembly = AssemblyNode.GetAssembly(filePath); // this causes mscorlib to be missing members
+ //AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, cache); // this causes compact framework non-classes to register as classes
+ //AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, cache, false, false, true, false); // this causes missing mscorlib members
+ //AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, cache, false, false, false, false); // this causes non-classes to register as classes
+ //AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, null, false, false, true, false); // this causes missing mscorlib members
+ AssemblyNode assembly = AssemblyNode.GetAssembly(filePath, null, false, false, false, false); // this causes non-classes to register as classes
+
+ if (assembly != null) {
+ if (assembly.Name == "mscorlib") ResetMscorlib(assembly);
+
+ // Console.WriteLine("assembly = {0}", assembly.Name);
+ resolver.Add(assembly);
+ //assembly.AssemblyReferenceResolutionAfterProbingFailed += unresolvedModuleHandler;
+ assemblies.Add(assembly);
+ //Console.WriteLine("{0} has {1} types", assembly.Name, assembly.ExportedTypes.Count);
+ //StoreTypes(assembly.Types);
+ }
+
+ }
+
+ // Visit Object Model
+
+ public void VisitApis() {
+
+ // store types
+ // we have to do this after all assemblies are registered because the resolution may not work unless
+ // all the assemblies we need are in the resolver cache
+ //Console.WriteLine("storing types");
+ foreach (AssemblyNode assembly in assemblies) {
+ //Console.WriteLine("assembly {0}", assembly.Name);
+ //Console.WriteLine("has {0} types", assembly.Types.Count);
+ StoreTypes(assembly.Types);
+ //Console.WriteLine("done with assembly");
+ }
+ //Console.WriteLine("done storing types");
+
+ //Console.WriteLine("visiting namespaces");
+ NamespaceList spaces = new NamespaceList();
+ foreach (Namespace space in catalog.Values) {
+ if (filter.IsExposedNamespace(space)) spaces.Add(space);
+ }
+ VisitNamespaces(spaces);
+ }
+
+ protected virtual void VisitEntity(Member entity) {
+ // inherit and insert logic here
+ }
+
+ protected virtual void VisitMember(Member member) {
+ VisitEntity(member);
+ }
+
+ protected virtual void VisitMembers(MemberList members) {
+ // sort members by name
+ Member[] sorted_members = new Member[members.Count];
+ for (int i = 0; i < members.Count; i++) sorted_members[i] = members[i];
+ Array.Sort < Member >(sorted_members, memberComparison);
+ // visit them
+ foreach (Member member in sorted_members) {
+ // don't visit nested types, as they are already visited
+ if (member is TypeNode) continue;
+ if (filter.IsExposedMember(member))
+ {
+ VisitMember(member);
+ }
+ }
+ }
+
+ protected virtual void VisitNamespace(Namespace space) {
+ //Console.WriteLine("Visit Entity {0}",space.FullName);
+ VisitEntity(space);
+ TypeNodeList types = space.Types;
+ VisitTypes(types);
+ }
+
+ protected virtual void VisitNamespaces(NamespaceList spaces) {
+ // sort namespaces by name
+ Namespace[] sorted_spaces = new Namespace[spaces.Count];
+ for (int i = 0; i < spaces.Count; i++) sorted_spaces[i] = spaces[i];
+ Array.Sort < Namespace >(sorted_spaces, namespaceComparison);
+ // visit them
+ foreach (Namespace space in sorted_spaces) {
+ if (filter.IsExposedNamespace(space)) VisitNamespace(space);
+ }
+ }
+
+ protected virtual void VisitType(TypeNode type) {
+ //Console.WriteLine(type.FullName);
+ VisitEntity(type);
+ MemberList members = type.Members;
+ //Console.WriteLine("{0}: {1}", type.FullName, members.Length);
+ VisitMembers(members);
+ }
+
+ protected virtual void VisitTypes(TypeNodeList types) {
+ // sort types by name
+ TypeNode[] sorted_types = new TypeNode[types.Count];
+ for (int i = 0; i < types.Count; i++) sorted_types[i] = types[i];
+ Array.Sort < TypeNode >(sorted_types, typeComparison);
+ // visit them
+ foreach (TypeNode type in sorted_types) {
+ //Console.WriteLine("visiting {0}", type.Name);
+ //visit this type if it is exposed, or has members that are set as exposed
+ if (filter.IsExposedType(type) || filter.HasExposedMembers(type))
+ VisitType(type); //visit type and members
+ }
+ }
+
+ private static int CompareMembers(Member a, Member b) {
+ return (String.Compare(a.FullName, b.FullName));
+ }
+
+ private static int CompareNamespaces(Namespace a, Namespace b) {
+ return (String.Compare(a.Name.Name, b.Name.Name));
+ }
+
+ private static int CompareTypes(TypeNode a, TypeNode b) {
+ return (String.Compare(a.Name.Name, b.Name.Name));
+ }
+
+ private static string GetNamespaceName(TypeNode type) {
+ TypeNode parent = type.DeclaringType;
+ if (parent != null) {
+ return (GetNamespaceName(parent));
+ } else {
+ if (type.Namespace == null) {
+ return (String.Empty);
+ } else {
+ return (type.Namespace.Name);
+ }
+ }
+ }
+
+ private void ResetMscorlib(AssemblyNode assembly) {
+ TargetPlatform.Clear();
+ CoreSystemTypes.Clear();
+ CoreSystemTypes.SystemAssembly = assembly;
+ CoreSystemTypes.Initialize(true, false);
+ }
+
+ private void StoreType(TypeNode type) {
+ //Console.WriteLine("type: {0} ", type.Name);
+ /*
+ if (type.Name == null) {
+ // CCI seems to occasionally construct corrupted, phantom types, which we should reject
+ // Console.WriteLine("unidentified type rejected");
+ return;
+ }
+ */
+ string spaceName = GetNamespaceName(type);
+ //Console.WriteLine("in space: {0}", spaceName);
+ Namespace space;
+ if (!catalog.TryGetValue(spaceName, out space)) {
+ space = new Namespace(new Identifier(spaceName));
+ catalog.Add(spaceName, space);
+ }
+ if (space.Types == null) Console.WriteLine("null type list");
+ space.Types.Add(type);
+
+ //Console.WriteLine("getting members");
+ MemberList members = type.Members;
+ //Console.WriteLine("got {0} members", members.Count);
+ for (int i = 0; i < members.Count; i++) {
+ TypeNode nestedType = members[i] as TypeNode;
+ if (nestedType != null) {
+ //Console.WriteLine("nested type {0}", type.FullName);
+ StoreType(nestedType);
+ }
+ }
+ //Console.WriteLine("done storing type");
+ }
+
+ private void StoreTypes(TypeNodeList types) {
+ //Console.WriteLine("{0} types", types.Length);
+ for (int i = 0; i < types.Count; i++) {
+ StoreType(types[i]);
+ }
+ }
+
+ }
+
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/AssemblyReferenceEventArgs.cs b/tools/Sandcastle/Source/Reflection/AssemblyReferenceEventArgs.cs
new file mode 100644
index 0000000..feaa117
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/AssemblyReferenceEventArgs.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class AssemblyReferenceEventArgs : EventArgs {
+
+ private Module module;
+
+ private AssemblyReference reference;
+
+ public AssemblyReferenceEventArgs(AssemblyReference reference, Module module) {
+ this.reference = reference;
+ this.module = module;
+ }
+
+ public AssemblyReference Reference {
+ get {
+ return (reference);
+ }
+ }
+
+ public Module Referrer {
+ get {
+ return (module);
+ }
+ }
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/AssemblyResolver.cs b/tools/Sandcastle/Source/Reflection/AssemblyResolver.cs
new file mode 100644
index 0000000..116dcc8
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/AssemblyResolver.cs
@@ -0,0 +1,89 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class AssemblyResolver {
+
+ private Dictionary < string, AssemblyNode > cache = new Dictionary < string, AssemblyNode >();
+
+ private bool useGac = true;
+
+ public AssemblyResolver() {
+
+ }
+
+ public AssemblyResolver(XPathNavigator configuration) {
+
+ string useGacValue = configuration.GetAttribute("use-gac", String.Empty);
+ if (!String.IsNullOrEmpty(useGacValue)) useGac = Convert.ToBoolean(useGacValue);
+
+ }
+
+ public event EventHandler < AssemblyReferenceEventArgs > UnresolvedAssemblyReference;
+
+ public bool UseGac {
+ get {
+ return (useGac);
+ }
+ set {
+ useGac = value;
+ }
+ }
+
+ public virtual void Add(AssemblyNode assembly) {
+ if (assembly == null) throw new ArgumentNullException("assembly");
+ string name = assembly.StrongName;
+ assembly.AssemblyReferenceResolution += new Module.AssemblyReferenceResolver(ResolveReference);
+ assembly.AssemblyReferenceResolutionAfterProbingFailed += new Module.AssemblyReferenceResolver(UnresolvedReference);
+ cache[name] = assembly;
+ //Console.WriteLine("added {0}; cache now contains {1}", name, cache.Count);
+ }
+
+ public virtual AssemblyNode ResolveReference(AssemblyReference reference, Module module) {
+
+ if (reference == null) throw new ArgumentNullException("reference");
+
+ //Console.WriteLine("resolving {0}", reference.StrongName);
+
+ // try to get it from the cache
+ string name = reference.StrongName;
+ if (cache.ContainsKey(name)) return (cache[name]);
+
+ // try to get it from the gac
+ if (useGac) {
+ string location = GlobalAssemblyCache.GetLocation(reference);
+ if (location != null) {
+ AssemblyNode assembly = AssemblyNode.GetAssembly(location, null, false, false, false, false);
+ if (assembly != null) {
+ Add(assembly);
+ return (assembly);
+ }
+ }
+ }
+
+ // couldn't find it; return null
+ // Console.WriteLine("returning null on request for {0}", reference.StrongName);
+ //OnUnresolvedAssemblyReference(reference, module);
+ return (null);
+
+ }
+
+ protected virtual void OnUnresolvedAssemblyReference(AssemblyReference reference, Module module) {
+ if (UnresolvedAssemblyReference != null) UnresolvedAssemblyReference(this, new AssemblyReferenceEventArgs(reference, module));
+ }
+
+ private AssemblyNode UnresolvedReference(AssemblyReference reference, Module module) {
+ OnUnresolvedAssemblyReference(reference, module);
+ return (null);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ExternalDocumentedFilter.cs b/tools/Sandcastle/Source/Reflection/ExternalDocumentedFilter.cs
new file mode 100644
index 0000000..e7f0cf7
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ExternalDocumentedFilter.cs
@@ -0,0 +1,82 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Xml.XPath;
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ // exposes all apis for which documentation is written
+
+ // this includes all visible members except for property and event accessors (e.g. get_ methods) and delegate members (e.g. Invoke).
+
+ // enumeration members are included
+
+ public class ExternalDocumentedFilter : ApiFilter {
+
+ public ExternalDocumentedFilter() : base() { }
+
+ public ExternalDocumentedFilter(XPathNavigator configuration) : base(configuration) { }
+
+ public override bool IsExposedMember(Member member) {
+ if (member == null) throw new ArgumentNullException("member");
+ // if the member isn't visible, we certainly won't expose it...
+ if (!member.IsVisibleOutsideAssembly) return (false);
+ // ...but there are also some visible members we won't expose.
+ TypeNode type = member.DeclaringType;
+ // member of delegates are not exposed
+ if (type.NodeType == NodeType.DelegateNode) return (false);
+ // accessor methods for properties and events are not exposed
+ if (member.IsSpecialName && (member.NodeType == NodeType.Method)) {
+ string name = member.Name.Name;
+ if (NameContains(name, "get_")) return (false);
+ if (NameContains(name, "set_")) return (false);
+ if (NameContains(name, "add_")) return (false);
+ if (NameContains(name, "remove_")) return (false);
+ if (NameContains(name, "raise_")) return (false);
+ }
+
+ // the value field of enumerations is not exposed
+ if (member.IsSpecialName && (type.NodeType == NodeType.EnumNode) && (member.NodeType == NodeType.Field)) {
+ string name = member.Name.Name;
+ if (name == "value__") return (false);
+ }
+
+ // protected members of sealed types are not exposed
+ // change of plan -- yes they are
+ // if (type.IsSealed && (member.IsFamily || member.IsFamilyOrAssembly)) return(false);
+
+ // One more test to deal with a case: a private method is an explicit implementation for
+ // a property accessor, but is not marked with the special name flag. To find these, test for
+ // the accessibility of the methods they implement
+ if (member.IsPrivate && member.NodeType == NodeType.Method) {
+ Method method = (Method)member;
+ MethodList implements = method.ImplementedInterfaceMethods;
+ if ((implements.Count > 0) && (!IsExposedMember(implements[0]))) return (false);
+ }
+
+ // okay, passed all tests, the member is exposed as long as the filters allow it
+ return (base.IsExposedMember(member));
+ }
+
+ // we are satistied with the default namespace expose test, so don't override it
+
+ public override bool IsExposedType(TypeNode type) {
+ if (type == null) throw new ArgumentNullException("type");
+ // expose any visible types allowed by the base filter
+ if (type.IsVisibleOutsideAssembly) {
+ return (base.IsExposedType(type));
+ } else {
+ return (false);
+ }
+ // return(type.IsVisibleOutsideAssembly);
+ }
+
+ private static bool NameContains(string name, string substring) {
+ return (name.Contains(substring));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ExternalFilter.cs b/tools/Sandcastle/Source/Reflection/ExternalFilter.cs
new file mode 100644
index 0000000..ff99bef
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ExternalFilter.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ // exposes all APIs that are visible from outside the assembly
+
+ // this includes property and event accessors (e.g. get_), delegate methods (e.g. Invoke), as well as enumeration members
+
+ public class ExternalFilter : ApiFilter {
+
+ public override bool IsExposedMember(Member member) {
+ if (member == null) throw new ArgumentNullException("member");
+ // expose all visible members
+ return (member.IsVisibleOutsideAssembly);
+ }
+
+ // we are satistied with the default namespace expose test, so don't override it
+
+ public override bool IsExposedType(TypeNode type) {
+ if (type == null) throw new ArgumentNullException("type");
+ // expose all visible types
+ return (type.IsVisibleOutsideAssembly);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/ExternalTopicFilter.cs b/tools/Sandcastle/Source/Reflection/ExternalTopicFilter.cs
new file mode 100644
index 0000000..ed6eae7
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/ExternalTopicFilter.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ // exposes all apis for which a topic exists
+ // this includes all documented members (see DocumentFilter) except for enumeration members
+
+ public class ExternalTopicFilter : ExternalDocumentedFilter {
+
+ public override bool IsExposedMember(Member member) {
+ // don't expose members of enumerations
+ if (member.DeclaringType.NodeType == NodeType.EnumNode) return (false);
+ // otherwise, agree with DocumentedFilter
+ return (base.IsExposedMember(member));
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/GlobalSuppressions.cs b/tools/Sandcastle/Source/Reflection/GlobalSuppressions.cs
new file mode 100644
index 0000000..aff5272
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/GlobalSuppressions.cs
@@ -0,0 +1,55 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools.Reflection")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Namer", Scope = "type", Target = "Microsoft.Ddue.Tools.Reflection.ApiNamer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#CompareMembers(System.Compiler.Member,System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#CompareNamespaces(System.Compiler.Namespace,System.Compiler.Namespace)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.Compare(System.String,System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#CompareTypes(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#CompareNamespaces(System.Compiler.Namespace,System.Compiler.Namespace)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#CompareTypes(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#ResetMscorlib(System.Compiler.AssemblyNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#Assemblies")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ApiVisitor.#AccessoryAssemblies")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#GetName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ReflectionUtilities.#TypeMatch(System.Compiler.TypeNode,System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#GetName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "argument", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#WriteType(System.Compiler.TypeNode,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "arguments", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ReflectionUtilities.#GetTemplateType(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "argument", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#WriteType(System.Compiler.TypeNode,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#WriteType(System.Compiler.TypeNode,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#WriteType(System.Compiler.TypeNode,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Module", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.AssemblyResolver.#ResolveReference(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Module", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.AssemblyResolver.#OnUnresolvedAssemblyReference(System.Compiler.AssemblyReference,System.Compiler.Module)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Namer", Scope = "type", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Namer", Scope = "type", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gac", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.AssemblyResolver.#UseGac")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.AssemblyResolver.#.ctor(System.Xml.XPath.XPathNavigator)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.MemberFilter.#.ctor(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.NamespaceFilter.#.ctor(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.RootFilter.#.ctor(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Convert.ToBoolean(System.String)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.TypeFilter.#.ctor(System.Xml.XmlReader)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.ReflectionUtilities.#GetTemplateType(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#GetMemberName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#GetName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#GetNamespaceName(System.Compiler.Namespace)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#GetTypeName(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#WriteEvent(System.Compiler.Event,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#WriteMethod(System.Compiler.Method,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.OrcasNamer.#WriteProperty(System.Compiler.Property,System.IO.TextWriter)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#GetMemberName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#GetName(System.Compiler.Member)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#GetNamespaceName(System.Compiler.Namespace)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.IO.StringWriter.#ctor", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.WhidbeyNamer.#GetTypeName(System.Compiler.TypeNode)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.RootFilter.#NamespaceFilters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.NamespaceFilter.#TypeFilters")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.NamespaceFilter.#IsExposedNamespace(System.Compiler.Namespace)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Scope = "member", Target = "Microsoft.Ddue.Tools.Reflection.TypeFilter.#IsExposedType(System.Compiler.TypeNode)")]
diff --git a/tools/Sandcastle/Source/Reflection/MemberFilter.cs b/tools/Sandcastle/Source/Reflection/MemberFilter.cs
new file mode 100644
index 0000000..051d589
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/MemberFilter.cs
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class MemberFilter
+ {
+
+#region Member Variables
+
+ private bool exposed;
+
+ private string name;
+
+#endregion
+
+#region Constructors
+ public MemberFilter(string name, bool exposed) {
+ if (name == null) throw new ArgumentNullException("name");
+ this.name = name;
+ this.exposed = exposed;
+ }
+
+ public MemberFilter(XmlReader configuration) {
+ if ((configuration.NodeType != XmlNodeType.Element) || (configuration.Name != "member")) throw new InvalidOperationException();
+ name = configuration.GetAttribute("name");
+ exposed = Convert.ToBoolean(configuration.GetAttribute("expose"));
+ }
+#endregion
+
+#region Public API
+ public bool? IsExposedMember(Member member) {
+ if (member.Name.Name == name) {
+ return (exposed);
+ } else {
+ return (null);
+ }
+ }
+#endregion
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/NamespaceFilter.cs b/tools/Sandcastle/Source/Reflection/NamespaceFilter.cs
new file mode 100644
index 0000000..9a8956c
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/NamespaceFilter.cs
@@ -0,0 +1,143 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class NamespaceFilter
+ {
+
+#region Member Variables
+
+ private bool exposed;
+ private string name;
+
+ private List < TypeFilter > typeFilters = new List < TypeFilter >();
+#endregion
+
+#region Constructors
+ public NamespaceFilter(string name, bool exposed) {
+ this.name = name;
+ this.exposed = exposed;
+ }
+
+ public NamespaceFilter(XmlReader configuration) {
+ if (configuration.Name != "namespace") throw new InvalidOperationException();
+ name = configuration.GetAttribute("name");
+ exposed = Convert.ToBoolean(configuration.GetAttribute("expose"));
+ XmlReader subtree = configuration.ReadSubtree();
+ while (subtree.Read()) {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "type")) {
+ TypeFilter typeFilter = new TypeFilter(subtree);
+ typeFilters.Add(typeFilter);
+ }
+ }
+ subtree.Close();
+ }
+#endregion
+
+#region Public API
+
+ /// <summary>
+ /// Gets the number of type filters
+ /// </summary>
+ public int TypeFilterCount
+ {
+ get
+ {
+ return typeFilters.Count;
+ }
+ }
+
+ public List < TypeFilter > TypeFilters {
+ get {
+ return (typeFilters);
+ {
+ }
+ }
+ }
+
+
+ //Find out if any are exposed incase this class is not exposed
+ public bool HasExposedMembers(TypeNode type)
+ {
+ Namespace space = ReflectionUtilities.GetNamespace(type);
+ if (IsExposedNamespace(space) != null)
+ {
+ foreach (TypeFilter typeFilter in typeFilters)
+ {
+ bool? result = typeFilter.IsExposedType(type);
+ if (result != null) //matched
+ {
+ return typeFilter.HasExposedMembers(type);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public bool? IsExposedMember(Member member) {
+ //Console.WriteLine("DEBUG: namespaceFilter.isExposedMemeber");
+ TypeNode type = ReflectionUtilities.GetTemplateType(member.DeclaringType);
+ Namespace space = ReflectionUtilities.GetNamespace(type);
+ if (IsExposedNamespace(space) != null) {
+ foreach (TypeFilter typeFilter in typeFilters) {
+ bool? result = typeFilter.IsExposedMember(member);
+ if (result != null) return (result);
+ }
+
+ //no filters matched this method, check if the type is exposed
+ bool? typeIsExposed = IsExposedType(type);
+ if (typeIsExposed != null) return typeIsExposed;
+
+ return (exposed); //if the namespace is exposed
+ } else {
+ return (null);
+ }
+ }
+
+ public bool? IsExposedNamespace(Namespace space) {
+ if (space.Name.Name == name) {
+ return (exposed);
+ } else {
+ return (null);
+ }
+ }
+
+ public bool? IsExposedType(TypeNode type) {
+ Namespace space = ReflectionUtilities.GetNamespace(type);
+ if (IsExposedNamespace(space) != null) {
+ foreach (TypeFilter typeFilter in typeFilters) {
+ bool? result = typeFilter.IsExposedType(type);
+ if (result != null) return (result);
+ }
+
+ //no filter matches for this type, check the parents since it could be nested
+ TypeNode parent = type.DeclaringType;
+ while (parent != null)
+ {
+ bool? parentExposed = IsExposedType(parent);
+
+ if (parentExposed != null)
+ return parentExposed;
+
+ parent = type.DeclaringType;
+ }
+
+ //no answer for the parents either, the top parent should pass this back above
+ return (exposed);
+ } else {
+ return (null);
+ }
+ }
+
+#endregion
+ }
+}
diff --git a/tools/Sandcastle/Source/Reflection/NoFilter.cs b/tools/Sandcastle/Source/Reflection/NoFilter.cs
new file mode 100644
index 0000000..0e7b7f5
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/NoFilter.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class NoFilter : ApiFilter {
+
+ public override bool IsExposedApi(Member api) {
+ return (true);
+ }
+
+ public override bool IsExposedMember(Member member) {
+ return (true);
+ }
+
+ public override bool IsExposedNamespace(Namespace space) {
+ return (true);
+ }
+
+ public override bool IsExposedType(TypeNode type) {
+ return (true);
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/Notes.txt b/tools/Sandcastle/Source/Reflection/Notes.txt
new file mode 100644
index 0000000..e5ab15c
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/Notes.txt
@@ -0,0 +1,215 @@
+Entity
+ Name : string
+ Visiblity :
+
+Namespace : Entity
+ Types : Type[]
+
+Type : Entity
+ Namespace : Namespace
+ Interfaces : Interface[]
+ Members : Member[]
+ TemplateArguments : Type[]
+ CustomAttributes : Attribute[]
+ SecurityAttributes :
+ ContainingType : Type
+ Assembly
+
+Class : Type
+ BaseClass : Class
+ DerivedClasses : Class[]
+ IsAbstract : bool
+ IsSealed : bool
+
+Structure : Type
+
+Interface : Type
+
+Delegate : Type
+ Parameters : Parameter[]
+ ReturnType : Type
+
+Enumeration : Type
+ UnderlyingType : Type
+
+TemplateParameter : Type
+ IsValueType : bool
+
+TypeArray : Type
+ Rank : int
+ UnderlyingType : Type
+
+TypePointer : Type
+ UnderlyingType : Type
+
+TypeReference : Type
+ UnderlyingType : Type
+
+Member : Entity
+ IsStatic : bool
+ IsSpecialName : bool
+ DeclaringType : Type
+ Overrides : Member
+ Attributes : Attribute[]
+
+Field : Member
+ Type : Type
+ IsLiteral : bool
+ IsInitOnly : bool
+ IsVolitile : bool
+
+Method : Member
+ Parameters : Parameter[]
+ ReturnType : Type
+ IsAbstract : bool
+ IsVirtual : bool
+ IsFinal : bool
+ IsExtern : bool
+ Implements : Member[]
+
+Constructor : Member
+ Parameters : Parameter[]
+
+Property : Member
+ Parameters : Parameter[]
+ Type : Type
+ IsAbstract : bool
+ IsVirtual : bool
+ IsFinal : bool
+ Implements : Property[]
+ Getter : Method
+ Setter : Method
+
+Event : Member
+ Handler : Delegate
+ IsAbstract : bool
+ IsVirtual : bool
+ IsFinal : bool
+ Implements : Event[]
+ Adder: Method
+ Remover : Method
+ Raiser : Method
+
+Parameter
+ Name : string
+ Type : Type
+ CustomAttributes : Attribute[]
+
+Attribute
+ Type : Type
+ Constructor : Constructor
+ Arguments : Object[]
+
+
+Namespace:
+ <apidata name="System.Web" group="namespace" />
+ <elements />
+
+Type:
+ <apidata name="System.String" group="type" subgroup="class" />
+ <typedata visibility="public" abstract="false" sealed="false" serializable="true" />
+ <containers namespace="N:System" assembly="mscorlib" />
+ <implements />
+ <elements />
+ <attributes />
+
+Class:
+ <classdata parent="T:System.Object" />
+
+Delegate:
+ <parameters />
+ <value />
+
+Enumeration:
+ <enumdata base />
+
+Member:
+ <apidata name="System.String.Length" group="member" subgroup="property" />
+ <memberdata visibility="public" static="false" special="false" />
+ <proceduredata abstract="false" virtual="false" final="false" />
+ <propertydata getter="M:System.String.get_Length" getter-visibility setter setter-visibility />
+ <containers namespace="N:System" type="T:System.String" assembly="mscorlib" />
+
+Field:
+ <fielddata literal initonly volative serialized />
+ <value />
+
+Method:
+ <templates />
+ <parameters />
+ <value />
+
+Event:
+ <eventdata handler adder remover args />
+
+
+
+Namespace:
+<entityProperties name="System.Web" group="namespace" />
+
+Class:
+<entityProperties name="Console" visibility="public" group="type" subgroup="class" />
+<typeProperties namespace="N:System" abstract="true" sealed="true" />
+
+Method:
+<entityProperties name="AsReadOnly" visiblity="public" group="member" subgroup="method" />
+<memberProperties type="T:System.Array" static="true" special="false" abstract="false" virtual="false" final="true" />
+
+
+entityProperties
+ name
+ group
+ subgroup
+ subsubgroup
+
+typeProperties
+ namespace
+ assembly
+ abstract
+ sealed
+ parent
+ container
+
+memberProperties
+ type
+ static
+ special
+ literal
+ initonly
+ volitile
+ abstract
+ virtual
+ final
+ extern
+
+
+<entityInfo name="Boo" visiblity="protected" group="type" />
+<typeInfo namespace="N:Foo" container="T:Foo.Barrel" assembly="mscorlib.dll" subgroup="class" />
+<classInfo base="T:System.Object" abstract="false" sealed="false" />
+<templates>
+ <template name="TKey" />
+ <template name="TValue" />
+</templates>
+<interfaces>
+ <interface type="T:Foo.IBoo" />
+</interfaces>
+<attributes>
+ <attribute type="T:Foo.MyAttribute" constructor="T:Foo.MyAttribute.#ctor(System.Boolean)" />
+ <parameter name="visible" type="T:System.Boolean" value="true" />
+ </attribute>
+</attributes>
+<members>
+ <member member="M:Foo.Boo.#ctor" />
+ <member member="P:Foo.Boo.Value" />
+</members>
+
+<entity name="Moo" visibility="protected" group="method" />
+<memberInfo type="T:Foo.Boo" static="false" special="false" subgroup="method" />
+<methodnfo abstract="false" virtual="true" />
+<parameters>
+ <parameter name="x" type="T:`0" />
+<parameters>
+<value type="T:System.Int32" />
+<implements>
+ <implement type="T:Foo.IBoo" member="M:Foo.IBoo.Choo" />
+</implements>
diff --git a/tools/Sandcastle/Source/Reflection/OrcasNamer.cs b/tools/Sandcastle/Source/Reflection/OrcasNamer.cs
new file mode 100644
index 0000000..806c7a2
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/OrcasNamer.cs
@@ -0,0 +1,376 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+// using System.Collections.Generic;
+using System.IO;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class OrcasNamer : ApiNamer {
+
+ public override string GetMemberName(Member member) {
+
+ using (TextWriter writer = new StringWriter()) {
+
+ switch (member.NodeType) {
+ case NodeType.Field:
+ writer.Write("F:");
+ WriteField((Field)member, writer);
+ break;
+ case NodeType.Property:
+ writer.Write("P:");
+ WriteProperty((Property)member, writer);
+ break;
+ case NodeType.Method:
+ writer.Write("M:");
+ WriteMethod((Method)member, writer);
+ break;
+ case NodeType.InstanceInitializer:
+ writer.Write("M:");
+ WriteConstructor((InstanceInitializer)member, writer);
+ break;
+ case NodeType.StaticInitializer:
+ writer.Write("M:");
+ WriteStaticConstructor((StaticInitializer)member, writer);
+ break;
+ case NodeType.Event:
+ writer.Write("E:");
+ WriteEvent((Event)member, writer);
+ break;
+ }
+
+ return (writer.ToString());
+
+ }
+
+ }
+
+ public override string GetNamespaceName(Namespace space) {
+ using (TextWriter writer = new StringWriter()) {
+ writer.Write("N:");
+ WriteNamespace(space, writer);
+ return (writer.ToString());
+ }
+ }
+
+ public override string GetTypeName(TypeNode type) {
+ using (TextWriter writer = new StringWriter()) {
+ writer.Write("T:");
+ WriteType(type, writer);
+ return (writer.ToString());
+ }
+ }
+
+
+ private static string GetName(Member entity) {
+
+ using (TextWriter writer = new StringWriter()) {
+
+ TypeNode type = entity as TypeNode;
+ if (type != null) {
+ writer.Write("T:");
+ WriteType(type, writer);
+ return (writer.ToString());
+ }
+
+ switch (entity.NodeType) {
+ case NodeType.Namespace:
+ writer.Write("N:");
+ WriteNamespace(entity as Namespace, writer);
+ break;
+ case NodeType.Field:
+ writer.Write("F:");
+ WriteField(entity as Field, writer);
+ break;
+ case NodeType.Property:
+ writer.Write("P:");
+ WriteProperty(entity as Property, writer);
+ break;
+ case NodeType.Method:
+ writer.Write("M:");
+ WriteMethod(entity as Method, writer);
+ break;
+ case NodeType.InstanceInitializer:
+ writer.Write("M:");
+ WriteConstructor(entity as InstanceInitializer, writer);
+ break;
+ case NodeType.StaticInitializer:
+ writer.Write("M:");
+ WriteStaticConstructor(entity as StaticInitializer, writer);
+ break;
+ case NodeType.Event:
+ writer.Write("E:");
+ WriteEvent(entity as Event, writer);
+ break;
+ }
+
+ return (writer.ToString());
+
+ }
+
+ }
+
+ private static void WriteConstructor(InstanceInitializer constructor, TextWriter writer) {
+ WriteType(constructor.DeclaringType, writer);
+ writer.Write(".#ctor");
+ WriteParameters(constructor.Parameters, writer);
+ }
+
+ private static void WriteEvent(Event trigger, TextWriter writer) {
+ WriteType(trigger.DeclaringType, writer);
+
+ Event eiiTrigger = null;
+ if (trigger.IsPrivate && trigger.IsVirtual) {
+ Event[] eiiTriggers = ReflectionUtilities.GetImplementedEvents(trigger);
+ if (eiiTriggers.Length > 0) eiiTrigger = eiiTriggers[0];
+ }
+
+ if (eiiTrigger != null) {
+ TypeNode eiiType = eiiTrigger.DeclaringType;
+ TextWriter eiiWriter = new StringWriter();
+
+ if (eiiType != null && eiiType.Template != null)
+ {
+ writer.Write(".");
+ WriteTemplate(eiiType, writer);
+ }
+ else
+ {
+ WriteType(eiiType, eiiWriter);
+ writer.Write(".");
+ writer.Write(eiiWriter.ToString().Replace('.', '#'));
+ }
+
+ writer.Write("#");
+ writer.Write(eiiTrigger.Name.Name);
+ } else {
+ writer.Write(".{0}", trigger.Name.Name);
+ }
+ }
+
+ private static void WriteField(Field field, TextWriter writer) {
+ WriteType(field.DeclaringType, writer);
+ writer.Write(".{0}", field.Name.Name);
+ }
+
+ private static void WriteMethod(Method method, TextWriter writer) {
+ string name = method.Name.Name;
+ WriteType(method.DeclaringType, writer);
+
+ Method eiiMethod = null;
+ if (method.IsPrivate && method.IsVirtual) {
+ MethodList eiiMethods = method.ImplementedInterfaceMethods;
+ if (eiiMethods.Count > 0) eiiMethod = eiiMethods[0];
+ }
+ if (eiiMethod != null) { //explicitly implemented interface
+ TypeNode eiiType = eiiMethod.DeclaringType;
+ TextWriter eiiWriter = new StringWriter();
+
+
+ //we need to keep the param names instead of turning them into numbers
+ //get the template to the right format
+ if (eiiType != null && eiiType.Template != null)
+ {
+ writer.Write(".");
+ WriteTemplate(eiiType, writer);
+ }
+ else //revert back to writing the type the old way if there is no template
+ {
+ WriteType(eiiType, eiiWriter);
+ writer.Write(".");
+ writer.Write(eiiWriter.ToString().Replace('.', '#'));
+ }
+
+ writer.Write("#");
+ writer.Write(eiiMethod.Name.Name);
+ } else {
+ writer.Write(".{0}", name);
+ }
+ if (method.IsGeneric) {
+ TypeNodeList genericParameters = method.TemplateParameters;
+ if (genericParameters != null) {
+ writer.Write("``{0}", genericParameters.Count);
+ }
+ }
+ WriteParameters(method.Parameters, writer);
+ // add ~ for conversion operators
+ if ((name == "op_Implicit") || (name == "op_Explicit")) {
+ writer.Write("~");
+ WriteType(method.ReturnType, writer);
+ }
+
+ }
+
+ // The actual logic to construct names
+
+ private static void WriteNamespace(Namespace space, TextWriter writer) {
+ writer.Write(space.Name);
+ }
+
+ private static void WriteParameters(ParameterList parameters, TextWriter writer) {
+ if ((parameters == null) || (parameters.Count == 0)) return;
+ writer.Write("(");
+ for (int i = 0; i < parameters.Count; i++) {
+ if (i > 0) writer.Write(",");
+ WriteType(parameters[i].Type, writer);
+ }
+ writer.Write(")");
+ }
+
+ private static void WriteProperty(Property property, TextWriter writer) {
+ WriteType(property.DeclaringType, writer);
+ //Console.WriteLine( "{0}::{1}", property.DeclaringType.FullName, property.Name );
+
+ Property eiiProperty = null;
+ if (property.IsPrivate && property.IsVirtual) {
+ Property[] eiiProperties = ReflectionUtilities.GetImplementedProperties(property);
+ if (eiiProperties.Length > 0) eiiProperty = eiiProperties[0];
+ }
+
+
+
+ if (eiiProperty != null) {
+ TypeNode eiiType = eiiProperty.DeclaringType;
+ TextWriter eiiWriter = new StringWriter();
+
+
+ if (eiiType != null && eiiType.Template != null)
+ {
+ writer.Write(".");
+ WriteTemplate(eiiType, writer);
+ }
+ else
+ {
+ WriteType(eiiType, eiiWriter);
+ writer.Write(".");
+ writer.Write(eiiWriter.ToString().Replace('.', '#'));
+ }
+
+ writer.Write("#");
+ writer.Write(eiiProperty.Name.Name);
+ } else {
+ writer.Write(".{0}", property.Name.Name);
+ }
+ ParameterList parameters = property.Parameters;
+ WriteParameters(parameters, writer);
+ }
+
+ private static void WriteStaticConstructor(StaticInitializer constructor, TextWriter writer) {
+ WriteType(constructor.DeclaringType, writer);
+ writer.Write(".#cctor");
+ WriteParameters(constructor.Parameters, writer);
+ }
+
+ /// <summary>
+ /// Used for explicitly implemented interfaces to convert the template to the
+ /// format used in the comments file.
+ /// </summary>
+ /// <param name="type">EII Type</param>
+ /// <param name="writer"></param>
+ private static void WriteTemplate(TypeNode eiiType, TextWriter writer)
+ {
+ string eiiClean = eiiType.Template.ToString();
+ eiiClean = eiiClean.Replace('.', '#');
+ eiiClean = eiiClean.Replace(',', '@'); //change the seperator between params
+ eiiClean = eiiClean.Replace('<', '{'); //change the parameter brackets
+ eiiClean = eiiClean.Replace('>', '}');
+ writer.Write(eiiClean);
+ }
+
+ private static void WriteType(TypeNode type, TextWriter writer) {
+ switch (type.NodeType) {
+ case NodeType.ArrayType:
+ ArrayType array = type as ArrayType;
+ WriteType(array.ElementType, writer);
+ writer.Write("[");
+ if (array.Rank > 1) {
+ for (int i = 0; i < array.Rank; i++) {
+ if (i > 0) writer.Write(",");
+ writer.Write("0:");
+ }
+ }
+ writer.Write("]");
+ break;
+ case NodeType.Reference:
+ Reference reference = type as Reference;
+ TypeNode referencedType = reference.ElementType;
+ WriteType(referencedType, writer);
+ writer.Write("@");
+ break;
+ case NodeType.Pointer:
+ Pointer pointer = type as Pointer;
+ WriteType(pointer.ElementType, writer);
+ writer.Write("*");
+ break;
+ case NodeType.OptionalModifier:
+ TypeModifier optionalModifierClause = type as TypeModifier;
+ WriteType(optionalModifierClause.ModifiedType, writer);
+ writer.Write("!");
+ WriteType(optionalModifierClause.Modifier, writer);
+ break;
+ case NodeType.RequiredModifier:
+ TypeModifier requiredModifierClause = type as TypeModifier;
+ WriteType(requiredModifierClause.ModifiedType, writer);
+ writer.Write("|");
+ WriteType(requiredModifierClause.Modifier, writer);
+ break;
+ default:
+ if (type.IsTemplateParameter) {
+ ITypeParameter gtp = (ITypeParameter)type;
+ if (gtp.DeclaringMember is TypeNode) {
+ writer.Write("`");
+ } else if (gtp.DeclaringMember is Method) {
+ writer.Write("``");
+ } else {
+ throw new InvalidOperationException("Generic parameter not on type or method.");
+ }
+ writer.Write(gtp.ParameterListIndex);
+ } else {
+ // namespace
+ TypeNode declaringType = type.DeclaringType;
+ if (declaringType != null) {
+ // names of nested types begin with outer type name
+ WriteType(declaringType, writer);
+ writer.Write(".");
+ } else {
+ // otherwise just prepend the namespace
+ Identifier space = type.Namespace;
+ if ((space != null) && !String.IsNullOrEmpty(space.Name)) {
+ //string space = type.Namespace.Name;
+ //if (space != null && space.Length > 0) {
+ writer.Write(space.Name);
+ writer.Write(".");
+ }
+ }
+ // name
+ writer.Write(type.GetUnmangledNameWithoutTypeParameters());
+ // generic parameters
+ if (type.IsGeneric) {
+ // number of parameters
+ TypeNodeList parameters = type.TemplateParameters;
+ if (parameters != null) {
+ writer.Write("`{0}", parameters.Count);
+ }
+ // arguments
+ TypeNodeList arguments = type.TemplateArguments;
+ if ((arguments != null) && (arguments.Count > 0)) {
+ writer.Write("{");
+ for (int i = 0; i < arguments.Count; i++) {
+ TypeNode argument = arguments[i];
+ if (i > 0) writer.Write(",");
+ WriteType(arguments[i], writer);
+ }
+ writer.Write("}");
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/Reflection/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a18dd70
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Reflection")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Reflection")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(false)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("649c6153-4fdf-419d-96d3-236bae5d5749")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/Reflection/Reflection.cs b/tools/Sandcastle/Source/Reflection/Reflection.cs
new file mode 100644
index 0000000..e646cc6
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/Reflection.cs
@@ -0,0 +1,298 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public static class ReflectionUtilities {
+
+ public static Event[] GetImplementedEvents(Event trigger) {
+ List < Event > list = new List < Event >();
+
+ // get the adder
+ Method adder = trigger.HandlerAdder;
+
+ // get interface methods corresponding to this adder
+ Method[] implementedAdders = GetImplementedMethods(adder);
+
+ // get the events corresponding to the implemented adders
+ foreach (Method implementedAdder in implementedAdders) {
+ Event implementedTrigger = GetEventFromAdder(implementedAdder);
+ if (implementedTrigger != null) list.Add(implementedTrigger);
+ }
+
+ return (list.ToArray());
+
+ }
+
+ public static Method[] GetImplementedMethods(Method method) {
+ List < Method > list = new List < Method >();
+
+ // Explicit implementations
+ MethodList explicitImplementations = method.ImplementedInterfaceMethods;
+ if (explicitImplementations != null) {
+ for (int i = 0; i < explicitImplementations.Count; i++) {
+ Method explicitImplementation = explicitImplementations[i];
+ list.Add(explicitImplementation);
+ }
+ }
+
+ // Implicit implementations
+ MethodList implicitImplementations = method.ImplicitlyImplementedInterfaceMethods;
+ if (implicitImplementations != null) {
+ for (int i = 0; i < implicitImplementations.Count; i++) {
+ Method implicitImplementation = implicitImplementations[i];
+ list.Add(implicitImplementation);
+ }
+ }
+
+ return (list.ToArray());
+ }
+
+ public static Property[] GetImplementedProperties(Property property) {
+ List < Property > list = new List < Property >();
+
+ // get an accessor
+ Method accessor = property.Getter;
+ if (accessor == null) accessor = property.Setter;
+ if (accessor == null) return (new Property[0]);
+
+ // get the interface methods corresponding to this accessor
+ Method[] methods = GetImplementedMethods(accessor);
+
+ // look for properties corresponding to these methods
+ for (int i = 0; i < methods.Length; i++) {
+ Method method = methods[i];
+ Property entry = GetPropertyFromAccessor(method);
+ if (entry != null) list.Add(entry);
+ }
+
+ return (list.ToArray());
+ }
+
+ public static Namespace GetNamespace(TypeNode type) {
+ if (type.DeclaringType != null) {
+ return (GetNamespace(type.DeclaringType));
+ } else {
+ return (new Namespace(type.Namespace));
+ }
+ }
+
+ public static Member GetTemplateMember(Member member) {
+
+ if (member == null) throw new ArgumentNullException("member");
+
+ // if the containing type isn't generic, the member is the template member
+ TypeNode type = member.DeclaringType;
+ if (!type.IsGeneric) return (member);
+
+ // if the containing type isn't specialized, the member is the template member
+ if (!IsSpecialized(type)) return (member);
+
+ // get the template type, and look for members with the same name
+ TypeNode template = ReflectionUtilities.GetTemplateType(member.DeclaringType);
+ Identifier name = member.Name;
+ MemberList candidates = template.GetMembersNamed(name);
+
+ // if no candidates, say so (this shouldn't happen)
+ if (candidates.Count == 0) throw new InvalidOperationException("No members in the template had the name found in the specialization. This is not possible, but apparently it happened.");
+
+ // if only one candidate, return it
+ if (candidates.Count == 1) return (candidates[0]);
+
+ // multiple candidates, so now we need to compare parameters
+ ParameterList parameters = GetParameters(member);
+
+ for (int i = 0; i < candidates.Count; i++) {
+ Member candidate = candidates[i];
+
+ // candidate must be same kind of node
+ if (candidate.NodeType != member.NodeType) continue;
+
+ // if parameters match, this is the one
+ if (ParametersMatch(parameters, GetParameters(candidate))) return (candidate);
+
+ }
+
+ Console.WriteLine(member.DeclaringType.FullName);
+ Console.WriteLine(member.FullName);
+ throw new InvalidOperationException("No members in the template matched the parameters of the specialization. This is not possible.");
+ }
+
+ public static TypeNode GetTemplateType(TypeNode type) {
+
+ if (type == null) throw new ArgumentNullException("type");
+ // Console.WriteLine(type.FullName);
+
+ // only generic types have templates
+ if (!type.IsGeneric) return (type);
+
+ if (type.DeclaringType == null) {
+ // if the type is not nested, life is simpler
+
+ // if the type is not specified, the type is the template
+ if (type.TemplateArguments == null) return (type);
+
+ // otherwise, construct the template type identifier and use it to fetch the template type
+ Module templateModule = type.DeclaringModule;
+ Identifier name = new Identifier(String.Format("{0}`{1}", type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count));
+ Identifier space = type.Namespace;
+ TypeNode template = templateModule.GetType(space, name);
+ return (template);
+ } else {
+ // if the type is nested, life is harder; we have to walk up the chain, constructing
+ // un-specialized identifiers as we go, then walk back down the chain, fetching
+ // template types as we go
+
+ // create a stack to keep track of identifiers
+ Stack < Identifier > identifiers = new Stack < Identifier >();
+
+ // populate the stack with the identifiers of all the types up to the outermost type
+ TypeNode current = type;
+ while (true) {
+ int count = 0;
+ if ((current.TemplateArguments != null) && (current.TemplateArguments.Count > count)) count = current.TemplateArguments.Count;
+ if ((current.TemplateParameters != null) && (current.TemplateParameters.Count > count)) count = current.TemplateParameters.Count;
+ TypeNodeList arguments = current.TemplateParameters;
+ if (count == 0) {
+ identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters()));
+ } else {
+ identifiers.Push(new Identifier(String.Format("{0}`{1}", current.GetUnmangledNameWithoutTypeParameters(), count)));
+ }
+ // Console.WriteLine("U {0} {1}", identifiers.Peek(), CountArguments(current));
+ if (current.DeclaringType == null) break;
+ current = current.DeclaringType;
+ }
+
+ // fetch a TypeNode representing that outermost type
+ Module module = current.DeclaringModule;
+ Identifier space = current.Namespace;
+ current = module.GetType(space, identifiers.Pop());
+
+ // move down the stack to the inner type we want
+ while (identifiers.Count > 0) {
+ current = (TypeNode)current.GetMembersNamed(identifiers.Pop())[0];
+ // Console.WriteLine("D {0} {1}", current.GetFullUnmangledNameWithTypeParameters(), CountArguments(current));
+ }
+
+ // whew, finally we've got it
+ return (current);
+ }
+
+ }
+
+ public static bool IsDefaultMember(Member member) {
+
+ if (member == null) throw new ArgumentNullException("member");
+ TypeNode type = member.DeclaringType;
+
+ MemberList defaultMembers = type.DefaultMembers;
+ for (int i = 0; i < defaultMembers.Count; i++) {
+ Member defaultMember = defaultMembers[i];
+ if (member == defaultMember) return (true);
+ }
+ return (false);
+
+ }
+
+ private static Event GetEventFromAdder(Method adder) {
+ if (adder == null) throw new ArgumentNullException("adder");
+ TypeNode type = adder.DeclaringType;
+ MemberList members = type.Members;
+ foreach (Member member in members) {
+ if (member.NodeType != NodeType.Event) continue;
+ Event trigger = member as Event;
+ if (trigger.HandlerAdder == adder) return (trigger);
+ }
+ return (null);
+ }
+
+ private static ParameterList GetParameters(Member member) {
+ Method method = member as Method;
+ if (method != null) return (method.Parameters);
+
+ Property property = member as Property;
+ if (property != null) return (property.Parameters);
+
+ return (new ParameterList());
+ }
+
+ private static Property GetPropertyFromAccessor(Method accessor) {
+ if (accessor == null) throw new ArgumentNullException("accessor");
+ TypeNode type = accessor.DeclaringType;
+ MemberList members = type.Members;
+ foreach (Member member in members) {
+ if (member.NodeType != NodeType.Property) continue;
+ Property property = member as Property;
+ if (property.Getter == accessor) return (property);
+ if (property.Setter == accessor) return (property);
+ }
+ return (null);
+ }
+
+ private static bool IsSpecialized(TypeNode type) {
+ for (TypeNode t = type; t != null; t = t.DeclaringType) {
+ TypeNodeList templates = t.TemplateArguments;
+ if ((templates != null) && (templates.Count > 0)) return (true);
+ }
+ return (false);
+ }
+
+ // parameters1 should be fully specialized; parameters2
+
+ private static bool ParametersMatch(ParameterList parameters1, ParameterList parameters2) {
+
+ if (parameters1.Count != parameters2.Count) return (false);
+
+ for (int i = 0; i < parameters1.Count; i++) {
+ TypeNode type1 = parameters1[i].Type;
+ TypeNode type2 = parameters2[i].Type;
+
+ // we can't determine the equivilence of template parameters; this is probably not good
+ if (type1.IsTemplateParameter || type2.IsTemplateParameter) continue;
+
+ // the node type must be the same; this is probably a fast check
+ if (type1.NodeType != type2.NodeType) return (false);
+
+ // if they are "normal" types, we will compare them
+ // comparing arrays, pointers, etc. is dangerous, because the types they contian may be template parameters
+ if ((type1.NodeType == NodeType.Class) || (type1.NodeType == NodeType.Struct) || (type1.NodeType == NodeType.Interface) ||
+ (type1.NodeType == NodeType.EnumNode) || (type1.NodeType == NodeType.DelegateNode)) {
+ type1 = GetTemplateType(type1);
+ type2 = GetTemplateType(type2);
+ if (!type2.IsStructurallyEquivalentTo(type1)) {
+ // Console.WriteLine("{0} !~ {1}", type1.FullName, type2.FullName);
+ return (false);
+ } else {
+ // Console.WriteLine("{0} ~ {1}", type1.FullName, type2.FullName);
+ }
+ }
+
+ }
+
+ return (true);
+ }
+
+ private static bool TypeMatch(TypeNode type1, TypeNode type2) {
+
+ // the two types must be of the same kind
+ if (type1.NodeType != type2.NodeType) return (false);
+
+ if (type1.NodeType == NodeType.ArrayType) {
+ // they are arrays, so check elements
+ ArrayType array1 = (ArrayType)type1;
+ ArrayType array2 = (ArrayType)type2;
+ return (TypeMatch(array1.ElementType, array2.ElementType));
+ } else {
+ // they are normal types
+ return (type1.IsStructurallyEquivalentTo(type2));
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/Reflection.csproj b/tools/Sandcastle/Source/Reflection/Reflection.csproj
new file mode 100644
index 0000000..9a88afa
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/Reflection.csproj
@@ -0,0 +1,107 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{74F5EB3F-DC99-4FBE-9495-EE378FC60F65}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Reflection</RootNamespace>
+ <AssemblyName>Reflection</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AllDocumentedFilter.cs" />
+ <Compile Include="AllTopicFilter.cs" />
+ <Compile Include="ApiFilter.cs" />
+ <Compile Include="ApiNamer.cs" />
+ <Compile Include="ApiVisitor.cs" />
+ <Compile Include="AssemblyReferenceEventArgs.cs" />
+ <Compile Include="AssemblyResolver.cs" />
+ <Compile Include="ExternalDocumentedFilter.cs" />
+ <Compile Include="ExternalFilter.cs" />
+ <Compile Include="ExternalTopicFilter.cs" />
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="MemberFilter.cs" />
+ <Compile Include="NamespaceFilter.cs" />
+ <Compile Include="NoFilter.cs" />
+ <Compile Include="OrcasNamer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Reflection.cs" />
+ <Compile Include="RootFilter.cs" />
+ <Compile Include="TestResolver.cs" />
+ <Compile Include="TypeFilter.cs" />
+ <Compile Include="WhidbeyNamer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CCI\CCI.csproj">
+ <Project>{4CB332D6-976E-44F6-A320-A515A9D1D1D3}</Project>
+ <Name>CCI</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/Reflection/RootFilter.cs b/tools/Sandcastle/Source/Reflection/RootFilter.cs
new file mode 100644
index 0000000..63401a5
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/RootFilter.cs
@@ -0,0 +1,126 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class RootFilter
+ {
+
+#region Member Variables
+ private bool exposed;
+
+ private List < NamespaceFilter > namespaceFilters = new List < NamespaceFilter >();
+#endregion
+
+#region Constructors
+
+ public RootFilter(bool exposed) {
+ this.exposed = exposed;
+ }
+
+ public RootFilter(XmlReader configuration) {
+ exposed = Convert.ToBoolean(configuration.GetAttribute("expose"));
+ XmlReader subtree = configuration.ReadSubtree();
+ while (subtree.Read()) {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "namespace")) {
+ NamespaceFilter namespaceFilter = new NamespaceFilter(subtree);
+ namespaceFilters.Add(namespaceFilter);
+ }
+ }
+ subtree.Close();
+ }
+#endregion
+
+#region Public API
+
+ /// <summary>
+ /// Gets the exposed value from the config
+ /// </summary>
+ public bool ExposedFilterSetting
+ {
+ get
+ {
+ return exposed;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of namespace filters
+ /// </summary>
+ public int NamespaceFilterCount
+ {
+ get
+ {
+ return namespaceFilters.Count;
+ }
+ }
+
+ public List < NamespaceFilter > NamespaceFilters {
+ get {
+ return (namespaceFilters);
+ }
+ }
+
+ //Find out if any are exposed incase this class is not exposed
+ public bool HasExposedMembers(TypeNode type)
+ {
+ foreach (NamespaceFilter namespaceFilter in namespaceFilters)
+ {
+ bool? result = namespaceFilter.IsExposedType(type);
+ if (result != null)
+ {
+ return namespaceFilter.HasExposedMembers(type);
+ }
+ }
+ return false;
+ }
+
+ public bool IsExposedApi(Member api) {
+
+ Namespace space = api as Namespace;
+ if (space != null) return (IsExposedNamespace(space));
+
+ TypeNode type = api as TypeNode;
+ if (type != null) return (IsExposedType(type));
+
+ return (IsExposedMember(api));
+
+ }
+
+
+ public bool IsExposedMember(Member member) {
+ //Console.WriteLine("DEBUG: root.IsExposedMember");
+ foreach (NamespaceFilter namespaceFilter in namespaceFilters) {
+ bool? result = namespaceFilter.IsExposedMember(member);
+ if (result != null) return ((bool)result);
+ }
+ return (exposed);
+ }
+
+ public bool IsExposedNamespace(Namespace space) {
+ foreach (NamespaceFilter namespaceFilter in namespaceFilters) {
+ bool? result = namespaceFilter.IsExposedNamespace(space);
+ if (result != null) return ((bool)result);
+ }
+ return (exposed);
+ }
+
+ public bool IsExposedType(TypeNode type) {
+ foreach (NamespaceFilter namespaceFilter in namespaceFilters) {
+ bool? result = namespaceFilter.IsExposedType(type);
+ if (result != null) return ((bool)result);
+ }
+
+ return (exposed);
+ }
+
+#endregion
+ }
+}
diff --git a/tools/Sandcastle/Source/Reflection/TestResolver.cs b/tools/Sandcastle/Source/Reflection/TestResolver.cs
new file mode 100644
index 0000000..5ad9c46
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/TestResolver.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class TestResolver : AssemblyResolver {
+
+ public TestResolver(XPathNavigator configuration) : base(configuration) { }
+
+ public override AssemblyNode ResolveReference(AssemblyReference reference, Module module) {
+ Console.WriteLine("test resolver: {0}", reference.StrongName);
+ return (base.ResolveReference(reference, module));
+ }
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Reflection/TypeFilter.cs b/tools/Sandcastle/Source/Reflection/TypeFilter.cs
new file mode 100644
index 0000000..de7a3fa
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/TypeFilter.cs
@@ -0,0 +1,120 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class TypeFilter
+ {
+
+#region Member Variables
+
+ private bool exposed;
+
+ private List < MemberFilter > memberFilters = new List < MemberFilter >();
+
+ private string name;
+
+#endregion
+
+#region Constructors
+ public TypeFilter(string name, bool exposed) {
+ if (name == null) throw new ArgumentNullException("name");
+ this.name = name;
+ this.exposed = exposed;
+ }
+
+ public TypeFilter(XmlReader configuration) {
+ if ((configuration.NodeType != XmlNodeType.Element) || (configuration.Name != "type")) throw new InvalidOperationException();
+ name = configuration.GetAttribute("name");
+ exposed = Convert.ToBoolean(configuration.GetAttribute("expose"));
+ XmlReader subtree = configuration.ReadSubtree();
+ while (subtree.Read()) {
+ if ((subtree.NodeType == XmlNodeType.Element) && (subtree.Name == "member")) {
+ MemberFilter memberFilter = new MemberFilter(subtree);
+ memberFilters.Add(memberFilter);
+ }
+ }
+ subtree.Close();
+ }
+#endregion
+
+#region Public API
+
+ //Find out if any are exposed incase this class is not exposed
+ public bool HasExposedMembers(TypeNode type)
+ {
+ foreach (Member member in type.Members)
+ foreach (MemberFilter memberFilter in memberFilters)
+ if (memberFilter.IsExposedMember(member) == true)
+ return true;
+
+ return false;
+ }
+
+
+ public bool? IsExposedMember(Member member) {
+ //Console.WriteLine("DEBUG: typeFilter.IsExposedMember");
+ TypeNode type = ReflectionUtilities.GetTemplateType(member.DeclaringType);
+ if (IsExposedType(type) != null) {
+ foreach (MemberFilter memberFilter in memberFilters) {
+ bool? result = memberFilter.IsExposedMember(member);
+ if (result != null) return (result);
+ }
+
+ return (exposed); //return the type's exposed setting
+ } else {
+ return (null);
+ }
+ }
+
+ /**
+ * <summary>IsExposedType compares the given type to itself. If this filter
+ * contains a '.' designating it as for a nested class it will skip
+ * non-nested classes. Classes with no declaring types will not be compared to
+ * filters with a '.'
+ * </summary>
+ */
+ public bool? IsExposedType(TypeNode type)
+ {
+ bool? typeIsExposed = null;
+
+ //check if the type was nested
+ if (type.DeclaringType == null)
+ {
+ if (type.Name.Name == name)
+ typeIsExposed = exposed;
+ }
+ //if we are nested then check if this filter is for a nested class
+ //check that nothing used is null also.
+ //if the name attribute is not there in the config name can be null here.
+ else if (name != null && name.Contains("."))
+ {
+ //Get a stack of declaring type names
+ Stack < string > parentNames = new Stack < string >();
+ parentNames.Push(type.Name.Name); //start with this one
+
+ TypeNode parent = type.DeclaringType;
+ while (parent != null)
+ {
+ parentNames.Push(parent.Name.Name);
+ parent = parent.DeclaringType;
+ }
+
+ //put them back in the correct order and check the name
+ if (name.Equals(String.Join(".", parentNames.ToArray())))
+ typeIsExposed = exposed;
+ }
+
+ return typeIsExposed;
+ }
+
+#endregion
+ }
+}
diff --git a/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs b/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs
new file mode 100644
index 0000000..f6234a8
--- /dev/null
+++ b/tools/Sandcastle/Source/Reflection/WhidbeyNamer.cs
@@ -0,0 +1,275 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+using System.Compiler;
+
+namespace Microsoft.Ddue.Tools.Reflection {
+
+ public class WhidbeyNamer : ApiNamer {
+
+ public override string GetMemberName(Member member) {
+
+ using (TextWriter writer = new StringWriter()) {
+
+ switch (member.NodeType) {
+ case NodeType.Field:
+ writer.Write("F:");
+ WriteField((Field)member, writer);
+ break;
+ case NodeType.Property:
+ writer.Write("P:");
+ WriteProperty((Property)member, writer);
+ break;
+ case NodeType.Method:
+ writer.Write("M:");
+ WriteMethod((Method)member, writer);
+ break;
+ case NodeType.InstanceInitializer:
+ writer.Write("M:");
+ WriteConstructor((InstanceInitializer)member, writer);
+ break;
+ case NodeType.StaticInitializer:
+ writer.Write("M:");
+ WriteStaticConstructor((StaticInitializer)member, writer);
+ break;
+ case NodeType.Event:
+ writer.Write("E:");
+ WriteEvent((Event)member, writer);
+ break;
+ }
+
+ return (writer.ToString());
+
+ }
+
+ }
+
+ public override string GetNamespaceName(Namespace space) {
+ using (TextWriter writer = new StringWriter()) {
+ writer.Write("N:");
+ WriteNamespace(space, writer);
+ return (writer.ToString());
+ }
+ }
+
+ public override string GetTypeName(TypeNode type) {
+ using (TextWriter writer = new StringWriter()) {
+ writer.Write("T:");
+ WriteType(type, writer);
+ return (writer.ToString());
+ }
+ }
+
+
+ private static string GetName(Member entity) {
+
+ using (TextWriter writer = new StringWriter()) {
+
+ TypeNode type = entity as TypeNode;
+ if (type != null) {
+ writer.Write("T:");
+ WriteType(type, writer);
+ return (writer.ToString());
+ }
+
+ switch (entity.NodeType) {
+ case NodeType.Namespace:
+ writer.Write("N:");
+ WriteNamespace(entity as Namespace, writer);
+ break;
+ case NodeType.Field:
+ writer.Write("F:");
+ WriteField(entity as Field, writer);
+ break;
+ case NodeType.Property:
+ writer.Write("P:");
+ WriteProperty(entity as Property, writer);
+ break;
+ case NodeType.Method:
+ writer.Write("M:");
+ WriteMethod(entity as Method, writer);
+ break;
+ case NodeType.InstanceInitializer:
+ writer.Write("M:");
+ WriteConstructor(entity as InstanceInitializer, writer);
+ break;
+ case NodeType.StaticInitializer:
+ writer.Write("M:");
+ WriteStaticConstructor(entity as StaticInitializer, writer);
+ break;
+ case NodeType.Event:
+ writer.Write("E:");
+ WriteEvent(entity as Event, writer);
+ break;
+ }
+
+ return (writer.ToString());
+
+ }
+
+ }
+
+ private static void WriteConstructor(InstanceInitializer constructor, TextWriter writer) {
+ WriteType(constructor.DeclaringType, writer);
+ writer.Write(".#ctor");
+ WriteParameters(constructor.Parameters, writer);
+ }
+
+ private static void WriteEvent(Event trigger, TextWriter writer) {
+ WriteType(trigger.DeclaringType, writer);
+ writer.Write(".{0}", trigger.Name.Name);
+ }
+
+ private static void WriteField(Field field, TextWriter writer) {
+ WriteType(field.DeclaringType, writer);
+ writer.Write(".{0}", field.Name.Name);
+ }
+
+ private static void WriteMethod(Method method, TextWriter writer) {
+ string name = method.Name.Name;
+ WriteType(method.DeclaringType, writer);
+ writer.Write(".{0}", name);
+ if (method.IsGeneric) {
+ TypeNodeList genericParameters = method.TemplateParameters;
+ if (genericParameters != null) {
+ writer.Write("``{0}", genericParameters.Count);
+ }
+ }
+ WriteParameters(method.Parameters, writer);
+ // add ~ for conversion operators
+ if ((name == "op_Implicit") || (name == "op_Explicit")) {
+ writer.Write("~");
+ WriteType(method.ReturnType, writer);
+ }
+
+ }
+
+ // The actual logic to construct names
+
+ private static void WriteNamespace(Namespace space, TextWriter writer) {
+ writer.Write(space.Name);
+ }
+
+ private static void WriteParameters(ParameterList parameters, TextWriter writer) {
+ if ((parameters == null) || (parameters.Count == 0)) return;
+ writer.Write("(");
+ for (int i = 0; i < parameters.Count; i++) {
+ if (i > 0) writer.Write(",");
+ WriteType(parameters[i].Type, writer);
+ }
+ writer.Write(")");
+ }
+
+ private static void WriteProperty(Property property, TextWriter writer) {
+ WriteType(property.DeclaringType, writer);
+ writer.Write(".{0}", property.Name.Name);
+ ParameterList parameters = property.Parameters;
+ WriteParameters(parameters, writer);
+ }
+
+ private static void WriteStaticConstructor(StaticInitializer constructor, TextWriter writer) {
+ WriteType(constructor.DeclaringType, writer);
+ writer.Write(".#cctor");
+ WriteParameters(constructor.Parameters, writer);
+ }
+
+ private static void WriteType(TypeNode type, TextWriter writer) {
+ switch (type.NodeType) {
+ case NodeType.ArrayType:
+ ArrayType array = type as ArrayType;
+ WriteType(array.ElementType, writer);
+ writer.Write("[");
+ for (int i = 1; i < array.Rank; i++) writer.Write(",");
+ writer.Write("]");
+ break;
+ case NodeType.Reference:
+ Reference reference = type as Reference;
+ TypeNode referencedType = reference.ElementType;
+ WriteType(referencedType, writer);
+
+ // DocStudio fails to add @ to template parameters or arrays of template
+ // parameters, so we have to mirror this bizarre behavior here
+ bool writeAt = true;
+ if (referencedType.IsTemplateParameter) writeAt = false;
+ if (referencedType.NodeType == NodeType.ArrayType) {
+ ArrayType referencedArray = referencedType as ArrayType;
+ if (referencedArray.ElementType.IsTemplateParameter) writeAt = false;
+ }
+ if (writeAt) writer.Write("@");
+ break;
+ case NodeType.Pointer:
+ Pointer pointer = type as Pointer;
+ WriteType(pointer.ElementType, writer);
+ writer.Write("*");
+ break;
+ case NodeType.OptionalModifier:
+ TypeModifier optionalModifierClause = type as TypeModifier;
+ WriteType(optionalModifierClause.ModifiedType, writer);
+ writer.Write("!");
+ WriteType(optionalModifierClause.Modifier, writer);
+ break;
+ case NodeType.RequiredModifier:
+ TypeModifier requiredModifierClause = type as TypeModifier;
+ WriteType(requiredModifierClause.ModifiedType, writer);
+ writer.Write("|");
+ WriteType(requiredModifierClause.Modifier, writer);
+ break;
+ default:
+ if (type.IsTemplateParameter) {
+ ITypeParameter gtp = (ITypeParameter)type;
+ if (gtp.DeclaringMember is TypeNode) {
+ writer.Write("`");
+ } else if (gtp.DeclaringMember is Method) {
+ writer.Write("``");
+ } else {
+ throw new InvalidOperationException("Generic parameter not on type or method.");
+ }
+ writer.Write(gtp.ParameterListIndex);
+ } else {
+ // namespace
+ TypeNode declaringType = type.DeclaringType;
+ if (declaringType != null) {
+ // names of nested types begin with outer type name
+ WriteType(declaringType, writer);
+ writer.Write(".");
+ } else {
+ // otherwise just prepend the namespace
+ string space = type.Namespace.Name;
+ if (space != null && space.Length > 0) {
+ writer.Write(space);
+ writer.Write(".");
+ }
+ }
+ // name
+ writer.Write(type.GetUnmangledNameWithoutTypeParameters());
+ // generic parameters
+ if (type.IsGeneric) {
+ // number of parameters
+ TypeNodeList parameters = type.TemplateParameters;
+ if (parameters != null) {
+ writer.Write("`{0}", parameters.Count);
+ }
+ // arguments
+ TypeNodeList arguments = type.TemplateArguments;
+ if ((arguments != null) && (arguments.Count > 0)) {
+ writer.Write("{");
+ for (int i = 0; i < arguments.Count; i++) {
+ TypeNode argument = arguments[i];
+ if (i > 0) writer.Write(",");
+ WriteType(arguments[i], writer);
+ }
+ writer.Write("}");
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ }
+
+}
diff --git a/tools/Sandcastle/Source/Sandcastle.sln b/tools/Sandcastle/Source/Sandcastle.sln
new file mode 100644
index 0000000..2815fa0
--- /dev/null
+++ b/tools/Sandcastle/Source/Sandcastle.sln
@@ -0,0 +1,155 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildAssembler", "BuildAssembler\BuildAssembler\BuildAssembler.csproj", "{5BA19924-5A65-46E0-97CD-948595932584}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildAssemblerLibrary", "BuildAssembler\BuildAssemblerLibrary\BuildAssemblerLibrary.csproj", "{399E78F8-4954-409E-991A-37DA9D0579CC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildComponents", "BuildAssembler\BuildComponents\BuildComponents.csproj", "{30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CopyComponents", "BuildAssembler\CopyComponents\CopyComponents.csproj", "{E64725D7-2208-4C28-922D-B6543C0BC483}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SyntaxComponents", "BuildAssembler\SyntaxComponents\SyntaxComponents.csproj", "{CEAEC85B-973A-4414-8668-723EB65E5088}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCI", "CCI\CCI.csproj", "{4CB332D6-976E-44F6-A320-A515A9D1D1D3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChmBuilder", "ChmBuilder\ChmBuilder.csproj", "{D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Assembler", "Build Assembler", "{9E55F052-6831-473C-82D8-0BA2CDAAEF2C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandLine", "CommandLine\CommandLine.csproj", "{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DBCSFix", "DBCSFix\DBCSFix.csproj", "{80407AE8-7A1F-4C28-8627-6C871E1D717A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MRefBuilder", "MRefBuilder\MRefBuilder.csproj", "{A8DCAD75-879F-4C97-803B-C9A17F227B04}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Reflection", "Reflection\Reflection.csproj", "{74F5EB3F-DC99-4FBE-9495-EE378FC60F65}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MergeXml", "XmlCat\MergeXml.csproj", "{1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XslTransform", "XslTransform\XslTransform.csproj", "{88A4B9E2-AE05-4817-879C-15461DA29761}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Sandcastle|Any CPU = Sandcastle|Any CPU
+ WebDocsDebug|Any CPU = WebDocsDebug|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5BA19924-5A65-46E0-97CD-948595932584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {5BA19924-5A65-46E0-97CD-948595932584}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {399E78F8-4954-409E-991A-37DA9D0579CC}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Release|Any CPU.Build.0 = Release|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Sandcastle|Any CPU.ActiveCfg = Release|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.Sandcastle|Any CPU.Build.0 = Release|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.WebDocsDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E64725D7-2208-4C28-922D-B6543C0BC483}.WebDocsDebug|Any CPU.Build.0 = Debug|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {CEAEC85B-973A-4414-8668-723EB65E5088}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {4CB332D6-976E-44F6-A320-A515A9D1D1D3}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Sandcastle|Any CPU.ActiveCfg = Release|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.Sandcastle|Any CPU.Build.0 = Release|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.WebDocsDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D17FA1CB-06EF-43A6-B11E-2B8E2661AA6D}.WebDocsDebug|Any CPU.Build.0 = Debug|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {6CF7CA42-3706-4F6B-A2B4-10EF3F511888}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Sandcastle|Any CPU.ActiveCfg = Release|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.Sandcastle|Any CPU.Build.0 = Release|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.WebDocsDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80407AE8-7A1F-4C28-8627-6C871E1D717A}.WebDocsDebug|Any CPU.Build.0 = Debug|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {A8DCAD75-879F-4C97-803B-C9A17F227B04}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {74F5EB3F-DC99-4FBE-9495-EE378FC60F65}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Sandcastle|Any CPU.ActiveCfg = Release|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.Sandcastle|Any CPU.Build.0 = Release|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.WebDocsDebug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}.WebDocsDebug|Any CPU.Build.0 = Debug|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Release|Any CPU.Build.0 = Release|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Sandcastle|Any CPU.ActiveCfg = Sandcastle|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.Sandcastle|Any CPU.Build.0 = Sandcastle|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.WebDocsDebug|Any CPU.ActiveCfg = WebDocsDebug|Any CPU
+ {88A4B9E2-AE05-4817-879C-15461DA29761}.WebDocsDebug|Any CPU.Build.0 = WebDocsDebug|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {399E78F8-4954-409E-991A-37DA9D0579CC} = {9E55F052-6831-473C-82D8-0BA2CDAAEF2C}
+ {30773718-BC7C-4FCC-A9C2-7EE61DF4EC41} = {9E55F052-6831-473C-82D8-0BA2CDAAEF2C}
+ {E64725D7-2208-4C28-922D-B6543C0BC483} = {9E55F052-6831-473C-82D8-0BA2CDAAEF2C}
+ {CEAEC85B-973A-4414-8668-723EB65E5088} = {9E55F052-6831-473C-82D8-0BA2CDAAEF2C}
+ {5BA19924-5A65-46E0-97CD-948595932584} = {9E55F052-6831-473C-82D8-0BA2CDAAEF2C}
+ EndGlobalSection
+EndGlobal
diff --git a/tools/Sandcastle/Source/XmlCat/GlobalSuppressions.cs b/tools/Sandcastle/Source/XmlCat/GlobalSuppressions.cs
new file mode 100644
index 0000000..8f3bbd3
--- /dev/null
+++ b/tools/Sandcastle/Source/XmlCat/GlobalSuppressions.cs
@@ -0,0 +1,17 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "MergeXml.Program.#Main(System.String[])")]
diff --git a/tools/Sandcastle/Source/XmlCat/MergeXml.csproj b/tools/Sandcastle/Source/XmlCat/MergeXml.csproj
new file mode 100644
index 0000000..ba9d6d2
--- /dev/null
+++ b/tools/Sandcastle/Source/XmlCat/MergeXml.csproj
@@ -0,0 +1,67 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{1CEE1BB8-10BF-483E-A54A-F97B308ABA0A}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MergeXml</RootNamespace>
+ <AssemblyName>MergeXml</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/XmlCat/Program.cs b/tools/Sandcastle/Source/XmlCat/Program.cs
new file mode 100644
index 0000000..7b0ab64
--- /dev/null
+++ b/tools/Sandcastle/Source/XmlCat/Program.cs
@@ -0,0 +1,166 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+using System.Xml.XPath;
+using Microsoft.Ddue.Tools.CommandLine;
+
+namespace MergeXml
+{
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ ConsoleApplication.WriteBanner();
+
+ // get and validate args
+ OptionCollection programOptions = new OptionCollection();
+ programOptions.Add(new SwitchOption("?", "Show this help page."));
+ programOptions.Add(new StringOption("out", "(String) Path to the file that the input files should be merged in to. Required."));
+ programOptions.Add(new StringOption("position", "(String) The name of the element or elements to which the input elements will be appended. Required."));
+ programOptions.Add(new StringOption("include", @"(String) An xpath expression indicating which elements from the source files should be introduced in to the output file. The default is '/'"));
+ ParseArgumentsResult options = programOptions.ParseArguments(args);
+ if (options.Options["?"].IsPresent || !options.Options["out"].IsPresent || !options.Options["position"].IsPresent)
+ {
+ programOptions.WriteOptionSummary(Console.Error);
+ Console.WriteLine();
+ Console.WriteLine("file1 file2 ...");
+ Console.WriteLine("The input files to operate on.");
+ return 0;
+ }
+ // ensure output file exists
+ string outputPath = options.Options["out"].Value.ToString();
+ if (!File.Exists(outputPath))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "The specified output file, which the input files are to be merged in to, doesn't exist.");
+ return 1;
+ }
+
+ // ensure a postition element name was passed
+ if (String.IsNullOrEmpty(options.Options["position"].Value.ToString()))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "No position element name was provided.");
+ return 1;
+ }
+ string positionName = options.Options["position"].Value.ToString();
+
+ // validate xpaths ("include" switch)
+ string xpath;
+ if (options.Options["include"].IsPresent)
+ xpath = options.Options["include"].Value.ToString();
+ else
+ xpath = @"/";
+ XPathExpression includeExpression;
+ try
+ {
+ includeExpression = XPathExpression.Compile(xpath);
+ }
+ catch (XPathException)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "The xpath expression provided by the include switch, '" + xpath + "', is invalid.");
+ return 1;
+ }
+
+ // get list of input files to operate on
+ if (options.UnusedArguments.Count == 0)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "No input files were provided.");
+ return 1;
+ }
+ string[] inputFiles = new string[options.UnusedArguments.Count];
+ options.UnusedArguments.CopyTo(inputFiles, 0);
+
+ // ensure all input files exist
+ foreach (string path in inputFiles)
+ {
+ if (!File.Exists(path))
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, "Specified input file '" + path + "' doesn't exist.");
+ return 1;
+ }
+ }
+
+
+ // open the output file and move to the position
+ XmlWriterSettings outputSettings = new XmlWriterSettings();
+ outputSettings.Indent = true;
+ outputSettings.Encoding = Encoding.UTF8;
+ using (XmlWriter output = XmlWriter.Create(outputPath + ".tmp", outputSettings))
+ {
+ // start printing output doc string until the selected node is matched
+ using (XmlReader source = XmlReader.Create(outputPath))
+ {
+ while (!source.EOF)
+ {
+ source.Read();
+
+ switch (source.NodeType)
+ {
+ case XmlNodeType.Element:
+ output.WriteStartElement(source.Prefix, source.LocalName, source.NamespaceURI);
+ output.WriteAttributes(source, true);
+ if (source.IsEmptyElement)
+ {
+ output.WriteEndElement();
+ }
+ if (String.Equals(source.Name, positionName, StringComparison.OrdinalIgnoreCase))
+ {
+ // start introducing the elements from the input files
+ foreach (string path in inputFiles)
+ {
+ XPathDocument inputDoc = new XPathDocument(path);
+ XPathNavigator inputNav = inputDoc.CreateNavigator();
+ XPathNodeIterator inputNodesIterator = inputNav.Select(includeExpression);
+ while (inputNodesIterator.MoveNext())
+ {
+ output.WriteNode(inputNodesIterator.Current, true);
+ }
+ }
+ }
+ break;
+ case XmlNodeType.Text:
+ output.WriteString(source.Value);
+ break;
+ case XmlNodeType.Whitespace:
+ case XmlNodeType.SignificantWhitespace:
+ output.WriteWhitespace(source.Value);
+ break;
+ case XmlNodeType.CDATA:
+ output.WriteCData(source.Value);
+ break;
+ case XmlNodeType.EntityReference:
+ output.WriteEntityRef(source.Name);
+ break;
+ case XmlNodeType.XmlDeclaration:
+ case XmlNodeType.ProcessingInstruction:
+ output.WriteProcessingInstruction(source.Name, source.Value);
+ break;
+ case XmlNodeType.DocumentType:
+ output.WriteDocType(source.Name, source.GetAttribute("PUBLIC"), source.GetAttribute("SYSTEM"), source.Value);
+ break;
+ case XmlNodeType.Comment:
+ output.WriteComment(source.Value);
+ break;
+ case XmlNodeType.EndElement:
+ output.WriteFullEndElement();
+ break;
+ }
+ }
+ }
+ output.WriteEndDocument();
+ output.Close();
+ }
+
+ File.Delete(outputPath);
+ File.Move(outputPath + ".tmp", outputPath);
+
+ return 0; // pau
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/Sandcastle/Source/XmlCat/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/XmlCat/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1f63295
--- /dev/null
+++ b/tools/Sandcastle/Source/XmlCat/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MergeXml")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MergeXml")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("03338e55-01af-4553-89ae-7e9e4d348862")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/XslTransform/GlobalSuppressions.cs b/tools/Sandcastle/Source/XslTransform/GlobalSuppressions.cs
new file mode 100644
index 0000000..a71731d
--- /dev/null
+++ b/tools/Sandcastle/Source/XslTransform/GlobalSuppressions.cs
@@ -0,0 +1,21 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
+// "In Project Suppression File".
+// You do not need to add suppressions to this file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ddue", Scope = "namespace", Target = "Microsoft.Ddue.Tools")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Scope = "type", Target = "Microsoft.Ddue.Tools.TransformInfo")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Scope = "type", Target = "Microsoft.Ddue.Tools.XslTransformer")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XslTransformer.#Main(System.String[])")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)", Scope = "member", Target = "Microsoft.Ddue.Tools.XslTransformer.#Main(System.String[])")]
diff --git a/tools/Sandcastle/Source/XslTransform/Properties/AssemblyInfo.cs b/tools/Sandcastle/Source/XslTransform/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c0bef2a
--- /dev/null
+++ b/tools/Sandcastle/Source/XslTransform/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("XslTransformer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("XslTransform")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2005-2006")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: System.CLSCompliant(true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("cc740102-786b-442a-9f23-c5241c025640")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("2.5.10626.00")]
+[assembly: AssemblyFileVersion("2.5.10626.00")]
diff --git a/tools/Sandcastle/Source/XslTransform/XslTransform.cs b/tools/Sandcastle/Source/XslTransform/XslTransform.cs
new file mode 100644
index 0000000..6b6d76c
--- /dev/null
+++ b/tools/Sandcastle/Source/XslTransform/XslTransform.cs
@@ -0,0 +1,275 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Xml.Xsl;
+using Microsoft.Ddue.Tools.CommandLine;
+
+
+namespace Microsoft.Ddue.Tools
+{
+ public class XslTransformer
+ {
+ public static int Main(string[] args)
+ {
+ // specify options
+ OptionCollection options = new OptionCollection();
+ options.Add(new SwitchOption("?", "Show this help page."));
+ options.Add(new ListOption("xsl", "Sepcify transform files.", "xsltPath"));
+ options.Add(new ListOption("arg", "Sepcify arguments.", "name=value"));
+ options.Add(new StringOption("out", "Specify an output file. If unspecified, output goes to the console.", "outputFilePath"));
+ options.Add(new SwitchOption("w", "Do not ignore insignificant whitespace. By default insignificant whitespace is ignored."));
+
+ ConsoleApplication.WriteBanner();
+
+ // process options
+ ParseArgumentsResult results = options.ParseArguments(args);
+ if (results.Options["?"].IsPresent)
+ {
+ Console.WriteLine("XslTransformer xsl_file [xml_file] [options]");
+ options.WriteOptionSummary(Console.Out);
+ return (0);
+ }
+
+ // check for invalid options
+ if (!results.Success)
+ {
+ results.WriteParseErrors(Console.Out);
+ return (1);
+ }
+
+ // check for missing or extra assembly directories
+ if (results.UnusedArguments.Count != 1)
+ {
+ Console.WriteLine("Specify one input XML input file.");
+ return (1);
+ }
+
+ if (!results.Options["xsl"].IsPresent)
+ {
+ Console.WriteLine("Specify at least one XSL transform file.");
+ return (1);
+ }
+
+ // set whitespace setting
+ bool ignoreWhitespace = !results.Options["w"].IsPresent;
+
+ // Load transforms
+ string[] transformFiles = (string[])results.Options["xsl"].Value;
+ XslCompiledTransform[] transforms = new XslCompiledTransform[transformFiles.Length];
+ for (int i = 0; i < transformFiles.Length; i++)
+ {
+ string transformFile = Environment.ExpandEnvironmentVariables(transformFiles[i]);
+ transforms[i] = new XslCompiledTransform();
+ XsltSettings transformSettings = new XsltSettings(true, true);
+ try
+ {
+ transforms[i].Load(transformFile, transformSettings, new XmlUrlResolver());
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message));
+ return (1);
+ }
+ catch (UnauthorizedAccessException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' could not be loaded. The error is: {1}", transformFile, e.Message));
+ return (1);
+ }
+ catch (XsltException e)
+ {
+ if (e.InnerException != null)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.InnerException.Message));
+ }
+ else
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transformation file '{0}' is not valid. The error is: {1}", transformFile, e.Message));
+ }
+ return (1);
+ }
+ catch (XmlException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The transform file '{0}' is not well-formed. The error is: {1}", transformFile, e.Message));
+ return (1);
+ }
+ }
+
+ // Compose the arguments
+ XsltArgumentList arguments = new XsltArgumentList();
+ if (results.Options["arg"].IsPresent)
+ {
+ string[] nameValueStrings = (string[])results.Options["arg"].Value;
+ foreach (string nameValueString in nameValueStrings)
+ {
+ string[] nameValuePair = nameValueString.Split('=');
+ if (nameValuePair.Length != 2) continue;
+ arguments.AddParam(nameValuePair[0], String.Empty, nameValuePair[1]);
+ }
+ }
+
+ string input = Environment.ExpandEnvironmentVariables(results.UnusedArguments[0]);
+
+ // prepare the reader
+ XmlReaderSettings readerSettings = new XmlReaderSettings();
+ readerSettings.IgnoreWhitespace = ignoreWhitespace;
+
+ // Do each transform
+ for (int i = 0; i < transforms.Length; i++)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Info, String.Format("Applying XSL transformation '{0}'.", transformFiles[i]));
+
+ // get the transform
+ XslCompiledTransform transform = transforms[i];
+
+ // figure out where to put the output
+ string output;
+ if (i < (transforms.Length - 1))
+ {
+ try
+ {
+ output = Path.GetTempFileName();
+ File.SetAttributes(output, FileAttributes.Temporary);
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured while attempting to create a temporary file. The error message is: {0}", e.Message));
+ return (1);
+ }
+ }
+ else
+ {
+ if (results.Options["out"].IsPresent)
+ {
+ output = Environment.ExpandEnvironmentVariables((string)results.Options["out"].Value);
+ }
+ else
+ {
+ output = null;
+ }
+ }
+
+ // create a reader
+ Stream readStream;
+ try
+ {
+ readStream = File.Open(input, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message));
+ return (1);
+ }
+ catch (UnauthorizedAccessException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' could not be loaded. The error is: {1}", input, e.Message));
+ return (1);
+ }
+
+ using (XmlReader reader = XmlReader.Create(readStream, readerSettings))
+ {
+ // create a writer
+ Stream outputStream;
+ if (output == null)
+ {
+ outputStream = Console.OpenStandardOutput();
+ }
+ else
+ {
+ try
+ {
+ outputStream = File.Open(output, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete);
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message));
+ return (1);
+ }
+ catch (UnauthorizedAccessException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The output file '{0}' could not be loaded. The error is: {1}", output, e.Message));
+ return (1);
+ }
+ }
+
+ using (XmlWriter writer = XmlWriter.Create(outputStream, transform.OutputSettings))
+ {
+ try
+ {
+ // do the deed
+ transform.Transform(reader, arguments, writer);
+ }
+ catch (XsltException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("An error occured during the transformation. The error message is: {0}",
+ (e.InnerException == null) ? e.Message : e.InnerException.Message));
+ return (1);
+ }
+ catch (XmlException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Error, String.Format("The input file '{0}' is not well-formed. The error is: {1}", input, e.Message));
+ return (1);
+ }
+ }
+ }
+
+ // if the last input was a temp file, delete it
+ if (i > 0)
+ {
+ // Console.WriteLine("deleting {0}", input);
+ try
+ {
+ File.Delete(input);
+ }
+ catch (IOException e)
+ {
+ ConsoleApplication.WriteMessage(LogLevel.Warn, String.Format("The temporary file '{0}' could not be deleted. The error message is: {1}", input, e.Message));
+ }
+ }
+
+ // the last output file is the next input file
+ input = output;
+
+ }
+
+ return (0);
+ }
+ }
+
+ internal class TransformInfo
+ {
+ public TransformInfo(string file)
+ {
+ this.file = file;
+ transform.Load(file, settings, resolver);
+ }
+
+ private string file;
+
+ private XslCompiledTransform transform = new XslCompiledTransform();
+
+ public string File
+ {
+ get
+ {
+ return (file);
+ }
+ }
+
+ public XslCompiledTransform Transform
+ {
+ get
+ {
+ return (transform);
+ }
+ }
+
+ private static XsltSettings settings = new XsltSettings(true, true);
+
+ private static XmlUrlResolver resolver = new XmlUrlResolver();
+ }
+}
diff --git a/tools/Sandcastle/Source/XslTransform/XslTransform.csproj b/tools/Sandcastle/Source/XslTransform/XslTransform.csproj
new file mode 100644
index 0000000..8d2e420
--- /dev/null
+++ b/tools/Sandcastle/Source/XslTransform/XslTransform.csproj
@@ -0,0 +1,89 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{88A4B9E2-AE05-4817-879C-15461DA29761}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>XslTransform</RootNamespace>
+ <AssemblyName>XslTransform</AssemblyName>
+ <SccProjectName>
+ </SccProjectName>
+ <SccLocalPath>
+ </SccLocalPath>
+ <SccAuxPath>
+ </SccAuxPath>
+ <SccProvider>
+ </SccProvider>
+ <SignAssembly>false</SignAssembly>
+ <AssemblyOriginatorKeyFile>../../key.snk</AssemblyOriginatorKeyFile>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>2.0</OldToolsVersion>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'WebDocsDebug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\WebDocsDebug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Sandcastle|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\Sandcastle\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="XslTransform.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\CommandLine\CommandLine.csproj">
+ <Project>{6CF7CA42-3706-4F6B-A2B4-10EF3F511888}</Project>
+ <Name>CommandLine</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <!-- Copy the output assemblies to a common binaries directory (ProductionTools). -->
+ <Target Name="AfterBuild">
+ <CreateItem Include="$(OutputPath)\$(AssemblyName).*">
+ <Output TaskParameter="Include" ItemName="ProductionFiles" />
+ </CreateItem>
+ <Copy SourceFiles="@(ProductionFiles)" DestinationFolder="..\..\ProductionTools" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/Sandcastle/Source/build.proj b/tools/Sandcastle/Source/build.proj
new file mode 100644
index 0000000..ca9fe49
--- /dev/null
+++ b/tools/Sandcastle/Source/build.proj
@@ -0,0 +1,17 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <SandcastleProjects Include="**\*.csproj" />
+ </ItemGroup>
+
+ <Target Name="Build">
+ <MSBuild Projects="@(SandcastleProjects)" />
+ </Target>
+
+ <Target Name="Rebuild">
+ <MSBuild Projects="@(SandcastleProjects)" Targets="Rebuild" />
+ </Target>
+
+ <Target Name="Clean">
+ <MSBuild Projects="@(SandcastleProjects)" Targets="Clean" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/tools/sandcastle.targets b/tools/sandcastle.targets
index 8103a21..afdc77b 100644
--- a/tools/sandcastle.targets
+++ b/tools/sandcastle.targets
@@ -58,7 +58,7 @@
<SetEnvironmentVariable Name="FxReflectionData" Value="$(FxReflectionOutputPath)" />
</Target>
- <Target Name="FxReflection" Condition="!Exists('$(FxReflectionOutputPath)')">
+ <Target Name="FxReflection" DependsOnTargets="ProductionTools" Condition="!Exists('$(FxReflectionOutputPath)')">
<MakeDir Directories="$(FxReflectionIntermediatePath)" Condition="!Exists('$(FxReflectionIntermediatePath)')" />
<MakeDir Directories="$(FxReflectionOutputPath)" Condition="!Exists('$(FxReflectionOutputPath)')" />
<CreateItem Include="@(AssemblyFolders->'%(FullPath)')">
@@ -92,7 +92,7 @@
</Target>
<Target Name="ReflectionBase" Inputs="$(OutputAssemblyFile)" Outputs="$(ReflectionBaseFile)"
- DependsOnTargets="SetEnvironmentVars;CreateIntermediatePath">
+ DependsOnTargets="SetEnvironmentVars;CreateIntermediatePath;ProductionTools">
<Exec Command='"$(ProductionTools)\MRefBuilder.exe" "$(OutputAssemblyFile)" /out:"$(ReflectionBaseFile)"' />
</Target>
@@ -151,4 +151,8 @@
<Exec Command='"$(ProductionTools)\XslTransform.exe" /xsl:"$(ProductionTransforms)\TocToHxSContents.xsl" "$(TocFile)" /out:"$(HxtFile)"' />
<Exec Command='hxcomp.exe -p "$(HxcFile)"' IgnoreExitCode="true" />
</Target>
+
+ <Target Name="ProductionTools">
+ <MSBuild Projects="$(DxRoot)\Source\build.proj" />
+ </Target>
</Project>